145 lines
5.6 KiB
JavaScript
145 lines
5.6 KiB
JavaScript
module.exports = function (app) {
|
|
const router = require('express').Router(),
|
|
userCtl = require('../controllers/user'),
|
|
Joi = require('joi');
|
|
Joi.objectId = require('joi-objectid')(Joi);
|
|
|
|
const { validateInputRequest } = require('../middlewares/validate');
|
|
const { ApplicationTypes, RefSources, DEFAULT_LANG } = require('../helpers/constants');
|
|
|
|
// Joi schema for appInfo based on RefSourceSchema from customer model
|
|
const appInfoSchema = Joi.object({
|
|
appTypes: Joi.array().items(
|
|
Joi.string().valid(...Object.values(ApplicationTypes))
|
|
).optional(),
|
|
refSources: Joi.array().items(
|
|
Joi.string().valid(...Object.values(RefSources))
|
|
).optional(),
|
|
});
|
|
|
|
// Joi schema for signup
|
|
const signupSchema = Joi.object({
|
|
contactEmail: Joi.string().email().required(),
|
|
password: Joi.string().required(),
|
|
contactName: Joi.string().required(),
|
|
companyName: Joi.string().required(),
|
|
country: Joi.string().required(),
|
|
|
|
// Fallback fields used when no addresses array provided
|
|
address: Joi.string().optional(),
|
|
city: Joi.string().optional(),
|
|
state: Joi.string().optional(),
|
|
postalCode: Joi.string().optional(),
|
|
contactPhone: Joi.string().optional(),
|
|
|
|
// Only allow addresses array for address input
|
|
addresses: Joi.array().items(Joi.object({
|
|
/* Full Name of the (billing) address mostly mean the name of the person on card, bank account or entity business name */
|
|
name: Joi.string().optional(),
|
|
line1: Joi.string().optional(),
|
|
line2: Joi.string().optional(),
|
|
city: Joi.string().optional(),
|
|
state: Joi.string().optional(),
|
|
postalCode: Joi.string().optional(),
|
|
country: Joi.string().required(),
|
|
phone: Joi.string().optional(),
|
|
email: Joi.string().email().optional(),
|
|
isBilling: Joi.boolean().optional()
|
|
})).min(1).optional(),
|
|
|
|
// AppInfo structure based on RefSourceSchema
|
|
appInfo: appInfoSchema.optional(),
|
|
|
|
taxId: Joi.string().allow('').optional(),
|
|
lang: Joi.string().default(DEFAULT_LANG).optional(),
|
|
partner: Joi.objectId().allow('').allow(null).optional(),
|
|
emailToken: Joi.string().optional(),
|
|
token: Joi.string().optional(),
|
|
})
|
|
.or('emailToken', 'token'); // Require either emailToken OR token for verification
|
|
|
|
// On routes that end in /users
|
|
router.route('/').post(userCtl.createUser_post);
|
|
|
|
/**
|
|
* @api {get} /users/:id Get User
|
|
* @apiVersion 1.2.1
|
|
* @apiName GetUser
|
|
* @apiGroup Users
|
|
* @apiDescription Retrieve a user document by ID. The response shape is
|
|
* controlled by the optional `view` query parameter.
|
|
*
|
|
* @apiParam {String} id User ObjectId.
|
|
*
|
|
* @apiQuery {String} [view] Controls the response shape. When set, `membership.*`
|
|
* fields are always excluded. Supported values:
|
|
* - `profile` — `_id, username, contact, name, phone, email, Country`.
|
|
* No `password`, no `membership`, no `addresses`.
|
|
* - `edit` — `_id, kind, active, username, password, name, address, country,
|
|
* phone, fax, email, contact, licence, parent, Country`.
|
|
* - `billing` — `_id, name, address, country, Country`.
|
|
* - *(omitted)* — full document without `addresses` (see `withAddresses`).
|
|
* @apiQuery {Boolean} [withAddresses=false] When `true` and `view` is omitted,
|
|
* returns the full document **including** the `addresses` array.
|
|
*
|
|
* `Country` (populated object with `code` and `name`) is included in all views.
|
|
*
|
|
* @apiSuccess {Object} user User document (shape varies by `view`).
|
|
*
|
|
* @apiError (401) {Object} error Not authorized.
|
|
* @apiError (409) {Object} error Invalid user ID.
|
|
*/
|
|
// On routes that end in /users/:id
|
|
router.route('/:id')
|
|
.get(userCtl.getUser_get)
|
|
.put(userCtl.updateUser_put)
|
|
.delete(userCtl.deleteUser)
|
|
|
|
/**
|
|
* @api {post} /users/login Login to AgMission server
|
|
* @apiVersion 1.2.1
|
|
* @apiName PostUsersLogin
|
|
* @apiGroup Users
|
|
* @apiDescription Login to AgMission Server. The returned token can be used for other API calls. For accounts used in aircrafts,
|
|
* user should login at the beginning of each work session such as beginning of the day to make sure the token is still valid or not.
|
|
* @apiParam {String} username The account's username
|
|
* @apiParam {String} password The account's password
|
|
* @apiParamExample {json} Request-Example:
|
|
* {
|
|
* "username": "me@mail.com", "password": "notell"
|
|
* }
|
|
* @apiSuccess {String} token Authorization token
|
|
* @apiSuccessExample {json} Success
|
|
* HTTP/1.1 200 OK
|
|
* {
|
|
* "token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiI1YWQ1Zjc4NWE5OWEzZjFkOWZjMmM5ZDAiLCJ1dCI6OSwiaWF0IjoxNTIzOTk0NjM1fQ.H_FRXwFiq33Pt9ZSF2LejWfrIG8ijb1xgFEl2Y7affT"
|
|
* }
|
|
* @apiuse WrongCredentialError
|
|
* @apiuse InActiveAccountError
|
|
*/
|
|
router.post('/login', userCtl.login_post);
|
|
|
|
router.route('/exists').post(userCtl.isUserNameExists_post);
|
|
|
|
router.route('/search').post(userCtl.search_post);
|
|
|
|
router.post('/clearTempData', userCtl.clearTempData_post);
|
|
|
|
router.post('/updateLang', userCtl.setUserLanguage_post);
|
|
|
|
router.post('/getUserDetail', userCtl.getUserDetail_post);
|
|
|
|
router.post('/mailPwdReset', userCtl.mailPwdReset_post);
|
|
|
|
router.post('/resetPassword/validate', userCtl.validateResetPwdToken_post);
|
|
|
|
router.post('/resetPassword', userCtl.resetPassword_post);
|
|
|
|
// Email verification endpoints (add these before signup)
|
|
router.post('/signup/requestVerifyEmail', userCtl.requestEmailVerification_post);
|
|
router.post('/signup/validate', userCtl.verifyEmailCode_post);
|
|
router.post('/signup', validateInputRequest(signupSchema), userCtl.signup_post);
|
|
|
|
app.use('/api/users', router);
|
|
};
|