validate() { if (this.schema !== null) { return Joi.validate(this.args, this.schema); } }
invalidDateTimeValues.forEach((time) => { Joi.validate(time, schema, function (error, value) { t.ok(error, time + ' should be invalid'); }); });
exports.assert = function (type, options, message) { var error = Joi.validate(options, internals[type]).error; Hoek.assert(!error, 'Invalid', type, 'options', message ? '(' + message + ')' : '', error && error.annotate()); };
handler: function(request, next) { var uDeets = request.payload; // Validate payload // Validate payload var validSchema = Joi.object().keys({ email: Joi.string().required() }) // We got everything we need to create a new user Joi.validate(uDeets, validSchema, function (err, value) { if(err !== null) { next({error: true, details: 'Incorrect email'}).type('application/json'); } else { var collection = db.collection('users'); collection.findOne({"email": uDeets.email}, function(err, user) { if(err) throw err; // Check we have a user if(user) { delete user.password; // Generate a forgot access token and email it to them var token = Jwt.sign(user, forgotSecret, { expiresInMinutes: 60 }); var opts = { payload: JSON.stringify({forgotToken: token}), headers: { 'content-type':'application/json'} }; API.call({ method: 'PUT', url: '/api/user/'+user._id, payload: { forgotToken: token }, credentials: options.coreCreds, callback: function (err, res, payload) { // Update user to be var link = options.app.url+"/reset/"+token; // setup e-mail data with unicode symbols var mailOptions = { from: from, // sender address to: user.email, // list of receivers subject: "Reset Password", // Subject line text: "Hi "+user.fname+",\nHere is your password reset link:\n\n"+link+"\n\nThis token will expire in 1 hour.\n\nThe Team", // plaintext body html: "<p>Hi "+user.fname+",</br>Click the link below to reset your password:</p><a href='"+link+"'><h3>Reset Password</h3></a><p>This token will expire in 1 hour.</p><p>The Team</p>" // html body } // send mail with defined transport object transporter.sendMail(mailOptions, function(error, response){ if(error) { console.log(error); } else { console.log("Password reset message sent: " + response.message); } // if you don't want to use this transport object anymore, uncomment following line //smtpTransport.close(); // shut down the connection pool, no more messages }); next({error: false, token: token}); } }); } else { // Throw error if we didn't find an email next({error: true, details: 'Incorrect email'}).type('application/json'); } }); } }) }
exports.response = function (request, next) { if (request.route.settings.response.sample) { const currentSample = Math.ceil((Math.random() * 100)); if (currentSample > request.route.settings.response.sample) { return next(); } } const response = request.response; const statusCode = response.isBoom ? response.output.statusCode : response.statusCode; const statusSchema = request.route.settings.response.status[statusCode]; if (statusCode >= 400 && !statusSchema) { return next(); // Do not validate errors by default } const schema = statusSchema || request.route.settings.response.schema; if (schema === null) { return next(); // No rules } if (!response.isBoom && request.response.variety !== 'plain') { return next(Boom.badImplementation('Cannot validate non-object response')); } const postValidate = (err, value) => { if (!err) { if (value !== undefined && request.route.settings.response.modify) { if (response.isBoom) { response.output.payload = value; } else { response.source = value; } } return next(); } // failAction: 'error', 'log' if (request.route.settings.response.failAction === 'log') { request._log(['validation', 'response', 'error'], err.message); return next(); } return next(Boom.badImplementation(err.message)); }; const localOptions = { context: { headers: request.headers, params: request.params, query: request.query, payload: request.payload, auth: { isAuthenticated: request.auth.isAuthenticated, credentials: request.auth.credentials } } }; const source = response.isBoom ? response.output.payload : response.source; Hoek.merge(localOptions, request.route.settings.response.options); if (typeof schema !== 'function') { return Joi.validate(source, schema, localOptions, postValidate); } request._protect.run(postValidate, (exit) => { return schema(source, localOptions, exit); }); };
CLOSE: 'reader-survey-close', }, EVENT_SHAPES: { IMPRESSION: {}, CONVERSION: { box: Joi.number().integer() .min(1) .max(10) .required(), }, CAPTURE: { name: Joi.string().valid('readerSurvey').required(), 'after.survey': Joi.boolean().valid(true), }, CLOSE: {}, }, isValidEvent(event, data) { const key = events.EVENTS_INVERSE[event]; if (!key) return false; const shape = events.EVENT_SHAPES[key]; const result = Joi.validate(data, shape); return result.error === null; }, }; events.EVENTS_INVERSE = _.invert(events.EVENTS); module.exports = events;
handler: function(request, next) { var newUser = request.payload; var validSchema = Joi.object().keys({ fname: Joi.string().required(), lname: Joi.string().required(), email: Joi.string().email().required(), password: Joi.string().alphanum().required().min(5).max(15), password2: Joi.any().valid(newUser.password) }) // We got everything we need to create a new user Joi.validate(newUser, validSchema, {abortEarly: false}, function (err, value) { if(err !== null) { console.log(err) var message = ''; for(i=0; i < err.details.length; i++) { var _message = err.details[i].message; if(err.details[i].path == 'password2') { message += 'Passwords must match. ' } else { message += _message.substr(0, 1).toUpperCase() + _message.substr(1) +'. '; } } return next({error: true, details: message}).type('application/json'); } else { delete newUser.password2; API.call({ method: 'POST', url: '/api/user', payload: newUser, credentials: options.coreCreds, callback: function(err, res, payload) { if (err) throw err; console.log('err: ' + err); // console.log('res: ', res); console.log('payload: ', payload); var response = JSON.parse(payload); if(response.error) { return next({error: true, details: 'Error registering.'}).type('application/json'); } else { var token = Jwt.sign({id:response._id}, forgotSecret); var link = options.app.url+"/activate/"+token; // setup e-mail data with unicode symbols var mailOptions = { from: from, // sender address to: response.email, // list of receivers subject: "Activate your Account", // Subject line text: "Hi "+response.fname+",\nThank you for registering. Use the following link to activate your account:\n\n"+link+"\n\nThanks for your cooperation.\n\nThe Team", // plaintext body html: "<p>Hi "+response.fname+",</p><p>Thank you for registering. Please click the following link to activate your account:</p><a href='"+link+"'><h3>Activate account</h3></a><p>Thanks for your cooperation.</p><p>The Team</p>" // html body } // send mail with defined transport object // send mail with defined transport object transporter.sendMail(mailOptions, function(error, info){ if(error){ console.log(error); }else{ console.log('Message sent: ' + info.response); } }); return next({error: false, details: 'Success! An activation email has been sent to you.'}).type('application/json'); } } }); } }) }
var validate = function (callback) { Joi.validate(config, ConfigSchema, callback); };
internals.implementation = function (server, options) { const results = Joi.validate(options, internals.schema); Hoek.assert(!results.error, results.error); const settings = results.value; const cookieOptions = { encoding: 'iron', password: settings.password, isSecure: settings.isSecure, // Defaults to true path: settings.path, isHttpOnly: settings.isHttpOnly, // Defaults to true clearInvalid: settings.clearInvalid, ignoreErrors: true }; if (settings.ttl) { cookieOptions.ttl = settings.ttl; } if (settings.domain) { cookieOptions.domain = settings.domain; } if (typeof settings.appendNext === 'boolean') { settings.appendNext = (settings.appendNext ? 'next' : ''); } server.state(settings.cookie, cookieOptions); const decoration = function (request) { const CookieAuth = function () { const self = this; this.set = function (session, value) { const reply = self.reply; if (arguments.length > 1) { const key = session; Hoek.assert(key && typeof key === 'string', 'Invalid session key'); session = request.auth.artifacts; Hoek.assert(session, 'No active session to apply key to'); session[key] = value; return reply.state(settings.cookie, session); } Hoek.assert(session && typeof session === 'object', 'Invalid session'); request.auth.artifacts = session; reply.state(settings.cookie, session); }; this.clear = function (key) { const reply = self.reply; if (arguments.length) { Hoek.assert(key && typeof key === 'string', 'Invalid session key'); const session = request.auth.artifacts; Hoek.assert(session, 'No active session to clear key from'); delete session[key]; return reply.state(settings.cookie, session); } request.auth.artifacts = null; reply.unstate(settings.cookie); }; this.ttl = function (msecs) { const reply = self.reply; const session = request.auth.artifacts; Hoek.assert(session, 'No active session to modify ttl on'); reply.state(settings.cookie, session, { ttl: msecs }); }; }; return new CookieAuth(); }; server.decorate('request', settings.requestDecoratorName, decoration, { apply: true }); server.ext('onPreAuth', (request, reply) => { // Used for setting and unsetting state, not for replying to request request[settings.requestDecoratorName].reply = reply; return reply.continue(); }); const scheme = { authenticate: function (request, reply) { const validate = function () { // Check cookie const session = request.state[settings.cookie]; if (!session) { return unauthenticated(Boom.unauthorized(null, 'cookie')); } if (!settings.validateFunc) { if (settings.keepAlive) { reply.state(settings.cookie, session); } return reply.continue({ credentials: session, artifacts: session }); } settings.validateFunc(request, session, (err, isValid, credentials) => { if (err || !isValid) { if (settings.clearInvalid) { reply.unstate(settings.cookie); } return unauthenticated(Boom.unauthorized('Invalid cookie'), { credentials: credentials || session, artifacts: session }); } if (settings.keepAlive) { reply.state(settings.cookie, session); } return reply.continue({ credentials: credentials || session, artifacts: session }); }); }; const unauthenticated = function (err, result) { if (settings.redirectOnTry === false && // Defaults to true request.auth.mode === 'try') { return reply(err, null, result); } let redirectTo = settings.redirectTo; if (request.route.settings.plugins['hapi-auth-cookie'] && request.route.settings.plugins['hapi-auth-cookie'].redirectTo !== undefined) { redirectTo = request.route.settings.plugins['hapi-auth-cookie'].redirectTo; } if (!redirectTo) { return reply(err, null, result); } let uri = redirectTo; if (settings.appendNext) { if (uri.indexOf('?') !== -1) { uri += '&'; } else { uri += '?'; } uri += settings.appendNext + '=' + encodeURIComponent(request.url.path); } return reply('You are being redirected...', null, result).redirect(uri); }; validate(); } }; return scheme; };
exports.validate = (data, schema) => { const result = Joi.validate(data, schema, { abortEarly: false }); return errorDetails(result.error); };
.filter(address => ! joi.validate(address, IP_ADDRESS.required()).error);
.then(resp => { const validationResult = Joi.validate(resp.body, GENERIC_RESPONSE_SCHEMA); expect(validationResult.error).to.be(null); });
exports.update = async function update(ctx) { const id = Joi.attempt(ctx.params.id, Joi.objectId()); const data = Joi.validate(ctx.request.body, validateSchema); await monitorService.findByIdAndUpdate(id, data); ctx.body = null; };
exports.apply = function (type, options, message) { var result = Joi.validate(options, internals[type]); Hoek.assert(!result.error, 'Invalid', type, 'options', message ? '(' + message + ')' : '', result.error && result.error.annotate()); return result.value; };
value: function(t, k, o) { // set defaults values var _token = t || '', _key = k || '', _opt = o || {}; // validate inputs var tokenValidate = joi.validate(_token, schema.token, {language: {label: 'token'}}); if (tokenValidate.error) { throw tokenValidate.error; } _token = tokenValidate.value; var keyValidate = joi.validate(_key, schema.key, {language: {label: 'key'}}); if (keyValidate.error) { throw keyValidate.error; } _key = keyValidate.value; var optValidate = joi.validate(_opt, schema.optVerify, {language: {label: 'opt'}}); if (optValidate.error) { throw optValidate.error; } _opt = optValidate.value; // get window var window = bigInt(_opt.window); // get counter var counter, isCounterHexa = false; if (!_.isNull(_opt.counter.int) && !_.isUndefined(_opt.counter.int)) { counter = bigInt(_opt.counter.int); } else { counter = bigInt(_opt.counter.hex, 16); isCounterHexa = true; } // get key var key; if (!_.isNull(_key.string) && !_.isUndefined(_key.string)) { key = { string: _key.string }; } else { key = { hex: _key.hex.toUpperCase() }; } // get flag to know if previous OTP values are allowed var previousOTPAllowed = _opt.previousOTPAllowed; // build opt object for gen method var opt = { codeDigits: _token.length, addChecksum: _opt.addChecksum, algorithm: _opt.algorithm }; if (!_.isNull(_opt.truncationOffset) && !_.isUndefined(_opt.truncationOffset)) { opt.truncationOffset = _opt.truncationOffset; } // Now loop through from C to C + W to determine if there is a correct code var min = counter, max = counter.add(window); // check if previousOTPAllowed if (previousOTPAllowed) { // Now loop through from C - W to C + W to determine if there is a correct code min = min.subtract(window); // check if min < 0 if (min.sign) { // Now loop through from 0 to C + W to determine if there is a correct code min = bigInt(0); } } for(var i = min; i.lesserOrEquals(max); i = i.next()) { // set counter in hexadecimal if (isCounterHexa) { opt.counter = {hex: pad.left(i.toString(16).toUpperCase(), 16, '0')}; } // set counter in integer else { opt.counter = {int: parseInt(i.toString())}; } // We have found a matching code, trigger callback and pass offset if (self.gen(key, opt) === _token) { // get delta var delta = i.subtract(counter); // delta in hexadecimal if (isCounterHexa) { var hex; // check if value < 0 to add good pad left if (delta.sign) { hex = '-' + pad.left(delta.toString(16).toUpperCase().substr(1), 16, '0'); } else { hex = pad.left(delta.toString(16).toUpperCase(), 16, '0'); } return { delta: { hex: hex } }; } // delta in integer else { return { delta: { int: parseInt(delta.toString()) } }; } } } // If we get to here then no codes have matched, return null return null; },
it('Should return true', (done) => { Joi.validate(project, schema, (err, value) => { expect(!!value).to.be.equal(true); done(); }); });
'use strict' const joi = require('joi') const {error, value: envVars} = joi.validate(process.env, joi.object({ // User to connect to mongodb MONGODB_USER: joi.string().default('mongoose'), // Password for the user specified MONGODB_PASS: joi.string(), // URL to connect to for mongodb MONGODB_HOST: joi.string().default('127.0.0.1'), // Port for the host to connect to MONGODB_PORT: joi.number().integer().min(1).default(27017), // Which database to use MONGODB_DATABASE: joi.string().default('stucoapp') }).unknown().required()) if (error) { throw new Error(`Config validation error: ${error.message}`) } const config = { mongodb: { user: envVars.MONGODB_USER, password: envVars.MONGODB_PASS, host: envVars.MONGODB_HOST, port: envVars.MONGODB_PORT, database: envVars.MONGODB_DATABASE } } module.exports = config
static _validateSchema(schema, model, options = {}) { if (!this.schema) return true; const result = Joi.validate(model, schema, options); return !result.error; }
exports.validateChallenge = function validateChallenge(challenge) { return Joi.validate(challenge, schema); };
module.exports = function(request, reply) { var createLicense = request.server.methods.npme.createLicense; var getCustomer = request.server.methods.npme.getCustomer; var updateCustomer = request.server.methods.npme.updateCustomer; var schema = Joi.object().keys({ id: Joi.string().token(), livemode: Joi.string(), client_ip: Joi.string(), created: Joi.string(), used: Joi.string(), object: Joi.string(), type: Joi.string(), card: Joi.object(), email: Joi.string().regex(/^.+@.+\..+$/), // email default accepts "boom@boom", which is kinda no bueno atm verification_allowed: Joi.string(), amount: Joi.number(), subType: Joi.number().valid([1, 2, 3]), quantity: Joi.number(), customerId: Joi.number() }); Joi.validate(request.payload, schema, function(err, token) { if (err) { request.logger.error('validation error'); request.logger.error(err); reply('validation error').code(403); return; } // load the customer by email and make sure the ID matches the one passed in getCustomer(token.email, function(err, customer) { if (err) { request.logger.error('error finding customer; email=' + token.email); request.logger.error(err); reply('error loading customer').code(500); return; } if (!customer) { request.logger.error('no customer found; email=' + token.email); reply('customer not found').code(500); return; } if (customer.id !== token.customerId) { request.logger.error('customer does not match ID; ID in db=' + customer.id + ';id passed=' + token.customerId + '; email=' + token.email); reply('error validating customer ID').code(500); return; } // pick a plan based on their selection var stripePlan, stripeQuantity, stripeDescription, licenseSeats; switch (token.subType) { case SUB_TYPE_MONTHLY: stripePlan = "enterprise-starter-pack"; stripeDescription = "npm Enterprise Starter Pack"; licenseSeats = 5; stripeQuantity = 1; break; case SUB_TYPE_ANNUAL: stripePlan = "enterprise-starter-pack-annual"; stripeDescription = "npm Enterprise Starter Pack (annual)"; licenseSeats = 5; stripeQuantity = 1; break; case SUB_TYPE_MULTI_SEAT: stripePlan = "enterprise-multi-seat"; stripeDescription = "npm Enterprise multi-seat license"; licenseSeats = token.quantity; stripeQuantity = licenseSeats; break; default: request.logger.error('invalid subscription type: ' + token.subType + '; email=' + token.email); reply('invalid subscription type').code(403); return; } // actually call stripe, record metrics, tell the client how things went var stripeStart = Date.now(); stripe.customers.create({ card: token.id, // obtained with Stripe.js plan: stripePlan, quantity: stripeQuantity, email: token.email, description: token.email + " " + stripeDescription }, function(err, stripeCustomer) { if (err) { request.logger.error('internal stripe error; plan=' + stripePlan + ';quantity=' + stripeQuantity + '; email=' + token.email); request.logger.error(err); reply('internal stripe error').code(500); return; } request.metrics.metric({ name: 'latency.stripe', value: Date.now() - stripeStart, }); request.logger.info('Stripe customer created: ', stripeCustomer); request.timing.page = 'enterprise-license-paymentProcessed'; // license purchased! We need to update the customer record with their stripe customer ID updateCustomer(customer.id, { stripe_customer_id: stripeCustomer.id }, function(er) { if (er) { request.logger.error('customer update error; id=' + customer.id); request.logger.error(er); reply('customer update error').code(500); return; } // now, create a new license for this customer and email it to them. var subscriptionId = stripeCustomer.subscriptions.data[0].id; var licenseStart = Date.now(); var licenseDetails = { billingEmail: token.email, seats: licenseSeats, stripeId: subscriptionId, // Danger! But we just created this customer, so only 1 subscription begins: moment(Date.now()).format(), // starts now ends: moment(Date.now()).add(1, 'years').format(), // ends a year from now (webhooks will refresh) }; createLicense(licenseDetails, function(err, license) { if (err) { request.logger.error('license creation error; email=' + token.email + ';seats=' + licenseSeats); request.logger.error(err); reply('license creation error').code(500); return; } request.metrics.metric({ name: 'latency.licenseCreation', value: Date.now() - licenseStart, }); request.logger.info('Successful license creation: ', license); request.timing.page = 'enterprise-license-created'; // now email them the generated license var sendEmail = request.server.methods.email.send; var data = { requirementsUrl: "https://docs.npmjs.com/enterprise/installation#requirements", instructionsUrl: "https://docs.npmjs.com/enterprise/installation", name: customer.name, email: customer.email, license_key: license.license_key }; sendEmail('enterprise-send-license', data, request.redis) .catch(function(er) { request.logger.error('Unable to send license to email', customer.email); request.logger.error(er); return reply('unable to send license email').code(500); }) .then(function() { return reply('License purchase successful').code(200); }); }); }); }); }); }); };
handler: function(request, next) { var changePass = request.payload; var validSchema = Joi.object().keys({ email: Joi.string().email().required(), password: Joi.string().alphanum().required().min(5).max(15), password2: Joi.any().valid(changePass.password), token: Joi.string().required() }) Joi.validate(changePass, validSchema,{abortEarly: false}, function (err, value) { if(err !== null) { var message = ''; for(i=0; i < err.details.length; i++) { var _message = err.details[i].message; if(err.details[i].path == 'password2') { message += 'Passwords must match. ' } else { message += _message.substr(0, 1).toUpperCase() + _message.substr(1) +'. '; } } return next({error: true, details: message}).type('application/json'); } else { var collection = db.collection('users'); collection.findOne({"email": changePass.email}, function(err, user) { if(err) throw err; // We are only going to change if we // 1. have a user // 2. we have the same token in DB // 3. Token is valid and not expired if(user && (user.forgotToken === changePass.token)) { Jwt.verify(user.forgotToken, forgotSecret, function(err, decoded) { if (err) { throw err; next({error: true, details: 'Incorrect Token'}); } else { var payload = {password: changePass.password, forgotToken: false} console.log(payload) API.call({ method: 'PUT', url: '/api/user/'+user._id, payload: payload, credentials: options.coreCreds, callback: function(err, res, payload) { if (err) throw err; next({error: false, details: 'Changed Password'}); } }); } }); } else { next({error: true, details: 'Incorrect Token'}); } }) } }) }
function validate(object, schema) { return joi.validate(object, schema, { allowUnknown: true }); }
exports.register = function(plugin, options, next){ config = options; var validation = joi.validate(options, schema) if(validation.error){ var err = new Error("config validation error") err.inner = validation.error return next(err); } plugin.log(["discovery"], "registering discovery routes"); plugin.route([ { method: "GET", path: "/discovery/announce", config: { handler: function(request, reply){ service.announce(function(err){ if(err){ return reply(err); } reply(); }); } } }, { method: "GET", path: "/discovery/unannounce", config: { handler: function(request, reply){ service.unannounce(function(err){ if(err){ return reply(err); } reply(); }); } } }, { method: "GET", path: "/discovery/lease", config: { handler: function(request, reply){ var lease = service.lease(); if(!lease){ return reply().code(404); } reply(lease); } } }, { method: "GET", path: "/discovery/lastUpdate", config: { handler: function(request, reply){ reply({ lastUpdate: service.lastUpdate().toISOString() }); } } } ]); plugin.expose({ announce: service.announce, unannounce: service.unannounce, find: service.find, findAll: service.findAll }); service.init(plugin, config, function(){ next(); }); };
register: function( req, res, next ) { //saves object to db function saveUser( userData ) { var newUser = new User( userData ); newUser.save( function( err, user ) { if ( err ) { logger.debug( 'Error inserting data into DB: ', err ); logger.trace( 'Erroneous data: ', userData ); if ( err.code === 11000 ) { res.status( 409 ).json( { message: 'Duplicate username and/or email address.' } ); } else { res.status( 500 ).json( { message: 'Error inserting user data into DB.' } ); } } else { res.redirect( '/login' ); } } ); } //creates user data object, and hashes password using bcrypt function registerUser( userData ) { var plainPassword = userData.password; bcrypt.hash( plainPassword, 8, function( err, hash ) { if ( err ) { res.status( 500 ).json( { message: 'Error storing user data in DB.' } ); } else { userData.password = hash; saveUser( userData ); } } ); } var userData = Object.assign( {}, req.body ); var userSchemaJoi = Joi.object().keys( { name: Joi.string().trim().regex( /^([a-z\s]){4,64}$/gi ).required(), username: Joi.string().trim().alphanum().min( 4 ).max( 32 ).required(), password: Joi.string().min( 4 ).max( 32 ).required(), confirmPassword: Joi.string().equal( Joi.ref( 'password' ) ).required(), email: Joi.string().trim().email().required(), confirmEmail: Joi.string().trim().equal( Joi.ref( 'email' ) ).email().required(), dob: Joi.date().required(), } ); Joi.validate( userData, userSchemaJoi, function( err, value ) { if ( err ) { var errMessage; logger.debug( 'Error validating user data. User data: ', value, '\nError: ', err ); //res.status(409).json({message: 'Invalid user data sent.'}); if ( err.details[ 0 ].path === 'name' ) { errMessage = 'The \'Name\' field has to contain letters only, and has to be between 4 and 64 characters long.'; } else if ( err.details[ 0 ].path === 'username' ) { errMessage = 'The \'Username\' field can only contain letters and numbers, and has to be 4-32 characters long.'; } else if ( err.details[ 0 ].path === 'password' ) { errMessage = 'The \'Password\' field has to be 4-32 characters long.'; } else if ( err.details[ 0 ].path === 'confirmPassword' ) { errMessage = 'The \'Confirm Password\' field has to match the \'password\'!'; } else if ( err.details[ 0 ].path === 'email' ) { errMessage = 'The \'Email\' field has to be a proper email address.'; } else if ( err.details[ 0 ].path === 'confirmEmail' ) { errMessage = 'The \'Confirm Email\' field has to match the \'email\' field!'; } else if ( err.details[ 0 ].path === 'dob' ) { errMessage = 'The \'Date of birth\' field is required and has to be in the format \'mm/dd/YYY\'.'; } else { errMessage = 'Form data is invalid!'; } res.status( 409 ).json( { message: errMessage } ); } else { //remove unnecessary fields delete value[ 'confirmEmail' ]; delete value[ 'confirmPassword' ]; registerUser( value ); } } ); },
internals.input = function (source, request, next) { if (typeof request[source] !== 'object') { return next(Boom.unsupportedMediaType(source + ' must represent an object')); } const postValidate = (err, value) => { request.orig[source] = request[source]; if (value !== undefined) { request[source] = value; } if (!err) { return next(); } if (err.isDeveloperError) { return next(err); } // failAction: 'error', 'log', 'ignore', function (source, err, next) if (request.route.settings.validate.failAction === 'ignore') { return next(); } // Prepare error const error = Boom.badRequest(err.message, err); error.output.payload.validation = { source: source, keys: [] }; if (err.details) { for (let i = 0; i < err.details.length; ++i) { error.output.payload.validation.keys.push(Hoek.escapeHtml(err.details[i].path)); } } if (request.route.settings.validate.errorFields) { const fields = Object.keys(request.route.settings.validate.errorFields); for (let i = 0; i < fields.length; ++i) { const field = fields[i]; error.output.payload[field] = request.route.settings.validate.errorFields[field]; } } request._log(['validation', 'error', source], error); // Log only if (request.route.settings.validate.failAction === 'log') { return next(); } // Return error if (typeof request.route.settings.validate.failAction !== 'function') { return next(error); } // Custom handler request._protect.run(next, (exit) => { const reply = request.server._replier.interface(request, request.route.realm, exit); request.route.settings.validate.failAction(request, reply, source, error); }); }; const localOptions = { context: { headers: request.headers, params: request.params, query: request.query, payload: request.payload, auth: { isAuthenticated: request.auth.isAuthenticated, credentials: request.auth.credentials } } }; delete localOptions.context[source]; Hoek.merge(localOptions, request.route.settings.validate.options); const schema = request.route.settings.validate[source]; if (typeof schema !== 'function') { return Joi.validate(request[source], schema, localOptions, postValidate); } request._protect.run(postValidate, (exit) => { return schema(request[source], localOptions, exit); }); };
EntityDatabase.prototype.newSearchRequest = function(searchParams, schema, filter) { var err = joi.validate(searchParams, schema); if (err) { throw err; } var request = this.request(); if (!lodash.isUndefined(searchParams.sort)) { request.sort(searchParams.sort.field, getSortOrder(searchParams.sort.descending)); } if (!lodash.isUndefined(searchParams.multiFieldSort)) { searchParams.multiFieldSort.forEach(function(sort){ request.sort(sort.field, getSortOrder(sort.descending)); }); } if (!lodash.isUndefined(searchParams.timeout)) { request.timeout(searchParams.timeout); } if (!lodash.isUndefined(searchParams.returnFields)) { request.fields(searchParams.returnFields); } if (!lodash.isUndefined(searchParams.version)) { request.version(searchParams.version); } if (!lodash.isUndefined(searchParams.from)) { request.from(searchParams.from); } if (!lodash.isUndefined(searchParams.pageSize)) { request.size(searchParams.pageSize); } if(searchParams.facet){ var termsFacet = this.ejs.TermsFacet(searchParams.facet.name); termsFacet.facetFilter(filter); request.facet(termsFacet); if(searchParams.facet.field){ termsFacet.field(searchParams.facet.field); }else{ termsFacet.fields(searchParams.facet.fields); } if (!lodash.isUndefined(searchParams.facet.size)) { termsFacet.size(searchParams.facet.size); } if (!lodash.isUndefined(searchParams.facet.excludes)) { termsFacet.excludes(searchParams.facet.excludes); } if (!lodash.isUndefined(searchParams.facet.order)) { termsFacet.order(searchParams.facet.order); } if (!lodash.isUndefined(searchParams.facet.regex)) { termsFacet.regex(searchParams.facet.regex); if (!lodash.isUndefined(searchParams.facet.regexFlags)) { termsFacet.regexFlags(searchParams.facet.regexFlags); } } } if (log.isDebugEnabled()) { log.debug('newSearchRequest() : ' + request); } return request; };
bindDn: Joi.string().required(), bindCredentials: Joi.string().required(), searchBase: Joi.string().required(), searchFilter: Joi.string().default( '(&(objectCategory=person)(objectClass=user))'), usernameField: Joi.string().default('userPrincipalName'), adminGroup: Joi.string().default('Domain Admins') }, elasticsearch: { hosts: Joi.array().items(Joi.string()).default(['localhost:9200']) } }; let argv = require('minimist')(process.argv.slice(2)); let configValidationResult = Joi.validate(JSON.parse(fs.readFileSync(argv.c, 'utf8')), schema); if (configValidationResult.err) { console.log(err); process.exit(1); } let config = configValidationResult.value; let ldapClient = ldap.createClient({ url: config.ldap.url }); let elasticsearchClient = elasticsearch.Client({ hosts: config.elasticsearch.hosts });
value: function(k, o) { // set defaults values var _key = k || '', _opt = o || {}; // validate inputs var keyValidate = joi.validate(_key, schema.key, {language: {label: 'key'}}); if (keyValidate.error) { throw keyValidate.error; } _key = keyValidate.value; var optValidate = joi.validate(_opt, schema.opt, {language: {label: 'opt'}}); if (optValidate.error) { throw optValidate.error; } _opt = optValidate.value; // get key and change it in bytes array var key; if (_key.string) { key = conv(_key.string, {in: 'binary', out:'bytes'}); } else { key = conv(_key.hex, {in: 'hex', out:'bytes'}); } // get counter and change it in bytes array var counter; if (!_.isNull(_opt.counter.int) && !_.isUndefined(_opt.counter.int)) { counter = conv(pad.left(Converter.convert(_opt.counter.int, 10, 16), 16, '0'), {in: 'hex', out:'bytes'}); } else { counter = conv(pad.left(_opt.counter.hex, 16, '0'), {in: 'hex', out:'bytes'}); } // get other options var codeDigits = _opt.codeDigits; var addChecksum = _opt.addChecksum; var algorithm = _opt.algorithm; var truncationOffset; if (!_.isNull(_opt.truncationOffset) && !_.isUndefined(_opt.truncationOffset)) { truncationOffset = _opt.truncationOffset; } else { truncationOffset = -1; } // return OTP return generateOTP(key, counter, codeDigits, addChecksum, truncationOffset, algorithm); },
/** * Validates spike options, provides defaults where necessary * @param {Object} opts - spike options object * @return {Object} validated and fully filled out objects */ validateOpts (opts) { // override argpare's annoying use of null values if (opts.env === null) { opts.env = undefined } const schema = Joi.object().keys({ root: Joi.string().required(), env: Joi.string(), matchers: Joi.object().default().keys({ jade: Joi.string().default('**/*.jade'), css: Joi.string().default('**/*.sss'), js: Joi.string().default('**/*.js'), static: Joi.string().default('!**/*.+(js|sss|jade)') }), postcss: Joi.object().default().keys({ plugins: Joi.array().single().default([]), parser: Joi.object(), stringifier: Joi.object(), syntax: Joi.object() }), babelConfig: Joi.object().default({}), cleanUrls: Joi.bool().default(true), jade: Joi.object().default({}), dumpDirs: Joi.array().default(['views', 'assets']), locals: Joi.object().default({}), ignore: Joi.array().default([]), entry: Joi.object().default({ 'js/main': ['./assets/js/index.js'] }), modulesDirectories: Joi.array().default(['node_modules', 'bower_components']), outputDir: Joi.string().default('public'), plugins: Joi.array().default([]), module: Joi.object().default().keys({ loaders: Joi.array().default([]) }), resolve: Joi.object().default().keys({ alias: Joi.object().default({}) }), server: Joi.object().default().keys({ watchOptions: Joi.object().default().keys({ ignored: Joi.array().default('node_modules') }), server: Joi.object().default({}), port: Joi.number().default(1111), middleware: Joi.array().default([]), logLevel: Joi.string().default('silent'), logPrefix: Joi.string().default('spike'), notify: Joi.bool().default(false), host: Joi.string().default('localhost') }) }) const validation = Joi.validate(opts, schema, { allowUnknown: true }) if (validation.error) { throw new Error(validation.error) } let res = validation.value // Joi can't handle defaulting this, so we do it manually res.server.server.baseDir = res.outputDir.replace(res.root, '') // add cleanUrls middleware to browserSync if cleanUrls === true if (res.cleanUrls) { res.server.middleware.unshift(hygienist(res.server.server.baseDir)) } // ensure server.watchOptions.ignored is an array (browsersync accepts // string or array), then push ['node_modules', '.git', outputDir] to make // sure they're not watched res.server.watchOptions.ignored = Array.prototype.concat(res.server.watchOptions.ignored) res.server.watchOptions.ignored = union(res.server.watchOptions.ignored, ['node_modules', '.git', res.outputDir]) // Here we set up the matchers that will watch for newly added files to the // project. // // The browsersync matcher doesn't like absolute paths, so we calculate the // relative path from cwd to your project root. Usually this will be an // empty string as spike commands are typically run from the project root. // // We then add all the watcher ignores so that they do not trigger the "new // file added to the project" code path. They are added twice, the first // time for the directory contents, and the second for the directory itself. const p = path.relative(process.cwd(), res.root) let allWatchedFiles = [path.join(p, '**/*')] .concat(res.server.watchOptions.ignored.map((i) => { return `!${path.join(p, i, '**/*')}` })) .concat(res.server.watchOptions.ignored.map((i) => { return `!${path.join(p, i)}` })) // catch newly added files, put through the pipeline res.server.files = [{ match: allWatchedFiles, fn: (event, file) => { const f = path.join(this.context, file.replace(p, '')) const files = this.spike.files.all if (files.indexOf(f) < 0 && !this.spike.ignored(f) && event !== 'addDir') { this.project.watcher.watch([], [], [f]) } } }] return res }
exports.view = function (options) { var error = Joi.validate(options, internals.viewSchema); return (error ? error.annotated() : null); };