const getThemeData = function(theme, callback){ let out = Hoek.clone(theme) // delete those items which would not be pass into template context delete out.templatePath; delete out.partialsPath; delete out.halpersPath; delete out.groupPages; delete out.groupItemPages; delete out.assetPath; callback(null, out); }
default(options) { Hoek.assert(!this.settings.default, 'Cannot set default strategy more than once'); options = Config.apply('auth', options, 'default strategy'); this.settings.default = this._setupRoute(Hoek.clone(options)); // Prevent changes to options const routes = this._core.router.table(); for (const route of routes) { route.rebuild(); } }
function toFieldExistenceChain(r, field) { var fields = field.split(SEP); field = fields.pop(); var ret, key; while (fields.length) { ret = ret || {}; if (key) delete ret[key]; ret[key = fields.pop()] = field; field = hoek.clone(ret); } return ret || field; }
plugin.expose('getJSON', function (exposeOptions, request, callback) { // use either options passed to function or plug-in scope options let exposeSettings = {}; if (exposeOptions && Utilities.hasProperties(exposeOptions)) { exposeSettings = Hoek.applyToDefaults(defaults, exposeOptions); Joi.assert(exposeSettings, schema); } else { exposeSettings = Hoek.clone(settings); } Builder.getSwaggerJSON(exposeSettings, request, callback); });
exports.authenticate = function(res, artifacts, options) { artifacts = Hoek.clone(artifacts); options = options || {}; if (res.headers['www-authenticate']) { // Parse HTTP WWW-Authenticate header var attributes = Utils.parseAuthorizationHeader(res.headers['www-authenticate'], ['ts', 'tsm', 'error']); if (attributes instanceof Error) { return false; } if (attributes.ts) { var tsm = Crypto.calculateTsMac(attributes.ts, artifacts.credentials); if (!Cryptiles.fixedTimeComparison(tsm, attributes.tsm)) { return false; } } } // Parse HTTP Server-Authorization header if (!res.headers['server-authorization'] && !options.required) { return true; } var attributes = Utils.parseAuthorizationHeader(res.headers['server-authorization'], ['mac', 'ext', 'hash']); if (attributes instanceof Error) { return false; } artifacts.ext = attributes.ext; artifacts.hash = attributes.hash; var mac = Crypto.calculateMac('response', artifacts); if (!Cryptiles.fixedTimeComparison(mac, attributes.mac)) { return false; } if (!options.hasOwnProperty('payload')) { return true; } if (!attributes.hash) { return false; } var calculatedHash = Crypto.calculateHash(options.payload, artifacts.credentials.algorithm, res.headers['content-type']); return Cryptiles.fixedTimeComparison(calculatedHash, attributes.hash); };
Iron.seal(obj, password, options, function (err, sealed) { expect(err).to.not.exist(); var options2 = Hoek.clone(Iron.defaults); options2.localtimeOffsetMsec = -100000; Iron.unseal(sealed, { 'default': password }, options2, function (err, unsealed) { expect(err).to.not.exist(); expect(unsealed).to.deep.equal(obj); done(); }); });
options.loadAppFunc(grant.app, function (err, app) { if (err || !app) { return callback(err || Boom.forbidden('Invalid application')); } var ticketOptions = Hoek.clone(options.ticket) || {}; if (ext) { ticketOptions.ext = ext; } Ticket.issue(app, grant, options.encryptionPassword, ticketOptions, callback); });
internals.implementation = function (server, options) { var settings = Hoek.clone(options); var scheme = { authenticate: function (request, reply) { var req = request.raw.req; var authorization = req.headers.authorization; if (!authorization) { return reply(Boom.unauthorized(null, 'Custom')); } var parts = authorization.split(/\s+/); if (parts.length !== 2) { return reply(); } var username = parts[1]; var credentials = settings.users[username]; if (!credentials) { return reply(Boom.unauthorized('Missing credentials', 'Custom'), { log: { tags: ['auth', 'custom'], data: 'oops' } }); } if (credentials === 'skip') { return reply(Boom.unauthorized(null, 'Custom')); } if (credentials === 'throw') { throw new Error('Boom'); } if (typeof credentials === 'string') { return reply(credentials); } return reply(null, { credentials: credentials }); }, payload: function (request, next) { return next(request.auth.credentials.payload); }, response: function (request, next) { return next(); } }; return scheme; };
exports.register = function (plugin, options, next) { var settings = Hoek.clone(internals.defaults); Hoek.merge(settings, options); var cssBaseUrl = (settings.endpoint === '/' ? '' : settings.endpoint) + '/css'; plugin.views({ engines: settings.engines || { html: { module: Handlebars } }, path: settings.basePath, partialsPath: settings.partialsPath, helpersPath: settings.helpersPath, runtimeOptions: { data: { cssBaseUrl: cssBaseUrl } } }); plugin.route({ method: 'GET', path: settings.endpoint, config: internals.docs(settings, plugin) }); if (settings.cssPath) { plugin.route({ method: 'GET', path: cssBaseUrl + '/{path*}', config: { handler: { directory: { path: settings.cssPath, index: false, listing: false } }, plugins: { lout: false }, auth: settings.auth } }); } next(); };
internals.special = function (type, value, options) { options = options || {}; const special = function () { }; // Return function because 1. typeof fastest 2. illegal database type special.type = type; special.flags = Hoek.clone(options); if (value !== undefined) { special.value = value; } return special; };
exports.apply = function (options) { Hoek.assert(options, 'Missing options'); // engine: 'memory', { engine: 'memory' }, { engine: implementation } var settings = {}; if (typeof options === 'string') { settings.engine = options; } else { var isExtension = options.engine === 'extension'; if (isExtension || options.engine && typeof options.engine === 'object') { settings.engine = 'extension'; settings.extension = isExtension ? options.extension : options.engine; settings.partition = options.partition || 'catbox'; return settings; } settings = Hoek.clone(options); } settings.partition = settings.partition || 'catbox'; Hoek.assert(['redis', 'mongodb', 'memory', 'memcache'].indexOf(settings.engine) !== -1, 'Unknown cache engine type: ' + settings.engine); if (settings.engine === 'redis') { settings.host = settings.host || '127.0.0.1'; settings.port = settings.port || 6379; } else if (settings.engine === 'mongodb') { settings.host = settings.host || '127.0.0.1'; settings.port = settings.port || 27017; settings.poolSize = settings.poolSize || 5; } else if (settings.engine === 'memory') { settings.maxByteSize = settings.maxByteSize || 100 * 1024 * 1024; // Defaults to 100MB } else if (settings.engine === 'memcache') { Hoek.assert(!options.location || (!options.host && !options.port), 'Cannot specify both location and host/port when using memcache'); settings.location = settings.location || ((options.host || '127.0.0.1') + ':' + (options.port || 11211)); delete options.port; delete options.host; } return settings; };
exports.handler = function (route, options) { Schema.assert('file handler', options, route.path); var settings = (typeof options !== 'object' ? { path: options } : Hoek.clone(options)); // options can be reused Hoek.assert(typeof settings.path !== 'string' || settings.path[settings.path.length - 1] !== '/', 'File path cannot end with a \'/\':', route.path); var handler = function (request, reply) { var path = (typeof settings.path === 'function' ? settings.path(request) : settings.path); return reply.file(path, settings); }; return handler; };
it('can send an email from defaultFrom', function (done) { var options = Hoek.clone(baseOptions); options.email.defaultFrom = testEmail; var email = Hoek.clone(baseEmail); delete email.from; email.subject += ' from defaultFrom'; var server = new Hapi.Server(); server.register({register: require('../'), options: options}, function (err) { expect(err).to.not.exist; }); server.plugins['hapi-mail'].sendMail(email, function(err, response) { expect(email.from).to.equal(options.email.defaultFrom); expect(err).to.not.exist; expect(response.MessageId).to.not.equal(''); done(); }); });
exports.type = function (type, value, options) { options = options || {}; const modifier = function () { }; // Return function because 1. typeof fastest 2. illegal database type modifier.type = type; modifier.flags = Hoek.clone(options); if (value !== undefined) { modifier.value = value; } return modifier; };
lab.beforeEach(done => { themeConfig = ThemeConfig.getInstance(); config = themeConfig.getConfig(); originalSettings = Hoek.clone(config.settings); newSettings = { color: '#000000', font: 'Sans Something', select: 'second', checkbox: true, radio: 'first', }; done(); });
it('creates a user tries to close a window', () => { const webOptions = hoek.clone(options); webOptions.url = '/auth/login/guest/web'; return server.inject(webOptions).then((reply) => { assert.equal(reply.statusCode, 200, 'Login/web route should be available'); assert.equal( reply.result, '<script>window.close();</script>', 'add script to close window' ); }); });
it('returns an error when Cryptiles.randomBits fails', function (done) { var options = Hoek.clone(Iron.defaults.encryption); options.salt = 'abcdefg'; options.algorithm = 'x'; Iron.algorithms.x = { keyBits: 256, ivBits: -1 }; Iron.generateKey('password', options, function (err, result) { expect(err).to.exist(); expect(err.message).to.equal('Invalid random bits count'); done(); }); });
module.exports = internals.GoodFluent = function GoodFluent(label, options) { var settings; Hoek.assert(this instanceof internals.GoodFluent, 'GoodFluent must be created with new'); Hoek.assert(typeof label === 'string', 'label must be a string'); options = Hoek.clone(options || {}); settings = Hoek.applyToDefaults(internals.defaults, options); this._sender = Fluent.createFluentSender(label, settings); this._sender.on('error', Function.prototype); GoodReporter.call(this, settings); };
internals.Request.prototype._setState = function (name, value, options) { // options: see Defaults.state const state = { name: name, value: value }; if (options) { Hoek.assert(!options.autoValue, 'Cannot set autoValue directly in a response'); state.options = Hoek.clone(options); } this._states[name] = state; };
it('errors on missing Auth plugin', (done) => { const manifest = Hoek.clone(internals.manifest); manifest.registrations.splice(2,1); University.init(manifest, internals.composeOptions, (err, server) => { expect(err).to.exist(); expect(err.message).to.equal('Plugin ' + ApiUser.register.attributes.name + ' missing dependency ' + Auth.register.attributes.name + ' in connection: ' + server.select('web-tls').info.uri); done(); }); });
it('errors on missing Auth plugin', function (done) { var manifest = Hoek.clone(internals.manifest); delete manifest.plugins['./auth']; var failingInit = University.init.bind(University, manifest, internals.composeOptions, function (err) { done(); }); expect(failingInit).to.throw(); done(); });
exports.header = function (credentials, artifacts, options) { // Prepare inputs options = options || {}; if (!artifacts || typeof artifacts !== 'object' || typeof options !== 'object') { return ''; } artifacts = Hoek.clone(artifacts); delete artifacts.mac; artifacts.hash = options.hash; artifacts.ext = options.ext; // Validate credentials if (!credentials || !credentials.key || !credentials.algorithm) { // Invalid credential object return ''; } if (Crypto.algorithms.indexOf(credentials.algorithm) === -1) { return ''; } // Calculate payload hash if (!artifacts.hash && (options.payload || options.payload === '')) { artifacts.hash = Crypto.calculatePayloadHash(options.payload, credentials.algorithm, options.contentType); } var mac = Crypto.calculateMac('response', credentials, artifacts); // Construct header var header = 'Hawk mac="' + mac + '"' + (artifacts.hash ? ', hash="' + artifacts.hash + '"' : ''); if (artifacts.ext !== null && artifacts.ext !== undefined && artifacts.ext !== '') { // Other falsey values allowed header += ', ext="' + Hoek.escapeHeaderAttribute(artifacts.ext) + '"'; } return header; };
it('can allow cc and bcc to not be specicied in the email object', function (done) { var options = Hoek.clone(baseOptions); var email = Hoek.clone(baseEmail); delete email.cc; delete email.bcc; email.subject += ' with no cc or bcc'; var server = new Hapi.Server(); server.register({register: require('../'), options: options}, function (err) { expect(err).to.not.exist; }); server.plugins['hapi-mail'].sendMail(email, function(err, response) { expect(email.cc.length).to.equal(0); expect(email.bcc.length).to.equal(0); expect(err).to.not.exist; expect(response.MessageId).to.not.equal(''); done(); }); });
constructor(name, options) { this._settings = Hoek.clone(Joi.attempt(options || {}, internals.schema.db, 'Invalid database options')); this.name = name; this._connection = null; this._connectionOptions = null; this._feeds = {}; // uuid -> { table, criteria, options } if (this._settings.test) { this.disable = internals.disable; this.enable = internals.enable; } this.tables = {}; }
internals.parsePlugin = function (plugin, relativeTo) { plugin = Hoek.clone(plugin); if (typeof plugin === 'string') { plugin = { register: plugin }; } let path = plugin.register; if (relativeTo && path[0] === '.') { path = Path.join(relativeTo, path); } plugin.register = require(path); return plugin; };
it('can assign from to replyTo and returnPath', function (done) { var options = Hoek.clone(baseOptions); var email = Hoek.clone(baseEmail); delete email.replyTo; delete email.returnPath; email.subject += ' with no replyTo or returnPath'; var server = new Hapi.Server(); server.register({register: require('../'), options: options}, function (err) { expect(err).to.not.exist; }); server.plugins['hapi-mail'].sendMail(email, function(err, response) { expect(email.replyTo[0]).to.equal(email.from); expect(email.returnPath).to.equal(email.from); expect(err).to.not.exist; expect(response.MessageId).to.not.equal(''); done(); }); });
reporter.start(ee, function (err) { expect(err).to.not.exist(); for (var i = 1; i < 6; ++i) { var event = Hoek.clone(internals.response); event.statusCode = i * 100; event.timestamp = now; delete event.query; delete event.responsePayload; ee.emit('report', 'response', event); } });
internals.Listener.subscription = function (path, options) { Hoek.assert(path, 'Subscription missing path'); Joi.assert(options, internals.subSchema, 'Invalid subscription options: ' + path); const settings = Hoek.clone(options || {}); // Auth configuration const auth = settings.auth; if (auth) { if (auth.scope) { if (typeof auth.scope === 'string') { auth.scope = [auth.scope]; } for (let i = 0; i < auth.scope.length; ++i) { if (/{([^}]+)}/.test(auth.scope[i])) { auth.hasScopeParameters = true; break; } } } auth.mode = auth.mode || 'required'; } // Path configuration const route = { method: 'sub', path: path }; const config = { subscribers: new internals.Subscribers(settings), filter: settings.filter, auth: auth }; const connections = this.connections; for (let i = 0; i < connections.length; ++i) { const connection = connections[i]; if (connection.plugins.nes) { connection.plugins.nes._listener._router.add(route, config); } } };
_passThrough() { if (this.variety === 'stream' && this.settings.passThrough) { if (this.source.statusCode && !this.statusCode) { this.statusCode = this.source.statusCode; // Stream is an HTTP response } if (this.source.headers) { let headerKeys = Object.keys(this.source.headers); if (headerKeys.length) { const localHeaders = this.headers; this.headers = {}; const connection = this.source.headers.connection; const byHop = {}; if (connection) { connection.split(/\s*,\s*/).forEach((header) => { byHop[header] = true; }); } for (let i = 0; i < headerKeys.length; ++i) { const key = headerKeys[i]; const lower = key.toLowerCase(); if (!internals.hopByHop[lower] && !byHop[lower]) { this.header(lower, Hoek.clone(this.source.headers[key])); // Clone arrays } } headerKeys = Object.keys(localHeaders); for (let i = 0; i < headerKeys.length; ++i) { const key = headerKeys[i]; this.header(key, localHeaders[key], { append: key === 'set-cookie' }); } } } } this.statusCode = this.statusCode || 200; }
Ctrl.facebookAuthorisationHandler = function (request, reply) { var getOptions, appSecretProof, query = {}, url = 'https://graph.facebook.com/me', auth = Hoek.clone(request.auth); if (auth.isAuthenticated !== true) { // todo: write test for failed authentication, eg.: change } // todo: check by email if user is registerd and authorise BG API if yes // todo: if user is not registered obtain token_for_business appSecretProof = Crypto .createHmac('sha256', Config.facebook.clientSecret) .update(request.auth.credentials.token) .digest('hex'); query = { appsecret_proof: appSecretProof, fields: 'token_for_business' }; getOptions = { headers: { Authorization: 'Bearer ' + request.auth.credentials.token }, json: true }; url += '?' + QueryString.encode(query); Wreck.get(url, getOptions, function (err, res, payload) { if (err || res.statusCode !== 200) { return reply(Boom.internal('Failed obtaining ' + name + ' user profile', err || payload)); } // todo: findout why payload is string and not JSON (it has been requested in getOptions) auth.credentials.token_for_business = JSON.parse(payload).token_for_business; reply('<pre>' + JSON.stringify(auth, null, 4) + '</pre>'); }); };