'use strict'; const Joi = require('joi'); const MongoModels = require('mongo-models'); class Dummy extends MongoModels {} Dummy.collectionName = 'dummies'; Dummy.schema = Joi.object().keys({ name: Joi.string().required(), hasHat: Joi.boolean() }); Dummy.indexes = [ { key: { name: 1 } }, { key: { hasHat: -1 } } ]; module.exports = Dummy;
export default () => Joi.object({ pkg: Joi.object({ version: Joi.string().default(Joi.ref('$version')), branch: Joi.string().default(Joi.ref('$branch')), buildNum: Joi.number().default(Joi.ref('$buildNum')), buildSha: Joi.string().default(Joi.ref('$buildSha')), }).default(), env: Joi.object({ name: Joi.string().default(Joi.ref('$env')), dev: Joi.boolean().default(Joi.ref('$dev')), prod: Joi.boolean().default(Joi.ref('$prod')) }).default(), dev: Joi.object({ basePathProxyTarget: Joi.number().default(5603), }).default(), pid: Joi.object({ file: Joi.string(), exclusive: Joi.boolean().default(false) }).default(), cpu: Joi.object({ cgroup: Joi.object({ path: Joi.object({ override: Joi.string().default() }) }) }), cpuacct: Joi.object({ cgroup: Joi.object({ path: Joi.object({ override: Joi.string().default() }) }) }), server: Joi.object({ uuid: Joi.string().guid().default(), name: Joi.string().default(os.hostname()), host: Joi.string().hostname().default('localhost'), port: Joi.number().default(5601), maxPayloadBytes: Joi.number().default(1048576), autoListen: Joi.boolean().default(true), defaultRoute: Joi.string().default('/app/kibana').regex(/^\//, `start with a slash`), basePath: Joi.string().default('').allow('').regex(/(^$|^\/.*[^\/]$)/, `start with a slash, don't end with one`), customResponseHeaders: Joi.object().unknown(true).default({}), ssl: Joi.object({ enabled: Joi.boolean().default(false), redirectHttpFromPort: Joi.number(), certificate: Joi.string().when('enabled', { is: true, then: Joi.required(), }), key: Joi.string().when('enabled', { is: true, then: Joi.required() }), keyPassphrase: Joi.string(), certificateAuthorities: Joi.array().single().items(Joi.string()), supportedProtocols: Joi.array().items(Joi.string().valid('TLSv1', 'TLSv1.1', 'TLSv1.2')), cipherSuites: Joi.array().items(Joi.string()).default(cryptoConstants.defaultCoreCipherList.split(':')) }).default(), cors: Joi.when('$dev', { is: true, then: Joi.object().default({ origin: ['*://localhost:9876'] // karma test server }), otherwise: Joi.boolean().default(false) }), xsrf: Joi.object({ disableProtection: Joi.boolean().default(false), token: Joi.string().optional().notes('Deprecated') }).default(), }).default(), logging: Joi.object().keys({ silent: Joi.boolean().default(false), quiet: Joi.boolean() .when('silent', { is: true, then: Joi.default(true).valid(true), otherwise: Joi.default(false) }), verbose: Joi.boolean() .when('quiet', { is: true, then: Joi.valid(false).default(false), otherwise: Joi.default(false) }), events: Joi.any().default({}), dest: Joi.string().default('stdout'), filter: Joi.any().default({}), json: Joi.boolean() .when('dest', { is: 'stdout', then: Joi.default(!process.stdout.isTTY), otherwise: Joi.default(true) }), useUTC: Joi.boolean().default(true), }) .default(), ops: Joi.object({ interval: Joi.number().default(5000), }).default(), plugins: Joi.object({ paths: Joi.array().items(Joi.string()).default([]), scanDirs: Joi.array().items(Joi.string()).default([]), initialize: Joi.boolean().default(true) }).default(), path: Joi.object({ data: Joi.string().default(getData()) }).default(), optimize: Joi.object({ enabled: Joi.boolean().default(true), bundleFilter: Joi.string().default('!tests'), bundleDir: Joi.string().default(fromRoot('optimize/bundles')), viewCaching: Joi.boolean().default(Joi.ref('$prod')), watch: Joi.boolean().default(false), watchPort: Joi.number().default(5602), watchHost: Joi.string().hostname().default('localhost'), watchPrebuild: Joi.boolean().default(false), watchProxyTimeout: Joi.number().default(5 * 60000), useBundleCache: Joi.boolean().default(Joi.ref('$prod')), unsafeCache: Joi.when('$prod', { is: true, then: Joi.boolean().valid(false), otherwise: Joi .alternatives() .try( Joi.boolean(), Joi.string().regex(/^\/.+\/$/) ) .default(true), }), sourceMaps: Joi.when('$prod', { is: true, then: Joi.boolean().valid(false), otherwise: Joi .alternatives() .try( Joi.string().required(), Joi.boolean() ) .default('#cheap-source-map'), }), profile: Joi.boolean().default(false) }).default(), status: Joi.object({ allowAnonymous: Joi.boolean().default(false) }).default(), map: Joi.object({ manifestServiceUrl: Joi.when('$dev', { is: true, then: Joi.string().default('https://staging-dot-catalogue-dot-elastic-layer.appspot.com/v1/manifest'), otherwise: Joi.string().default('https://catalogue.maps.elastic.co/v1/manifest') }) }).default(), tilemap: Joi.object({ url: Joi.string(), options: Joi.object({ attribution: Joi.string(), minZoom: Joi.number().min(0, 'Must be 0 or higher').default(0), maxZoom: Joi.number().default(10), tileSize: Joi.number(), subdomains: Joi.array().items(Joi.string()).single(), errorTileUrl: Joi.string().uri(), tms: Joi.boolean(), reuseTiles: Joi.boolean(), bounds: Joi.array().items(Joi.array().items(Joi.number()).min(2).required()).min(2) }).default() }).default(), regionmap: Joi.object({ includeElasticMapsService: Joi.boolean().default(true), layers: Joi.array().items(Joi.object({ url: Joi.string(), type: Joi.string(), attribution: Joi.string(), name: Joi.string(), fields: Joi.array().items(Joi.object({ name: Joi.string(), description: Joi.string() })) })) }).default(), i18n: Joi.object({ defaultLocale: Joi.string().default('en'), }).default(), }).default();
'wheelchair' ]) .default('driving-car') .description( 'Specifies the mode of transport to use when calculating directions.' ), restrictions: Joi.object() .when('profile', { is: Joi.string().regex(/^driving-hgv$/), then: Joi.object().keys({ length: Joi.number().description('Length of the HGV vehicle'), width: Joi.number().description('Width of the HGV vehicle'), weight: Joi.number().description('Weight of the HGV vehicle'), height: Joi.number().description('Height of the HGV vehicle'), axleload: Joi.number().description('Axleload of the HGV vehicle'), hazmat: Joi.boolean().description( 'Whether the HGV carries hazardous materials' ) }) }) .when('profile', { is: Joi.string().regex(/^wheelchair$/), then: Joi.object().keys({ surface_type: Joi.any().description('Surface type'), track_type: Joi.any().description('Track type'), smoothness_type: Joi.any().description('Smoothness type'), maximum_sloped_curb: Joi.any().description('Maximum sloped curb'), maximum_incline: Joi.any().description('Maximum incline') }) }) .when('profile', {
internals.Policy.prototype.ttl = function (created) { return internals.Policy.ttl(this.rule, created); }; internals.schema = Joi.object({ expiresIn: Joi.number().integer().min(1), expiresAt: Joi.string().regex(/^\d\d?\:\d\d$/), staleIn: [Joi.number().integer().min(1).max(86400000 - 1), Joi.func()], // One day - 1 (max is inclusive) staleTimeout: Joi.number().integer().min(1), generateFunc: Joi.func(), generateTimeout: Joi.number().integer().min(1).allow(false), generateOnReadError: Joi.boolean(), generateIgnoreWriteError: Joi.boolean(), dropOnError: Joi.boolean(), pendingGenerateTimeout: Joi.number().integer().min(1), // Ignored external keys (hapi) privacy: Joi.any(), cache: Joi.any(), segment: Joi.any(), shared: Joi.any() }) .without('expiresIn', 'expiresAt') .with('staleIn', 'generateFunc') .with('generateOnReadError', 'generateFunc') .with('generateIgnoreWriteError', 'generateFunc')
page: { allow: true }, create: { allow: true }, delete: { allow: true } }; var noCreatePermissions = { page: { allow: true }, delete: { allow: true } }; var noPermissions = {}; var mentions = { validation: Joi.object().keys({ page: Joi.object().keys({ allow: Joi.boolean() }), create: Joi.object().keys({ allow: Joi.boolean() }), delete: Joi.object().keys({ allow: Joi.boolean() }) }), layout: { page: { title: 'Allow User to View Mentions' }, create: { title: 'Allow User to Create Mentions' }, delete: { title: 'Allow User to Delete Mentions' } },
const joi = require('joi') const envVarsSchema = joi.object({ NODE_ENV: joi.string() .allow(['development', 'production', 'test', 'provision']) .required(), PORT: joi.number() .required(), LOGGER_LEVEL: joi.string() .allow(['error', 'warn', 'info', 'verbose', 'debug', 'silly']) .default('info'), LOGGER_ENABLED: joi.boolean() .truthy('TRUE') .truthy('true') .falsy('FALSE') .falsy('false') .default(true) }).unknown() .required() const { error, value: envVars } = joi.validate(process.env, envVarsSchema) if (error) { throw new Error(`Config validation error: ${error.message}`) } const config = { env: envVars.NODE_ENV, isTest: envVars.NODE_ENV === 'test', isDevelopment: envVars.NODE_ENV === 'development', logger: { level: envVars.LOGGER_LEVEL,
var lodash = require('lodash'); var joi = require('joi'); var types = { 'number' : {validate: joi.number()}, 'alpha' : {validate: joi.string().regex(/^[a-z]+$/i)}, 'alphanumeric' : {validate: joi.string().alphanum()}, 'date' : { validate: joi.date(), default: function () { return Date.now(); } }, 'email' : {validate: joi.string().email()}, 'boolean' : { validate: joi.boolean(), default: false, onSet: Boolean, processIn: Boolean, }, 'integer': { validate: joi.number().integer(), processIn: function (v) { return parseInt(v, 10); }, setTo: function (v) { return parseInt(v, 10); }, }, 'enum': { validate: function (value) {
var Joi = require('joi'); var ConfigSchema = Joi.object().keys({ tz: Joi.string().required(), port: Joi.number().required(), recordspath: Joi.string().required(), db: Joi.object().keys({ client: Joi.string().required(), connection: Joi.object().keys({ host: Joi.string().required(), port: Joi.number().integer().min(1).max(65535).default(3306), user: Joi.string().required(), database: Joi.string().required(), password: Joi.string().allow('').required(), charset: Joi.string().required() }).required() }), cdr: Joi.object().keys({ table: Joi.string().required() }).required(), auth: Joi.boolean().valid(true, false).default(false), username: Joi.string() .when('auth', {is: true, then: Joi.required().default('admin')}), password: Joi.string() .when('auth', {is: true, then: Joi.required().default('password')}), realm: Joi.string() .when('auth', {is: true, then: Joi.default('Ryo CDR')}), }); module.exports = ConfigSchema;
const Hoek = require('hoek'); const Joi = require('joi'); const Etag = require('./etag'); // Declare internals const internals = {}; internals.schema = Joi.alternatives([ Joi.string(), Joi.func(), Joi.object({ path: Joi.alternatives(Joi.string(), Joi.func()).required(), confine: Joi.alternatives(Joi.string(), Joi.boolean()).default(true), filename: Joi.string(), mode: Joi.string().valid('attachment', 'inline').allow(false), lookupCompressed: Joi.boolean(), etagMethod: Joi.string().valid('hash', 'simple').allow(false) }) .with('filename', 'mode') ]); exports.handler = function (route, options) { let settings = Joi.attempt(options, internals.schema, 'Invalid file handler options (' + route.path + ')'); settings = (typeof options !== 'object' ? { path: options, confine: '.' } : settings); settings.confine = settings.confine === true ? '.' : settings.confine; Hoek.assert(typeof settings.path !== 'string' || settings.path[settings.path.length - 1] !== '/', 'File path cannot end with a \'/\':', route.path);
module.exports = function(options) { var serverConfig = { debug: options.debug, connections: { routes: { security: true } } }; if ( options.redisUrl ) { var redisUrl = require('redis-url').parse(options.redisUrl); serverConfig.cache = { engine: require('catbox-redis'), host: redisUrl.hostname, port: redisUrl.port, password: redisUrl.password }; } var server = new Hapi.Server(serverConfig); server.connection({ host: options.host, port: options.port }); if ( options.logging ) { server.register({ register: require('hapi-bunyan'), options: { logger: require('bunyan').createLogger({ name: 'id-webmaker-org', level: options.logLevel }) } }, function(err) { Hoek.assert(!err, err); }); } server.register([ require('hapi-auth-cookie'), require('inert'), require('scooter'), { register: require('blankie'), options: { defaultSrc: [ '\'none\'' ], styleSrc: [ '\'self\'', 'https://fonts.googleapis.com' ], imgSrc: [ '\'self\'', 'data:', 'https://www.google-analytics.com', 'http://www.google-analytics.com' ], scriptSrc: [ '\'self\'', '\'unsafe-eval\'', 'https://www.google-analytics.com', 'http://www.google-analytics.com' ], fontSrc: [ '\'self\'', 'https://fonts.gstatic.com' ] } } ], function(err) { // MAYDAY, MAYDAY, MAYDAY! Hoek.assert(!err, err); server.auth.strategy('session', 'cookie', { password: options.cookieSecret, cookie: 'webmaker', ttl: 1000 * 60 * 60 * 24, isSecure: options.secureCookies, isHttpOnly: true }); server.auth.default({ strategy: 'session', mode: 'try' }); }); function skipCSRF(request, reply) { return true; } function isUniqueError(fieldName, err) { // SQLite and MariaDB/MySQL have conflicting error messages, and we don't know which DB the login server is using if ( err && // SQLite err.indexOf('Users.' + fieldName) !== -1 || ( // MariaDB/MySQL err.indexOf('ER_DUP_ENTRY') !== -1 && err.indexOf(fieldName) !== -1 ) ) { return true; } return false; } server.register({ register: require('crumb'), options: { restful: true, skip: !options.enableCSRF ? skipCSRF : undefined, cookieOptions: { isSecure: options.secureCookies } } }, function(err) { Hoek.assert(!err, err); }); server.register({ register: require('../lib/account'), options: { loginAPI: options.loginAPI, uri: options.uri } }, function(err) { Hoek.assert(!err, err); }); var oauthDb = new OAuthDB(options.oauth_clients, options.authCodes, options.accessTokens); server.route([ { method: 'GET', path: '/', handler: function(request, reply) { reply.redirect('/signup'); } }, { method: 'GET', path: '/{params*}', handler: { file: { path: Path.join(__dirname, '../public/index.html') } } }, { method: 'GET', path: '/assets/{param*}', handler: { directory: { path: Path.join(__dirname, '../public') } } }, { method: 'GET', path: '/login/oauth/authorize', config: { validate: { query: { client_id: Joi.string().required(), response_type: Joi.string().valid('code', 'token'), scopes: Joi.string().required(), state: Joi.string().required(), action: Joi.string().optional().valid('signup', 'signin').default('signin') } }, pre: [ { assign: 'user', method: function(request, reply) { if (request.auth.isAuthenticated) { return reply(request.auth.credentials); } var redirectUrl = '/login'; if (request.query.action === 'signup') { redirectUrl = '/signup'; } var redirect = url.parse(redirectUrl, true); redirect.query.client_id = request.query.client_id; redirect.query.response_type = request.query.response_type; redirect.query.state = request.query.state; redirect.query.scopes = request.query.scopes; reply().takeover().redirect(url.format(redirect)); } }, { assign: 'client', method: function(request, reply) { oauthDb.getClient(request.query.client_id, reply); } }, { method: function(request, reply) { if ( request.pre.client.allowed_responses.indexOf(request.query.response_type) === -1 ) { return reply(Boom.forbidden('Response type forbidden: ' + request.query.response_type)); } reply(); } }, { assign: 'scopes', method: function(request, reply) { reply(request.query.scopes.split(' ')); } }, { assign: 'auth_code', method: function(request, reply) { if (request.query.response_type !== 'code') { return reply(null); } oauthDb.generateAuthCode( request.pre.client.client_id, request.pre.user.id, request.pre.scopes, new Date(Date.now() + 60 * 1000).toISOString(), function(err, authCode) { if (err) { return reply(Boom.badRequest('An error occurred processing your request', err)); } reply(authCode); } ); } }, { assign: 'access_token', method: function(request, reply) { if (request.query.response_type !== 'token') { return reply(null); } oauthDb.generateAccessToken( request.pre.client.client_id, request.pre.user.id, request.pre.scopes, reply ); } } ] }, handler: function(request, reply) { var redirectObj = url.parse(request.pre.client.redirect_uri, true); redirectObj.search = null; if (request.query.response_type === 'token') { redirectObj.hash = 'token=' + request.pre.access_token; } else { redirectObj.query.code = request.pre.auth_code; redirectObj.query.client_id = request.query.client_id; } redirectObj.query.state = request.query.state; reply.redirect(url.format(redirectObj)); } }, { method: 'POST', path: '/login/oauth/access_token', config: { validate: { payload: { grant_type: Joi.any().valid('authorization_code', 'password').required(), code: Joi.string().when('grant_type', { is: 'authorization_code', then: Joi.required(), otherwise: Joi.forbidden() }), client_secret: Joi.string().when('grant_type', { is: 'authorization_code', then: Joi.required(), otherwise: Joi.forbidden() }), client_id: Joi.string().required(), uid: Joi.string().when('grant_type', { is: 'password', then: Joi.required(), otherwise: Joi.forbidden() }), password: Joi.string().when('grant_type', { is: 'password', then: Joi.required(), otherwise: Joi.forbidden() }), scopes: Joi.string().when('grant_type', { is: 'password', then: Joi.required(), otherwise: Joi.forbidden() }) }, failAction: function(request, reply, source, error) { reply(Boom.badRequest('invalid ' + source + ': ' + error.data.details[0].path)); } }, auth: false, plugins: { crumb: false }, pre: [ { assign: 'grant_type', method: function (request, reply) { reply(request.payload.grant_type); } }, { assign: 'client', method: function(request, reply) { oauthDb.getClient(request.payload.client_id, function(err, client) { if ( err ) { return reply(err); } if ( client.allowed_grants.indexOf(request.pre.grant_type) === -1 || ( request.pre.grant_type === 'authorization_code' && client.client_secret !== request.payload.client_secret ) ) { return reply(Boom.forbidden('Invalid Client Credentials')); } reply(client); }); } }, { assign: 'authCode', method: function(request, reply) { if ( request.pre.grant_type === 'password' ) { return server.methods.account.verifyPassword(request, function(err, json) { if ( err ) { return reply(err); } reply({ user_id: json.user.id, scopes: request.payload.scopes.split(' ') }); }); } oauthDb.verifyAuthCode(request.payload.code, request.pre.client.client_id, reply); } }, { assign: 'accessToken', method: function(request, reply) { oauthDb.generateAccessToken( request.pre.client.client_id, request.pre.authCode.user_id, request.pre.authCode.scopes, reply ); } } ] }, handler: function(request, reply) { var responseObj = { access_token: request.pre.accessToken, scopes: request.pre.authCode.scopes, token_type: 'token' }; reply(responseObj); } }, { method: 'POST', path: '/login', config: { pre: [ { assign: 'user', method: function(request, reply) { server.methods.account.verifyPassword(request, function(err, json) { if ( err ) { return reply(err); } reply(json.user); }); } } ] }, handler: function(request, reply) { request.auth.session.set(request.pre.user); reply({ status: 'Logged In' }); } }, { method: 'POST', path: '/request-reset', config:{ auth: false }, handler: function(request, reply) { server.methods.account.requestReset(request, function(err, json) { if ( err ) { return reply(err); } reply(json); }); } }, { method: 'POST', path: '/reset-password', config:{ auth: false }, handler: function(request, reply) { server.methods.account.resetPassword(request, function(err, json) { if ( err ) { return reply(err); } reply(json); }); } }, { method: 'POST', path: '/create-user', config: { auth: false, plugins: { crumb: false }, cors: true, validate: { payload: { username: Joi.string().regex(/^[a-zA-Z0-9\-]{1,20}$/).required(), email: Joi.string().email().required(), password: Joi.string().regex(/^\S{8,128}$/).required(), feedback: Joi.boolean().required(), client_id: Joi.string().required(), lang: Joi.string().default('en-US') }, failAction: function(request, reply, source, error) { reply(Boom.badRequest('invalid ' + source + ': ' + error.data.details[0].path)); } }, pre: [ { assign: 'username', method: function(request, reply) { reply(request.payload.username); } }, { assign: 'password', method: function(request, reply) { var password = request.payload.password; var result = passTest.test(password); if ( !result.strong ) { var err = Boom.badRequest('Password not strong enough.', result); err.output.payload.details = err.data; return reply(err); } reply(password); } }, { assign: 'client', method: function(request, reply) { oauthDb.getClient(request.payload.client_id, reply); } } ] }, handler: function(request, reply) { server.methods.account.createUser(request, function(err, json) { if ( err ) { err.output.payload.data = err.data; return reply(err); } if ( json.login_error ) { if ( isUniqueError('username', json.login_error) ) { return reply(Boom.badRequest('That username is taken')); } else if ( isUniqueError('email', json.login_error) ) { return reply(Boom.badRequest('An account exists for that email address')); } return reply(Boom.badRequest(json.login_error)); } request.auth.session.set(json.user); reply(json.user); }); } }, { method: 'GET', path: '/logout', config: { auth: false, pre: [ { assign: 'redirectUri', method: function(request, reply) { if ( !request.query.client_id ) { return reply('https://webmaker.org'); } oauthDb.getClient(request.query.client_id, function(err, client) { if ( err ) { return reply(err); } reply(client.redirect_uri); }); } } ] }, handler: function(request, reply) { request.auth.session.clear(); var redirectObj = url.parse(request.pre.redirectUri, true); redirectObj.query.logout = true; reply.redirect(url.format(redirectObj)) .header('cache-control', 'no-cache'); } }, { method: 'GET', path: '/user', config: { auth: false, cors: true, pre: [ { assign: 'requestToken', method: function(request, reply) { var tokenHeader = request.headers.authorization || ''; tokenHeader = tokenHeader.split(' '); if ( tokenHeader[0] !== 'token' || !tokenHeader[1] ) { return reply(Boom.unauthorized('Missing or invalid authorization header')); } reply(tokenHeader[1]); } }, { assign: 'token', method: function(request, reply) { oauthDb.lookupAccessToken(request.pre.requestToken, function(err, token) { if ( err ) { return reply(err); } if ( token.expires_at <= Date.now() ) { return reply(Boom.unauthorized('Expired token')); } var tokenScopes = token.scopes; if ( tokenScopes.indexOf('user') === -1 && tokenScopes.indexOf('email') === -1 ) { return reply(Boom.unauthorized('The token does not have the required scopes')); } reply(token); }); } }, { assign: 'user', method: function(request, reply) { server.methods.account.getUser(request.pre.token.user_id, function(err, json) { if ( err ) { return reply(Boom.badImplementation(err)); } reply(json.user); }); } } ] }, handler: function(request, reply) { var responseObj = Scopes.filterUserForScopes( request.pre.user, request.pre.token.scopes ); reply(responseObj); } }, { method: 'POST', path: '/request-migration-email', config: { auth: false }, handler: function(request, reply) { server.methods.account.requestMigrateEmail(request, function(err, json) { if ( err ) { return reply(Boom.badImplementation(err)); } reply({ status: 'migration email sent' }); }); } }, { method: 'POST', path: '/migrate-user', config: { auth: false, pre: [ { assign: 'uid', method: function(request, reply) { reply(request.payload.uid); } }, { assign: 'password', method: function(request, reply) { var password = request.payload.password; if ( !password ) { return reply(Boom.badRequest('No password provided')); } var result = passTest.test(password); if ( !result.strong ) { return reply(Boom.badRequest('Password not strong enough'), result); } reply(password); } }, { assign: 'isValidToken', method: function(request, reply) { server.methods.account.verifyToken(request, function(err, json) { if ( err ) { return reply(err); } reply(true); }); } }, { assign: 'user', method: function(request, reply) { server.methods.account.setPassword( request, request.pre.uid, request.pre.password, function(err, json) { if ( err ) { return reply(err); } reply(json.user); } ); } } ] }, handler: function(request, reply) { request.auth.session.set(request.pre.user); reply({ status: 'Logged in' }); } }, { method: 'POST', path: '/check-username', config: { auth: false }, handler: function(request, reply) { server.methods.account.checkUsername(request, function(err, json) { if ( err ) { return reply(err); } reply(json); }); } } ]); return server; };
}; internals.schema = {}; internals.schema.viewOverride = Joi.object({ path: [Joi.array().items(Joi.string()), Joi.string()], relativeTo: Joi.string(), compileOptions: Joi.object(), runtimeOptions: Joi.object(), layout: Joi.string().allow(false, true), layoutKeyword: Joi.string(), layoutPath: [Joi.array().items(Joi.string()), Joi.string()], encoding: Joi.string(), allowAbsolutePaths: Joi.boolean(), allowInsecureAccess: Joi.boolean(), contentType: Joi.string() }); internals.schema.viewBase = internals.schema.viewOverride.keys({ partialsPath: [Joi.array().items(Joi.string()), Joi.string()], helpersPath: [Joi.array().items(Joi.string()), Joi.string()], isCached: Joi.boolean(), compileMode: Joi.string().valid('sync', 'async'), defaultExtension: Joi.string() }); internals.schema.manager = internals.schema.viewBase.keys({
var Joi = require('joi'); var generateUsername = function (context) { return context.firstname.toLowerCase() + '-' + context.lastname.toLowerCase(); }; generateUsername.description = 'generated username'; module.exports = { body: { username: Joi.string().default(generateUsername), firstname: Joi.string(), lastname: Joi.string(), created: Joi.date().default(Date.now, 'time of creation'), status: Joi.string().default('registered'), registered: Joi.boolean().default(true), type: Joi.string().when('registered', { is: true, then: Joi.default('registered'), otherwise: Joi.default('unregistered') }), values: Joi.array().default(['1']) } };
exports.register = (server, options, next) => { const scm = server.root.app.pipelineFactory.scm; const pluginOptions = joi.attempt(options, joi.object().keys({ username: joi.string().required(), ignoreCommitsBy: joi.array().items(joi.string()).optional(), restrictPR: joi.string().valid('all', 'none', 'branch', 'fork').optional(), chainPR: joi.boolean().optional(), maxBytes: joi.number().integer().optional() }), 'Invalid config for plugin-webhooks'); server.route({ method: 'POST', path: '/webhooks', config: { description: 'Handle webhook events', notes: 'Acts on pull request, pushes, comments, etc.', tags: ['api', 'webhook'], payload: { maxBytes: parseInt(pluginOptions.maxBytes, 10) || DEFAULT_MAX_BYTES }, handler: async (request, reply) => { const userFactory = request.server.app.userFactory; const ignoreUser = pluginOptions.ignoreCommitsBy; let message = 'Unable to process this kind of event'; let skipMessage; try { const parsed = await scm.parseHook(request.headers, request.payload); if (!parsed) { // for all non-matching events or actions return reply({ message }).code(204); } const { type, hookId, username, scmContext, ref, checkoutUrl, action } = parsed; request.log(['webhook', hookId], `Received event type ${type}`); // skipping checks if (/\[(skip ci|ci skip)\]/.test(parsed.lastCommitMessage)) { skipMessage = 'Skipping due to the commit message: [skip ci]'; } // if skip ci then don't return if (ignoreUser && ignoreUser.includes(username) && !skipMessage) { message = `Skipping because user ${username} is ignored`; request.log(['webhook', hookId], message); return reply({ message }).code(204); } const token = await obtainScmToken( pluginOptions, userFactory, username, scmContext); if (!parsed.sha) { try { parsed.sha = await getCommitRefSha({ scm, token, ref, checkoutUrl, scmContext }); } catch (err) { request.log(['webhook', hookId, 'getCommitRefSha'], err); // there is a possibility of scm.getCommitRefSha() is not implemented yet return reply({ message }).code(204); } } if (action !== 'release' && action !== 'tag') { await promiseToWait(WAIT_FOR_CHANGEDFILES); parsed.changedFiles = await scm.getChangedFiles({ payload: request.payload, type, token, scmContext }); request.log(['webhook', hookId], `Changed files are ${parsed.changedFiles}`); } if (type === 'pr') { // disregard skip ci for pull request events return pullRequestEvent(pluginOptions, request, reply, parsed, token); } return pushEvent(pluginOptions, request, reply, parsed, skipMessage, token); } catch (err) { return reply(boom.boomify(err)); } } } }); next(); };
getMoodParams: { user: common.primaryKeyId, team: common.primaryKeyId, city: common.primaryKeyId, }, radioParams: { city: common.primaryKeyId, id: common.primaryKeyId, }, eventsParams: { city: common.primaryKeyId, id: common.primaryKeyId, showPast: Joi.boolean().default(false), }, citiesParams: { city: common.primaryKeyId, }, teamsParams: { city: common.primaryKeyId, }, }; const conversions = {}; function assert(obj, schemaName) { var joiObj = _getSchema(schemaName);
} module.exports = { auth: { strategy: auth.AUTH_STRATEGY, scope: auth.SCOPE_CLIENT_MANAGEMENT.getImplicantValues() }, response: { schema: { clients: Joi.array().items( Joi.object().keys({ id: validators.clientId, name: Joi.string().required(), image_uri: Joi.string().allow(''), redirect_uri: Joi.string().allow('').required(), can_grant: Joi.boolean().required(), trusted: Joi.boolean().required() }) ) } }, handler: async function listEndpoint(req) { const developerEmail = req.auth.credentials.email; return db.getClients(developerEmail).then(function(clients) { return { clients: clients.map(serialize) }; }); } };
var Joi = require('joi'); var strOrArray = Joi.alternatives().try(Joi.string(), Joi.array().includes(Joi.string())); var sandboxString = Joi.string().valid('allow-forms', 'allow-same-origin', 'allow-scripts', 'allow-top-navigation'); module.exports = Joi.object().keys({ defaultSrc: strOrArray, scriptSrc: strOrArray, styleSrc: strOrArray, imgSrc: strOrArray, connectSrc: strOrArray, fontSrc: strOrArray, objectSrc: strOrArray, mediaSrc: strOrArray, frameSrc: strOrArray, sandbox: [ sandboxString, Joi.array().includes(sandboxString), Joi.boolean() ], reportUri: Joi.string(), reportOnly: Joi.boolean(), oldSafari: Joi.boolean() }).with('reportOnly', 'reportUri');
// TODO 2.0 - remove notFound response = { context: context, values: valuesToReturn, isNotFound: isNotFound, notFound: isNotFound }; this._callback(null, response); return true; }; var schema = Joi.object().keys({ // namespace bucket: Joi.string().required(), // bucket type is required since default probably shouldn't have a // datatype associated with it bucketType: Joi.string().required(), key: Joi.binary().required(), returnRaw: Joi.boolean().default(false).optional(), // quorum r: Joi.number().default(null).optional(), pr: Joi.number().default(null).optional(), notFoundOk: Joi.boolean().default(null).optional(), useBasicQuorum: Joi.boolean().default(null).optional(), setsAsBuffers: Joi.boolean().default(false).optional(), timeout: Joi.number().default(null).optional() }); /** * A builder for constructing FetchSet instances. *
// schema for paths paths.schema = Joi.object({ tags: Joi.array().items(Joi.string()), summary: Joi.string(), description: Joi.string(), externalDocs: Joi.object({ description: Joi.string(), url: Joi.string().uri() }), operationId: Joi.string(), consumes: Joi.array().items(Joi.string()), produces: Joi.array().items(Joi.string()), parameters: Joi.array().items(Joi.object()), responses: Joi.object().required(), schemes: Joi.array().items(Joi.string().valid(['http', 'https', 'ws', 'wss'])), deprecated: Joi.boolean(), security: Joi.array().items(Joi.object()) }); /** * build the swagger path section * * @param {Object} setting * @param {Object} routes * @return {Object} */ paths.build = function (settings, routes) { Responses.build({}, {}, {}, {});
cache: joi.object().keys({ privacy: joi.string(), expiresIn: joi.any(), expiresAt: joi.any(), statuses: joi.array() }), config: joi.object().keys({ description: joi.string(), notes: joi.string(), tags: joi.string(), handler: joi.alternatives().try( joi.func(), joi.string() ), cors: joi.alternatives().try( joi.boolean(), //Hapi definition joi.object().keys({ origin: joi.array(), maxAge: joi.number(), headers: joi.array(), additionalHeaders: joi.array(), exposedHeaders: joi.array(), additionalExposedHeaders: joi.array(), credentials: joi.boolean() }), //Express definition joi.object().keys({ origin: joi.any(), methods: [joi.string(), joi.array()], allowedHeaders: [joi.string(), joi.array()],
* @apiSuccess {timestamp} data.created_at Timestamp of when the report note was created * @apiSuccess {timestamp} data.updated_at Timestamp of when the report note was last updated * * @apiError (Error 500) InternalServerError There was an error retrieving the user report notes */ module.exports = { method: 'GET', path: '/api/reports/usernotes/{report_id}', config: { auth: { strategy: 'jwt' }, validate: { params: { report_id: Joi.string().required() }, query: { page: Joi.number().integer().min(1).default(1), limit: Joi.number().integer().min(1).max(100).default(10), desc: Joi.boolean().default(true) } }, pre: [ { method: 'auth.reports.users.notes.page(server, auth)' } ] }, handler: function(request, reply) { var reportId = request.params.report_id; var opts = { limit: request.query.limit, page: request.query.page, desc: request.query.desc }; var reportNotes = request.db.reports.pageUserReportsNotes(reportId, opts); var reportNotesCount = request.db.reports.userReportsNotesCount(reportId);
} }); Weiner._collection = 'weiners'; Weiner.schema = Joi.object().keys({ _id: Joi.object(), weinerFrom: Joi.object().keys({ userId: Joi.number().required(), username: Joi.string().required() }).required(), weinerTo: Joi.array().items(Joi.object().keys({ userId: Joi.number().required(), username: Joi.string().required(), avatar: Joi.string().required(), userChecked: Joi.boolean().required() })).required(), content: Joi.string(), created: Joi.date(), status: Joi.number() }); Weiner.indexes = [ { key: { 'weinerFrom.userId': 1, unique: true } }, { key: { 'weinerTo.userId': 1, unique: true } } ]; // Create and save weiner to database. Weiner.create = function(weiner, callback) { const self = this;
var joi = require('joi'); var schema = { name: joi.string().min(3), description: joi.string(), dockerRepository: joi.string(), publicFacing: joi.boolean(), ports: joi.array().includes( joi.object().keys({ container: joi.number().integer().required(), host: joi.number().integer() })), env: joi.object(), volume: joi.object(), numInstances: joi.number().integer().min(1) }; module.exports = { write: { name: schema.name.required(), description: schema.description, dockerRepository: schema.dockerRepository.required(), publicFacing: schema.publicFacing, ports: schema.ports, env: schema.env, volume: schema.volume, numInstances: schema.numInstances }, patch: { name: schema.name, description: schema.description,
const Path = require('path'); const Boom = require('boom'); const Hoek = require('hoek'); const Items = require('items'); const Joi = require('joi'); const File = require('./file'); // Declare internals const internals = {}; internals.schema = Joi.object({ path: Joi.alternatives(Joi.array().items(Joi.string()).single(), Joi.func()).required(), index: Joi.alternatives(Joi.boolean(), Joi.array().items(Joi.string()).single()).default(true), listing: Joi.boolean(), showHidden: Joi.boolean(), redirectToSlash: Joi.boolean(), lookupCompressed: Joi.boolean(), etagMethod: Joi.string().valid('hash', 'simple').allow(false), defaultExtension: Joi.string().alphanum() }); exports.handler = function (route, options) { const settings = Joi.attempt(options, internals.schema, 'Invalid directory handler options (' + route.path + ')'); Hoek.assert(route.path[route.path.length - 1] === '}', 'The route path for a directory handler must end with a parameter:', route.path); const normalize = (paths) => {
var utils = require('../../../../utils.js'); var is = require('joi'); module.exports = is.object({ name: 'Airlines', type: 'object', file: is.string(), root: is.string(), is_dependency: is.boolean(), dependants: is.array(), key: '_id', seed: 0, data: { min: 0, max: 0, count: 1, dependencies: is.array().items(is.string()).length(1), inputs: is.array().items(is.string()).length(1), pre_run: is.func(), post_build: is.func(), }, properties: { _id: utils.check('string', 'The document id', { post_build: is.func(), }), doc_type: utils.check('string', 'The document type', { value: is.string(), }), airline_id: utils.check('integer', 'The airlines id', { pre_build: is.func(), }), airline_name: utils.check('string', 'The name of the airline', { build: is.func(), }), airline_iata: utils.check('string', 'The airlines iata code if availabe, otherwise null', { build: is.func(), }), airline_icao: utils.check('string', 'The airlines icao code if available, otherwise null', { build: is.func(), }), callsign: utils.check('string', 'The airlines callsign if available', { build: is.func(), }), iso_country: utils.check('string', 'The ISO country code the airline is based in', { build: is.func(), }), active: utils.check('boolean', 'Whether or not the airline is active', { pre_build: is.func(), post_build: is.func(), }),
import chalk from 'chalk' import moduleSchema from './properties/module' import entrySchema from './properties/entry' import contextSchema from './properties/context' import devtoolSchema from './properties/devtool' import externalsSchema from './properties/externals' import nodeSchema from './properties/node' import pluginsSchema from './properties/plugins' import resolveSchema from './properties/resolve' import outputSchema from './properties/output' import watchOptionsSchema from './properties/watchOptions' import { absolutePath } from './types' const schema = Joi.object({ amd: Joi.object(), bail: Joi.boolean(), cache: Joi.boolean(), context: contextSchema, debug: Joi.boolean(), devServer: Joi.object(), devtool: devtoolSchema, entry: entrySchema, externals: externalsSchema, loader: Joi.any(), // ? module: moduleSchema, node: nodeSchema, output: outputSchema, plugins: pluginsSchema, profile: Joi.boolean(), recordsInputPath: absolutePath, recordsOutputPath: absolutePath,
method: 'GET', path: '/centroid/v1/{table}', config: { description: 'feature centroid', notes: 'Get the centroid of a feature(s).', tags: ['api'], validate: { params: { table: Joi.string() .required() .description('name of the table') }, query: { geom_column: Joi.string().default('geom') .description('The geometry column of the table. The default is <em>geom</em>.'), srid: Joi.number().integer().default(4326) .description('The SRID for the returned centroid. The default is <em>4326</em> Lat/Lng.'), filter: Joi.string() .description('Filtering parameters for a SQL WHERE statement.'), force_on_surface: Joi.boolean().default(false) .description('Set true to force point on surface. The default is the <em>false</em>.') } }, jsonp: 'callback', cache: config.cache, handler: function(request, reply) { config.fetch.postgis(config.db.postgis, formatSQL(request), reply); } } }];
'use strict'; var Joi = require('joi'); var ConfigSchema = Joi.object().keys({ agi: Joi.object().keys({ port: Joi.number().integer().min(1).max(65535).required() }).required(), web: Joi.object().keys({ port: Joi.number().integer().min(1).max(65535).required(), auth: Joi.boolean().valid(true, false).default(false), username: Joi.string() .when('auth', {is: true, then: Joi.required().default('admin')}), password: Joi.string() .when('auth', {is: true, then: Joi.required().default('password')}), realm: Joi.string() .when('auth', {is: true, then: Joi.default('voicer web')}), }).required(), processing: Joi.object().keys({ totalAttempts: Joi.number().min(1).max(20).default(2), playGreeting: Joi.boolean().default(true), playBeepBeforeRecording: Joi.boolean().default(true) }).required(), asterisk: Joi.object().keys({ sounds: Joi.object().keys({ onErrorBeforeFinish: Joi.string(), onErrorBeforeRepeat: Joi.string(), greeting: Joi.string() }).required(), recognitionDialplanVars: Joi.object().keys({ status: Joi.string().required(),
'use strict' const path = require('path') const joi = require('joi') const { parse } = require('pg-connection-string') const envVarsSchema = joi.object({ PG_URI: joi.string().uri({ scheme: 'postgres' }).required(), PG_SSL_CA: joi.string(), PG_SSL_KEY: joi.string(), PG_SSL_CERT: joi.string(), PG_SSL_ALLOW_UNAUTHORIZED: joi.boolean().truthy('true').falsy('false').default(true), PG_POOL_MIN: joi.number().integer().default(1), PG_POOL_MAX: joi.number().integer().default(20), PG_HEALTH_CHECK_TIMEOUT: joi.number().integer().default(2000) }).unknown() .required() const envVars = joi.attempt(process.env, envVarsSchema) const config = { client: 'pg', connection: Object.assign( parse(envVars.PG_URI), envVars.PG_SSL_CA || envVars.PG_SSL_KEY || envVars.PG_SSL_CERT ? { ssl: { ca: envVars.PG_SSL_CA, key: envVars.PG_SSL_KEY, cert: envVars.PG_SSL_CERT, rejectUnauthorized: !envVars.PG_SSL_ALLOW_UNAUTHORIZED
if (profile) { return checksum(JSON.stringify(profile)); } return false; } module.exports = { auth: { strategy: 'oauth' }, response: { schema: { email: Joi.string().allow(null), uid: Joi.string().allow(null), avatar: Joi.string().allow(null), avatarDefault: Joi.boolean().allow(null), displayName: Joi.string().allow(null), locale: Joi.string().allow(null), amrValues: Joi.array().items(Joi.string().required()).allow(null), twoFactorAuthentication: Joi.boolean().allow(null), subscriptions: Joi.array().items(Joi.string().required()).optional(), //openid-connect sub: Joi.string().allow(null) } }, handler: function profile(req, reply) { const server = req.server; const creds = req.auth.credentials; function createResponse (err, result, cached, report) {
internals.url = Joi.alternatives(Joi.string().required(), Joi.object().keys({ protocol: Joi.string(), hostname: Joi.string(), port: Joi.any(), pathname: Joi.string().required(), query: Joi.any() }).required()); internals.options = Joi.object().keys({ url: internals.url.required(), headers: Joi.object(), payload: Joi.any(), simulate: Joi.object().keys({ end: Joi.boolean(), split: Joi.boolean(), error: Joi.boolean(), close: Joi.boolean() }), authority: Joi.string(), remoteAddress: Joi.string(), method: Joi.string().regex(/^[a-zA-Z0-9!#\$%&'\*\+\-\.^_`\|~]+$/) }).min(1); module.exports = Joi.object().keys({ dispatchFunc: Joi.func().required(), options: Joi.alternatives(internals.options, internals.url).required(), callback: Joi.func() });