Ejemplo n.º 1
0
exports = module.exports = internals.paths = function(settings) {
  this.settings = settings;
  this.definitions = new Definitions(settings);
  this.properties = new Properties(settings, {}, {});
  this.responses = new Responses(settings, {}, {});

  this.defaults = {
    responses: {}
  };

  this.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())
  });
};
Ejemplo n.º 2
0
  lab.test('reuseDefinitions = false', async () => {
    // forces two models even though the model hash is the same

    const tempRoutes = [
      {
        method: 'POST',
        path: '/store1/',
        options: {
          handler: Helper.defaultHandler,
          tags: ['api'],
          validate: {
            payload: Joi.object({
              a: Joi.number(),
              b: Joi.number(),
              operator: Joi.string(),
              equals: Joi.number()
            }).label('A')
          }
        }
      },
      {
        method: 'POST',
        path: '/store2/',
        options: {
          handler: Helper.defaultHandler,
          tags: ['api'],
          validate: {
            payload: Joi.object({
              a: Joi.number(),
              b: Joi.number(),
              operator: Joi.string(),
              equals: Joi.number()
            }).label('B')
          }
        }
      }
    ];

    const server = await Helper.createServer({ reuseDefinitions: false }, tempRoutes);

    const response = await server.inject({ method: 'GET', url: '/swagger.json' });

    //console.log(JSON.stringify(response.result));
    expect(response.statusCode).to.equal(200);
    expect(response.result.definitions.A).to.exist();
    expect(response.result.definitions.B).to.exist();
    const isValid = await Validate.test(response.result);
    expect(isValid).to.be.true();
  });
Ejemplo n.º 3
0
  lab.test('test that name changing for required', async () => {
    const FormDependencyDefinition = Joi.object({
      id: Joi.number().required()
    }).label('FormDependencyDefinition');

    const ActionDefinition = Joi.object({
      id: Joi.number()
        .required()
        .allow(null),
      reminder: FormDependencyDefinition.required()
    }).label('ActionDefinition');

    let testRoutes = [
      {
        method: 'POST',
        path: '/server/',
        options: {
          handler: Helper.defaultHandler,
          tags: ['api'],
          validate: {
            payload: ActionDefinition
          }
        }
      }
    ];

    const server = await Helper.createServer({}, testRoutes);

    const response = await server.inject({ method: 'GET', url: '/swagger.json' });

    expect(response.statusCode).to.equal(200);
    expect(response.result.definitions.ActionDefinition).to.equal({
      type: 'object',
      properties: {
        id: {
          type: 'number'
        },
        reminder: {
          $ref: '#/definitions/FormDependencyDefinition'
        }
      },
      required: ['id', 'reminder']
    });
  });
Ejemplo n.º 4
0
 ['queryParams', 'pathParams', 'headerParams', 'payloadParams'].forEach(function(property) {
   // swap out any custom validation function for Joi object/string
   if (Utilities.isFunction(routeData[property])) {
     if (property !== 'pathParams') {
       self.settings.log(
         ['validation', 'warning'],
         'Using a Joi.function for a query, header or payload is not supported.'
       );
       if (property === 'payloadParams') {
         routeData[property] = Joi.object().label('Hidden Model');
       } else {
         routeData[property] = Joi.object({ 'Hidden Model': Joi.string() });
       }
     } else {
       self.settings.log(
         ['validation', 'error'],
         'Using a Joi.function for a params is not supported and has been removed.'
       );
       routeData[property] = null;
     }
   }
 });
Ejemplo n.º 5
0
  lab.test('test that optional array is not in swagger output', async () => {
    let testRoutes = [
      {
        method: 'POST',
        path: '/server/1/',
        options: {
          handler: Helper.defaultHandler,
          tags: ['api'],
          validate: {
            payload: Joi.object({
              a: Joi.number().required(),
              b: Joi.string().optional()
            }).label('test')
          }
        }
      }
    ];

    const server = await Helper.createServer({}, testRoutes);

    const response = await server.inject({ method: 'GET', url: '/swagger.json' });

    expect(response.statusCode).to.equal(200);
    expect(response.result.definitions.test).to.equal({
      type: 'object',
      properties: {
        a: {
          type: 'number'
        },
        b: {
          type: 'string'
        }
      },
      required: ['a']
    });
  });
Ejemplo n.º 6
0
'use strict';

const Boom = require('@hapi/boom');
const Hoek = require('@hapi/hoek');
const Joi = require('@hapi/joi');


const internals = {};


internals.schema = Joi.object({
    sampleInterval: Joi.number().min(0),
    maxHeapUsedBytes: Joi.number().min(0),
    maxEventLoopDelay: Joi.number().min(0),
    maxRssBytes: Joi.number().min(0)
})
    .unknown();


internals.defaults = {
    sampleInterval: 0,                          // Frequency of load sampling in milliseconds (zero is no sampling)
    maxHeapUsedBytes: 0,                        // Reject requests when V8 heap is over size in bytes (zero is no max)
    maxRssBytes: 0,                             // Reject requests when process RSS is over size in bytes (zero is no max)
    maxEventLoopDelay: 0                        // Milliseconds of delay after which requests are rejected (zero is no max)
};


exports = module.exports = internals.Heavy = function (options) {

    options = options || {};
Ejemplo n.º 7
0
  routes.forEach(route => {
    let routeOptions = Hoek.reach(route, 'settings.plugins.hapi-swagger') || {};
    let routeData = {
      path: route.path,
      method: route.method.toUpperCase(),
      description: route.settings.description,
      notes: route.settings.notes,
      tags: Hoek.reach(route, 'settings.tags'),
      queryParams: Hoek.reach(route, 'settings.validate.query'),
      pathParams: Hoek.reach(route, 'settings.validate.params'),
      payloadParams: Hoek.reach(route, 'settings.validate.payload'),
      responseSchema: Hoek.reach(route, 'settings.response.schema'),
      responseStatus: Hoek.reach(route, 'settings.response.status'),
      headerParams: Hoek.reach(route, 'settings.validate.headers'),
      consumes: Hoek.reach(routeOptions, 'consumes') || null,
      produces: Hoek.reach(routeOptions, 'produces') || null,
      responses: Hoek.reach(routeOptions, 'responses') || null,
      payloadType: Hoek.reach(routeOptions, 'payloadType') || null,
      security: Hoek.reach(routeOptions, 'security') || null,
      order: Hoek.reach(routeOptions, 'order') || null,
      deprecated: Hoek.reach(routeOptions, 'deprecated') || null,
      id: Hoek.reach(routeOptions, 'id') || null,
      groups: route.group
    };

    Utilities.assignVendorExtensions(routeData, routeOptions);
    routeData.path = Utilities.replaceInPath(routeData.path, ['endpoints'], this.settings.pathReplacements);

    // user configured interface through route plugin options
    if (Hoek.reach(routeOptions, 'validate.query')) {
      routeData.queryParams = Utilities.toJoiObject(Hoek.reach(routeOptions, 'validate.query'));
    }
    if (Hoek.reach(routeOptions, 'validate.params')) {
      routeData.pathParams = Utilities.toJoiObject(Hoek.reach(routeOptions, 'validate.params'));
    }
    if (Hoek.reach(routeOptions, 'validate.headers')) {
      routeData.headerParams = Utilities.toJoiObject(Hoek.reach(routeOptions, 'validate.headers'));
    }
    if (Hoek.reach(routeOptions, 'validate.payload')) {
      // has different structure, just pass straight through
      routeData.payloadParams = Hoek.reach(routeOptions, 'validate.payload');
      // if its a native javascript object convert it to JOI
      if (!routeData.payloadParams.isJoi) {
        routeData.payloadParams = Joi.object(routeData.payloadParams);
      }
    }

    // swap out any custom validation function for Joi object/string
    ['queryParams', 'pathParams', 'headerParams', 'payloadParams'].forEach(function(property) {
      // swap out any custom validation function for Joi object/string
      if (Utilities.isFunction(routeData[property])) {
        if (property !== 'pathParams') {
          self.settings.log(
            ['validation', 'warning'],
            'Using a Joi.function for a query, header or payload is not supported.'
          );
          if (property === 'payloadParams') {
            routeData[property] = Joi.object().label('Hidden Model');
          } else {
            routeData[property] = Joi.object({ 'Hidden Model': Joi.string() });
          }
        } else {
          self.settings.log(
            ['validation', 'error'],
            'Using a Joi.function for a params is not supported and has been removed.'
          );
          routeData[property] = null;
        }
      }
    });

    // hapi wildcard method support
    if (routeData.method === '*') {
      // OPTIONS not supported by Swagger and HEAD not support by HAPI
      ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'].forEach(method => {
        var newRoute = Hoek.clone(routeData);
        newRoute.method = method.toUpperCase();
        routesData.push(newRoute);
      });
    } else {
      routesData.push(routeData);
    }
  });
Ejemplo n.º 8
0
const js2xmlparser = require('js2xmlparser');

const sumModel = Joi.object({
  id: Joi.string()
    .required()
    .example('x78P9c'),
  a: Joi.number()
    .required()
    .example(5),
  b: Joi.number()
    .required()
    .example(5),
  operator: Joi.string()
    .required()
    .description('either +, -, /, or *')
    .example('+'),
  equals: Joi.number()
    .required()
    .example(10),
  created: Joi.string()
    .required()
    .isoDate()
    .description('ISO date string')
    .example('2015-12-01'),
  modified: Joi.string()
    .isoDate()
    .description('ISO date string')
    .example('2015-12-01')
})
  .label('Sum')
  .description('json body for sum');
Ejemplo n.º 9
0
'use strict';

const Stream = require('stream');

const Boom = require('@hapi/boom');
const Cryptiles = require('@hapi/cryptiles');
const Hoek = require('@hapi/hoek');
const Joi = require('@hapi/joi');


const internals = {
    restfulValidatedMethods: ['post', 'put', 'patch', 'delete']
};


internals.schema = Joi.object().keys({
    key: Joi.string().optional(),
    size: Joi.number().optional(),
    autoGenerate: Joi.boolean().optional(),
    addToViewContext: Joi.boolean().optional(),
    cookieOptions: Joi.object().keys(null),
    headerName: Joi.string().optional(),
    restful: Joi.boolean().optional(),
    skip: Joi.func().optional(),
    enforce: Joi.boolean().optional(),
    logUnauthorized: Joi.boolean().optional()
});


internals.defaults = {
    key: 'crumb',
Ejemplo n.º 10
0
Archivo: index.js Proyecto: hapijs/bell
internals.schema = Joi.object({
    provider: Joi.object({
        name: Joi.string().optional().default('custom'),
        protocol: Joi.string().valid('oauth', 'oauth2'),
        temporary: Joi.string().when('protocol', { is: 'oauth', then: Joi.required(), otherwise: Joi.forbidden() }),
        signatureMethod: Joi.string().valid('HMAC-SHA1', 'RSA-SHA1').when('protocol', { is: 'oauth', then: Joi.default('HMAC-SHA1'), otherwise: Joi.forbidden() }),
        auth: Joi.string().required(),
        useParamsAuth: internals.flexBoolean.default(false).when('protocol', { is: 'oauth2', then: Joi.optional(), otherwise: Joi.forbidden() }),
        token: Joi.string().required(),
        headers: Joi.object(),
        profile: Joi.func(),
        profileMethod: Joi.string().valid('get', 'post').default('get'),
        scope: Joi.alternatives().try(
            Joi.array().items(Joi.string()),
            Joi.func()
        ).when('protocol', { is: 'oauth2', otherwise: Joi.forbidden() }),
        scopeSeparator: Joi.string().when('protocol', { is: 'oauth2', otherwise: Joi.forbidden() })
    }).required(),
    password: Joi.string().required(),
    clientId: Joi.string().required(),
    clientSecret: Joi.alternatives().when('protocol', {
        is: 'oauth',
        then: Joi.string().required().allow(''),
        otherwise: Joi.alternatives().try(Joi.string().allow(''), Joi.object())
    }).required(),
    cookie: Joi.string(),
    isSameSite: Joi.valid('Strict', 'Lax').allow(false).default('Strict'),
    isSecure: internals.flexBoolean,
    isHttpOnly: internals.flexBoolean,
    ttl: Joi.number(),
    domain: Joi.string().allow(null),
    providerParams: Joi.alternatives().try(Joi.object(), Joi.func()),
    allowRuntimeProviderParams: internals.flexBoolean.default(false),
    scope: Joi.alternatives().try(
        Joi.array().items(Joi.string()),
        Joi.func()
    ).when('provider.protocol', { is: 'oauth2', otherwise: Joi.forbidden() }),
    name: Joi.string().required(),
    config: Joi.object(),
    profileParams: Joi.object(),
    skipProfile: internals.flexBoolean.optional().default(false),
    forceHttps: internals.flexBoolean.optional().default(false),
    location: Joi.alternatives().try(
        Joi.func().maxArity(1),
        Joi.string()
    ).default(false),
    runtimeStateCallback: Joi.func().optional()
});
Ejemplo n.º 11
0
module.exports = Joi.object({
    baseUri: Joi.array().items(Joi.string()).single().default(['self']),
    childSrc: Joi.array().items(Joi.string()).single(),
    connectSrc: Joi.array().items(Joi.string()).single().default(['self']),
    defaultSrc: Joi.array().items(Joi.string()).single().default(['none']),
    fontSrc: Joi.array().items(Joi.string()).single(),
    formAction: Joi.array().items(Joi.string()).single(),
    frameAncestors: Joi.array().items(Joi.string()).single(),
    frameSrc: Joi.array().items(Joi.string()).single(),
    imgSrc: Joi.array().items(Joi.string()).single().default(['self']),
    manifestSrc: Joi.array().items(Joi.string()).single(),
    mediaSrc: Joi.array().items(Joi.string()).single(),
    objectSrc: Joi.array().items(Joi.string()).single(),
    oldSafari: Joi.boolean(),
    pluginTypes: Joi.array().items(Joi.string()).single(),
    reflectedXss: Joi.string().valid('allow', 'block', 'filter'),
    reportOnly: Joi.boolean(),
    reportUri: Joi.string(),
    requireSriFor: Joi.array().items(Joi.string()).single(),
    sandbox: [
        Joi.array().items(Joi.string().valid('allow-forms', 'allow-same-origin', 'allow-scripts', 'allow-top-navigation')).single(),
        Joi.boolean()
    ],
    scriptSrc: Joi.array().items(Joi.string()).single().default(['self'])
        .when('generateNonces', { is: [false, 'style'], then: Joi.array().items(Joi.string().valid('strict-dynamic').forbidden()) }),
    styleSrc: Joi.array().items(Joi.string()).single().default(['self'])
        .when('generateNonces', { is: [false, 'script'], then: Joi.array().items(Joi.string().valid('strict-dynamic').forbidden()) }),
    workerSrc: Joi.array().items(Joi.string()).single().default(['self']),
    generateNonces: Joi.alternatives().try([Joi.boolean(), Joi.string().valid('script', 'style')]).default(true)
}).with('reportOnly', 'reportUri');
Ejemplo n.º 12
0
'use strict';

const Joi = require('@hapi/joi');


const internals = {
    schema: Joi.object({
        uri: Joi.string().uri().required()
    }).required()
};


exports = module.exports = function (options) {

    const settings = Joi.attempt(options, internals.schema);

    return {
        protocol: 'oauth2',
        useParamsAuth: true,
        auth: settings.uri + '/oauthserver/auth/',
        token: settings.uri + '/oauthserver/token/',
        scope: ['whoami'],
        scopeSeparator: ',',
        profile: async function (credentials, params, get) {

            const query = {
                access_token: credentials.token
            };

            const profile = await get(settings.uri + '/api/user.whoami', query);
Ejemplo n.º 13
0
const baseSchema = require('./base-schema');
const defaults = require('./defaults');
const regExpObject = require('./reg-exp-object');

// Add some constraints that apply to both generateSW and generateSWString.
module.exports = baseSchema.keys({
  cacheId: joi.string(),
  cleanupOutdatedCaches: joi.boolean().default(defaults.cleanupOutdatedCaches),
  clientsClaim: joi.boolean().default(defaults.clientsClaim),
  directoryIndex: joi.string(),
  ignoreURLParametersMatching: joi.array().items(regExpObject),
  navigateFallback: joi.string().default(defaults.navigateFallback),
  navigateFallbackBlacklist: joi.array().items(regExpObject),
  navigateFallbackWhitelist: joi.array().items(regExpObject),
  navigationPreload: joi.boolean().default(defaults.navigationPreload),
  offlineGoogleAnalytics: joi.alternatives().try(joi.boolean(), joi.object())
      .default(defaults.offlineGoogleAnalytics),
  runtimeCaching: joi.array().items(joi.object().keys({
    method: joi.string().valid(
        'DELETE',
        'GET',
        'HEAD',
        'PATCH',
        'POST',
        'PUT'
    ),
    urlPattern: [regExpObject, joi.string(), joi.func()],
    handler: [
      joi.func(),
      joi.string().valid(
          'CacheFirst',
Ejemplo n.º 14
0
'use strict';

const Joi = require('@hapi/joi');


const internals = {
    schema: Joi.object({
        express: Joi.boolean().optional()
    }).optional()
};


exports = module.exports = (options = {}) => {

    const settings = Joi.attempt(options, internals.schema);
    const domain = 'connect.stripe.com';
    const authPrefix = settings.express ? '/express' : '';

    return {
        protocol: 'oauth2',
        useParamsAuth: true,
        auth: `https://${domain}${authPrefix}/oauth/authorize`,
        token: `https://${domain}/oauth/token`,
        scope: [],
        headers: { 'User-Agent': 'hapi-bell-stripe' },
        profile: async function (credentials, params, get) {

            const user = `https://${credentials.token}@${domain}/v1/account`;

            const profile = await get(user);
            credentials.profile = {
Ejemplo n.º 15
0
  lab.test('definitionPrefix = useLabel', async () => {
    // use the label as a prefix for dynamic model names

    const tempRoutes = [
      {
        method: 'POST',
        path: '/store1/',
        options: {
          handler: Helper.defaultHandler,
          tags: ['api'],
          validate: {
            payload: Joi.object({
              a: Joi.number(),
              b: Joi.number(),
              operator: Joi.string(),
              equals: Joi.number()
            }).label('A')
          }
        }
      },
      {
        method: 'POST',
        path: '/store2/',
        options: {
          handler: Helper.defaultHandler,
          tags: ['api'],
          validate: {
            payload: Joi.object({
              c: Joi.number(),
              v: Joi.number(),
              operator: Joi.string(),
              equals: Joi.number()
            }).label('A A')
          }
        }
      },
      {
        method: 'POST',
        path: '/store3/',
        options: {
          handler: Helper.defaultHandler,
          tags: ['api'],
          validate: {
            payload: Joi.object({
              c: Joi.number(),
              f: Joi.number(),
              operator: Joi.string(),
              equals: Joi.number()
            }).label('A')
          }
        }
      }
    ];

    const server = await Helper.createServer({ definitionPrefix: 'useLabel' }, tempRoutes);

    const response = await server.inject({ method: 'GET', url: '/swagger.json' });

    expect(response.statusCode).to.equal(200);
    expect(response.result.definitions.A).to.exist();
    expect(response.result.definitions['A A']).to.exist();
    expect(response.result.definitions['A 1']).to.exist();
    const isValid = await Validate.test(response.result);
    expect(isValid).to.be.true();
  });
Ejemplo n.º 16
0
const internals = {};


internals.schema = Joi.object({
    strictHeader: Joi.boolean(),
    ignoreErrors: Joi.boolean(),
    isSecure: Joi.boolean(),
    isHttpOnly: Joi.boolean(),
    isSameSite: Joi.valid('Strict', 'Lax').allow(false),
    path: Joi.string().allow(null),
    domain: Joi.string().allow(null),
    ttl: Joi.number().allow(null),
    encoding: Joi.string().valid('base64json', 'base64', 'form', 'iron', 'none'),
    sign: Joi.object({
        password: [Joi.string(), Joi.binary(), Joi.object()],
        integrity: Joi.object()
    }),
    iron: Joi.object(),
    password: [Joi.string(), Joi.binary(), Joi.object()],

    // Used by hapi

    clearInvalid: Joi.boolean(),
    autoValue: Joi.any(),
    passThrough: Joi.boolean()
});


internals.defaults = {
    strictHeader: true,                             // Require an RFC 6265 compliant header format
Ejemplo n.º 17
0
/**
 * @type {Object}
 * @private
 *
 * Store internal objects
 */
const internals = {
  regexp: {
    braces: /[{}']+/g,
    params: /\{(\w+\*?|\w+\?|\w+\*[1-9][0-9]*)\}/g,
    wildcard: /\*$/g
  },
  scheme: {
    params: {
      query: joi.object(),
      params: joi.object()
    },
    options: {
      secure: joi.boolean(),
      rel: joi.boolean().default(false),
      host: joi.string()
    }
  }
}

/**
 * @function
 * @private
 *
 * Check if condition is true and throw error if not
Ejemplo n.º 18
0
Archivo: index.js Proyecto: hapijs/h2o2
};


internals.schema = Joi.object({
    httpClient: Joi.object({
        request: Joi.func(),
        parseCacheControl: Joi.func()
    }),
    host: Joi.string(),
    port: Joi.number().integer(),
    protocol: Joi.string().valid('http', 'https', 'http:', 'https:'),
    uri: Joi.string(),
    passThrough: Joi.boolean(),
    localStatePassThrough: Joi.boolean(),
    acceptEncoding: Joi.boolean().when('passThrough', { is: true, otherwise: Joi.forbidden() }),
    rejectUnauthorized: Joi.boolean(),
    xforward: Joi.boolean(),
    redirects: Joi.number().min(0).integer().allow(false),
    timeout: Joi.number().integer(),
    mapUri: Joi.func(),
    onResponse: Joi.func(),
    onRequest: Joi.func(),
    agent: Joi.object(),
    ttl: Joi.string().valid('upstream').allow(null),
    maxSockets: Joi.number().positive().allow(false),
    secureProtocol: Joi.string(),
    ciphers: Joi.string(),
    downstreamResponseTime: Joi.boolean()
})
    .xor('host', 'mapUri', 'uri')
    .without('mapUri', 'port')
    .without('mapUri', 'protocol')
Ejemplo n.º 19
0
Archivo: ping.js Proyecto: ipfs/js-ipfs
'use strict'

const Joi = require('@hapi/joi')
const pull = require('pull-stream')
const ndjson = require('pull-ndjson')
const { PassThrough } = require('readable-stream')

module.exports = {
  validate: {
    query: Joi.object().keys({
      n: Joi.alternatives()
        .when('count', {
          is: Joi.any().exist(),
          then: Joi.any().forbidden(),
          otherwise: Joi.number().integer().greater(0)
        }),
      count: Joi.number().integer().greater(0),
      arg: Joi.string().required()
    }).unknown()
  },
  async handler (request, h) {
    const { ipfs } = request.server.app
    const peerId = request.query.arg

    // Default count to 10
    const count = request.query.n || request.query.count || 10

    const responseStream = await new Promise((resolve, reject) => {
      const stream = new PassThrough()

      pull(
Ejemplo n.º 20
0
const DEFAULT = {
  width: 1300,
  height: 900,
  timeout: 30000,
  maxImageFileSize: 10240,
  minify: true,
  inline: false,
  strict: false,
  extract: false,
  inlineImages: false,
  concurrency: Infinity,
  include: [],
};

const schema = Joi.object()
  .keys({
    html: Joi.string(),
    src: [Joi.string(), Joi.object()],
    css: [Joi.string(), Joi.array()],
    base: Joi.string(),
    strict: Joi.boolean().default(DEFAULT.strict),
    extract: Joi.boolean().default(DEFAULT.extract),
    inlineImages: Joi.boolean().default(DEFAULT.inlineImages),
    postcss: Joi.array(),
    ignore: [Joi.array(), Joi.object().unknown(true)],
    width: Joi.number().default(DEFAULT.width),
    height: Joi.number().default(DEFAULT.height),
    minify: Joi.boolean().default(DEFAULT.minify),
    dimensions: Joi.array().items({width: Joi.number(), height: Joi.number()}),
    inline: [Joi.boolean().default(DEFAULT.inline), Joi.object().unknown(true)],
Ejemplo n.º 21
0
'use strict';

const Hoek = require('@hapi/hoek');
const Joi = require('@hapi/joi');


const internals = {};


internals.schema = Joi.object({
    uri: Joi.string().uri().optional(),
    extendedProfile: Joi.boolean().optional(),
    identityServiceProfile: Joi.boolean().optional().when('extendedProfile', { is: false, then: Joi.invalid(true) })
});


internals.defaults = {
    uri: 'https://login.salesforce.com',
    extendedProfile: true,
    identityServiceProfile: false
};


exports = module.exports = function (options) {

    const combinedSettings = Hoek.applyToDefaults(internals.defaults, options || {});
    const settings = Joi.attempt(combinedSettings, internals.schema);

    return {
        protocol: 'oauth2',
        auth: settings.uri + '/services/oauth2/authorize',
Ejemplo n.º 22
0
lab.experiment('lout examples', () => {
  // these are example are taken from https://github.com/hapijs/lout/blob/master/test/routes/default.js
  /*
    Copyright (c) 2012-2014, Walmart and other contributors.
    All rights reserved.

    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions are met:
        * Redistributions of source '@hapi/code' must retain the above copyright
        notice, this list of conditions and the following disclaimer.
        * Redistributions in binary form must reproduce the above copyright
        notice, this list of conditions and the following disclaimer in the
        documentation and/or other materials provided with the distribution.
        * The names of any contributors may not be used to endorse or promote
        products derived from this software without specific prior written
        permission.

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY
    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    */
  const routes = [
    {
      method: 'GET',
      path: '/test',
      config: {
        handler: Helper.defaultHandler,
        validate: {
          query: {
            param1: Joi.string()
              .insensitive()
              .required()
          }
        },
        tags: ['api'],
        description: 'Test GET',
        notes: 'test note'
      }
    },
    {
      method: 'GET',
      path: '/another/test',
      config: {
        tags: ['api'],
        handler: Helper.defaultHandler,
        validate: {
          query: {
            param1: Joi.string().required()
          }
        }
      }
    },
    {
      method: 'GET',
      path: '/zanother/test',
      config: {
        tags: ['api'],
        handler: Helper.defaultHandler,
        validate: {
          query: {
            param1: Joi.string().required()
          }
        }
      }
    },
    {
      method: 'POST',
      path: '/test',
      config: {
        tags: ['api'],
        handler: Helper.defaultHandler,
        validate: {
          query: {
            param2: Joi.string().valid('first', 'last'),
            param3: 'third',
            param4: 42
          }
        }
      }
    },
    {
      method: 'DELETE',
      path: '/test',
      config: {
        tags: ['api'],
        handler: Helper.defaultHandler,
        validate: {
          query: {
            param2: Joi.string().valid('first', 'last')
          }
        }
      }
    },
    {
      method: 'PUT',
      path: '/test',
      config: {
        tags: ['api'],
        handler: Helper.defaultHandler,
        validate: {
          query: {
            param2: Joi.string().valid('first', 'last')
          }
        }
      }
    },
    {
      method: 'PATCH',
      path: '/test',
      config: {
        tags: ['api'],
        handler: Helper.defaultHandler,
        validate: {
          query: {
            param2: Joi.string().valid('first', 'last'),
            param3: Joi.number().valid(42)
          }
        }
      }
    },
    {
      method: 'GET',
      path: '/notincluded',
      config: {
        tags: ['api'],
        handler: Helper.defaultHandler,
        plugins: {
          lout: false
        }
      }
    },
    {
      method: 'GET',
      path: '/nested',
      config: {
        tags: ['api'],
        handler: Helper.defaultHandler,
        validate: {
          query: {
            param1: Joi.object({
              nestedparam1: Joi.string().required(),
              array: Joi.array()
            })
          }
        }
      }
    },
    {
      method: 'GET',
      path: '/rootobject',
      config: {
        tags: ['api'],
        handler: Helper.defaultHandler,
        validate: {
          query: Joi.object({
            param1: Joi.string().required()
          })
        }
      }
    },
    {
      method: 'GET',
      path: '/rootarray',
      config: {
        tags: ['api'],
        handler: Helper.defaultHandler,
        validate: {
          query: Joi.array()
            .items(Joi.string().required(), Joi.object({ param1: Joi.number() }), Joi.number().forbidden())
            .min(2)
            .max(5)
            .length(3)
        }
      }
    },
    {
      method: 'GET',
      path: '/complexarray',
      config: {
        tags: ['api'],
        handler: Helper.defaultHandler,
        validate: {
          query: Joi.array()
            .ordered('foo', 'bar')
            .items(
              Joi.string().required(),
              Joi.string()
                .valid('four')
                .forbidden(),
              Joi.object({ param1: Joi.number() }),
              Joi.number().forbidden()
            )
            .min(2)
            .max(5)
            .length(3)
            .ordered('bar', 'bar')
            .items(Joi.number().required())
        }
      }
    },
    {
      method: 'GET',
      path: '/path/{pparam}/test',
      config: {
        tags: ['api'],
        handler: Helper.defaultHandler,
        validate: {
          params: {
            pparam: Joi.string().required()
          }
        }
      }
    },
    {
      method: 'GET',
      path: '/emptyobject',
      config: {
        tags: ['api'],
        handler: Helper.defaultHandler,
        validate: {
          query: {
            param1: Joi.object()
          }
        }
      }
    },
    {
      method: 'GET',
      path: '/alternatives',
      config: {
        tags: ['api'],
        handler: Helper.defaultHandler,
        validate: {
          query: {
            param1: Joi.alternatives().try(Joi.number().required(), Joi.string().valid('first', 'last'))
          }
        }
      }
    },
    {
      method: 'GET',
      path: '/withnestedalternatives',
      config: {
        tags: ['api'],
        handler: Helper.defaultHandler,
        validate: {
          query: {
            param1: Joi.object({
              param2: Joi.alternatives().try(
                {
                  param3: Joi.object({
                    param4: Joi.number().example(5)
                  }).description('this is cool too')
                },
                Joi.number().min(42)
              )
            }).description('something really cool'),
            param2: Joi.array()
              .items(
                Joi.object({
                  param2: Joi.alternatives().try(
                    {
                      param3: Joi.object({
                        param4: Joi.number().example(5)
                      }).description('this is cool too')
                    },
                    Joi.array().items('foo', 'bar'),
                    Joi.number()
                      .min(42)
                      .required(),
                    Joi.number()
                      .max(42)
                      .required()
                  )
                }).description('all the way down')
              )
              .description('something really cool')
          }
        }
      }
    },
    {
      method: 'GET',
      path: '/novalidation',
      config: {
        tags: ['api'],
        handler: Helper.defaultHandler
      }
    },
    {
      method: 'GET',
      path: '/withresponse',
      config: {
        tags: ['api'],
        handler: Helper.defaultHandler,
        response: {
          schema: {
            param1: Joi.string()
          }
        }
      }
    },
    {
      method: 'GET',
      path: '/withstatus',
      config: {
        tags: ['api'],
        handler: Helper.defaultHandler,
        response: {
          schema: {
            param1: Joi.string()
          },
          status: {
            204: {
              param2: Joi.string()
            },
            404: {
              error: 'Failure'
            }
          }
        }
      }
    },
    {
      method: 'GET',
      path: '/withpojoinarray',
      config: {
        tags: ['api'],
        handler: Helper.defaultHandler,
        validate: {
          query: {
            param1: Joi.array().items({
              param2: Joi.string()
            })
          }
        }
      }
    },
    {
      method: 'POST',
      path: '/withnestedrulesarray',
      config: {
        tags: ['api'],
        handler: Helper.defaultHandler,
        validate: {
          payload: {
            param1: Joi.array().items(
              Joi.object({
                param2: Joi.array()
                  .items(
                    Joi.object({
                      param3: Joi.string()
                    })
                  )
                  .optional()
              })
            )
          }
        }
      }
    },
    {
      method: 'GET',
      path: '/withhtmlnote',
      config: {
        tags: ['api'],
        handler: Helper.defaultHandler,
        validate: {
          query: {
            param1: Joi.string().notes('<span class="htmltypenote">HTML type note</span>')
          }
        },
        notes: '<span class="htmlroutenote">HTML route note</span>'
      }
    },
    {
      method: 'GET',
      path: '/withnotesarray',
      config: {
        tags: ['api'],
        handler: Helper.defaultHandler,
        validate: {
          query: {
            param1: Joi.string().notes([
              '<span class="htmltypenote">HTML type note</span>',
              '<span class="htmltypenote">HTML type note</span>'
            ])
          }
        }
      }
    },
    {
      method: 'GET',
      path: '/withexample',
      config: {
        tags: ['api'],
        handler: Helper.defaultHandler,
        validate: {
          query: {
            param1: Joi.string()
              .regex(/^\w{1,5}$/)
              .example('abcde')
          }
        }
      }
    },
    {
      method: 'POST',
      path: '/denybody',
      config: {
        tags: ['api'],
        handler: Helper.defaultHandler,
        validate: {
          payload: false
        }
      }
    },
    {
      method: 'POST',
      path: '/rootemptyobject',
      config: {
        tags: ['api'],
        handler: Helper.defaultHandler,
        validate: {
          payload: Joi.object()
        }
      }
    },
    {
      method: 'GET',
      path: '/withnestedexamples',
      config: {
        tags: ['api'],
        handler: Helper.defaultHandler,
        validate: {
          query: {
            param1: Joi.object({
              param2: Joi.object({
                param3: Joi.number().example(5)
              }).example({
                param3: 5
              })
            }).example({
              param2: {
                param3: 5
              }
            })
          }
        }
      }
    },
    {
      method: 'GET',
      path: '/withmeta',
      config: {
        tags: ['api'],
        handler: Helper.defaultHandler,
        validate: {
          query: {
            param1: Joi.string().meta({
              index: true,
              unique: true
            })
          }
        }
      }
    },
    {
      method: 'GET',
      path: '/withunit',
      config: {
        tags: ['api'],
        handler: Helper.defaultHandler,
        validate: {
          query: {
            param1: Joi.number().unit('ms')
          }
        }
      }
    },
    {
      method: 'GET',
      path: '/withdefaultvalue',
      config: {
        tags: ['api'],
        handler: Helper.defaultHandler,
        validate: {
          query: {
            param1: Joi.number().default(42)
          }
        }
      }
    },
    {
      method: 'GET',
      path: '/withbinaryencoding',
      config: {
        tags: ['api'],
        handler: Helper.defaultHandler,
        validate: {
          query: {
            param1: Joi.binary()
              .min(42)
              .max(128)
              .length(64)
              .encoding('base64')
          }
        }
      }
    },
    {
      method: 'GET',
      path: '/withdate',
      config: {
        tags: ['api'],
        handler: Helper.defaultHandler,
        validate: {
          query: {
            param1: Joi.date()
              .min('1-1-1974')
              .max('12-31-2020')
          }
        }
      }
    },
    {
      method: 'GET',
      path: '/withpeersconditions',
      config: {
        tags: ['api'],
        handler: Helper.defaultHandler,
        validate: {
          query: {
            param1: Joi.object()
              .and('a', 'b', 'c')
              .or('a', 'b', 'c')
              .xor('a', 'b', 'c')
              .with('a', ['b', 'c'])
              .without('a', ['b', 'c'])
          }
        }
      }
    },
    {
      method: 'GET',
      path: '/withpattern',
      config: {
        tags: ['api'],
        handler: Helper.defaultHandler,
        validate: {
          query: {
            param1: Joi.object({
              a: Joi.string()
            }).pattern(/\w\d/, Joi.boolean())
          }
        }
      }
    },
    {
      method: 'GET',
      path: '/withallowunknown',
      config: {
        tags: ['api'],
        handler: Helper.defaultHandler,
        validate: {
          query: {
            param1: Joi.object().unknown(),
            param2: Joi.object().unknown(false)
          }
        }
      }
    },
    {
      method: 'GET',
      path: '/withstringspecifics',
      config: {
        tags: ['api'],
        handler: Helper.defaultHandler,
        validate: {
          query: {
            param1: Joi.string()
              .alphanum()
              .regex(/\d{3}.*/)
              .token()
              .email()
              .guid()
              .isoDate()
              .hostname()
              .lowercase()
              .uppercase()
              .trim(),
            param2: Joi.string().email()
          }
        }
      }
    },
    {
      method: 'GET',
      path: '/withconditionalalternatives',
      config: {
        tags: ['api'],
        handler: Helper.defaultHandler,
        validate: {
          query: {
            param1: Joi.alternatives()
              .when('b', {
                is: 5,
                then: Joi.string(),
                otherwise: Joi.number()
                  .required()
                  .description('Things and stuff')
              })
              .when('a', {
                is: true,
                then: Joi.date(),
                otherwise: Joi.any()
              }),
            param2: Joi.alternatives()
              .when('b', {
                is: 5,
                then: Joi.string()
              })
              .when('a', {
                is: true,
                otherwise: Joi.any()
              })
          }
        }
      }
    },
    {
      method: 'GET',
      path: '/withreferences',
      config: {
        tags: ['api'],
        handler: Helper.defaultHandler,
        validate: {
          query: {
            param1: Joi.ref('a.b'),
            param2: Joi.ref('$x')
          }
        }
      }
    },
    {
      method: 'GET',
      path: '/withassert',
      config: {
        tags: ['api'],
        handler: Helper.defaultHandler,
        validate: {
          query: {
            param1: Joi.object().assert('d.e', Joi.ref('a.c'), 'equal to a.c'),
            param2: Joi.object().assert('$x', Joi.ref('b.e'), 'equal to b.e')
          }
        }
      }
    },
    {
      method: 'GET',
      path: '/withproperties',
      vhost: 'john.doe',
      config: {
        tags: ['api'],
        handler: Helper.defaultHandler,
        cors: {
          maxAge: 12345
        },
        jsonp: 'callback'
      }
    },
    {
      method: 'OPTIONS',
      path: '/optionstest',
      handler: Helper.defaultHandler
    },
    {
      method: 'GET',
      path: '/withrulereference',
      config: {
        tags: ['api'],
        handler: Helper.defaultHandler,
        validate: {
          query: {
            param1: Joi.date().min(Joi.ref('param2')),
            param2: Joi.date()
          }
        }
      }
    },
    {
      method: 'GET',
      path: '/withcorstrue',
      vhost: 'john.doe',
      config: {
        tags: ['api'],
        handler: Helper.defaultHandler,
        cors: true
      }
    },
    {
      method: 'GET',
      path: '/withstrip',
      config: {
        tags: ['api'],
        handler: Helper.defaultHandler,
        validate: {
          query: {
            param1: Joi.any().strip(),
            param2: Joi.any()
          }
        }
      }
    },
    {
      method: 'GET',
      path: '/internal',
      config: {
        tags: ['api'],
        isInternal: true,
        handler: Helper.defaultHandler
      }
    }
  ];

  lab.test('all routes parsed', async () => {
    const server = await Helper.createServer({}, routes);
    const response = await server.inject({ method: 'GET', url: '/swagger.json' });
    expect(response.statusCode).to.equal(200);
    // the 40 to 45 difference is in one route having a number of methods
    expect(response.result.paths).to.have.length(40);
  });
});
Ejemplo n.º 23
0
/*
  Copyright 2018 Google LLC

  Use of this source code is governed by an MIT-style
  license that can be found in the LICENSE file or at
  https://opensource.org/licenses/MIT.
*/

const joi = require('@hapi/joi');

const defaults = require('./defaults');
const regExpObject = require('./reg-exp-object');

// Define some common constraints used by all methods.
module.exports = joi.object().keys({
  dontCacheBustURLsMatching: regExpObject,
  globFollow: joi.boolean().default(defaults.globFollow),
  globIgnores: joi.array().items(joi.string()).default(defaults.globIgnores),
  globPatterns: joi.array().items(joi.string()).default(defaults.globPatterns),
  globStrict: joi.boolean().default(defaults.globStrict),
  manifestTransforms: joi.array().items(joi.func().arity(1)),
  maximumFileSizeToCacheInBytes: joi.number().min(1)
      .default(defaults.maximumFileSizeToCacheInBytes),
  modifyURLPrefix: joi.object(),
  // templatedURLs is an object where any property name is valid, and the values
  // can be either a string or an array of strings.
  templatedURLs: joi.object().pattern(/./,
      [joi.string(), joi.array().items(joi.string())]),
});
Ejemplo n.º 24
0
// Declare Internals

const internals = {};

internals.defaults = {
    accessTokenName: 'access_token',
    allowQueryToken: false,
    allowCookieToken: false,
    allowMultipleHeaders: false,
    allowChaining: false,
    tokenType: 'Bearer',
    unauthorized: Boom.unauthorized
};

internals.schema = Joi.object().keys({
    validate: Joi.func().required(),
    accessTokenName: Joi.string().required(),
    allowQueryToken: Joi.boolean(),
    allowCookieToken: Joi.boolean(),
    allowMultipleHeaders: Joi.boolean(),
    allowChaining: Joi.boolean(),
    tokenType: Joi.string().required(),
    unauthorized: Joi.func()
});

internals.implementation = (server, options) => {

    Hoek.assert(options, 'Missing bearer auth strategy options');

    const settings = Hoek.applyToDefaults(internals.defaults, options);
Ejemplo n.º 25
0
lab.experiment('definitions', () => {
  const routes = [
    {
      method: 'POST',
      path: '/test/',
      options: {
        handler: Helper.defaultHandler,
        tags: ['api'],
        validate: {
          payload: {
            a: Joi.number()
              .required()
              .description('the first number'),

            b: Joi.number()
              .required()
              .description('the second number'),

            operator: Joi.string()
              .required()
              .default('+')
              .description('the opertator i.e. + - / or *'),

            equals: Joi.number()
              .required()
              .description('the result of the sum')
          }
        }
      }
    },
    {
      method: 'POST',
      path: '/test/2',
      options: {
        handler: Helper.defaultHandler,
        tags: ['api'],
        validate: {
          payload: Joi.object({
            a: Joi.string(),
            b: Joi.object({
              c: Joi.string()
            })
          }).label('Model')
        }
      }
    },
    {
      method: 'POST',
      path: '/test/3',
      options: {
        handler: Helper.defaultHandler,
        tags: ['api'],
        validate: {
          payload: Joi.object({
            a: Joi.string(),
            b: Joi.object({
              c: Joi.string()
            })
          }).label('Model 1')
        }
      }
    }
  ];

  lab.test('payload with inline definition', async () => {
    const server = await Helper.createServer({}, routes);

    const defination = {
      properties: {
        a: {
          description: 'the first number',
          type: 'number'
        },
        b: {
          description: 'the second number',
          type: 'number'
        },
        operator: {
          description: 'the opertator i.e. + - / or *',
          default: '+',
          type: 'string'
        },
        equals: {
          description: 'the result of the sum',
          type: 'number'
        }
      },
      required: ['a', 'b', 'operator', 'equals'],
      type: 'object'
    };

    const response = await server.inject({ method: 'GET', url: '/swagger.json' });

    expect(response.statusCode).to.equal(200);
    expect(response.result.paths['/test/'].post.parameters[0].schema).to.equal({
      $ref: '#/definitions/Model 1'
    });
    expect(response.result.definitions['Model 1']).to.equal(defination);
    const isValid = await Validate.test(response.result);
    expect(isValid).to.be.true();
  });

  lab.test('override definition named Model', async () => {
    const server = await Helper.createServer({}, routes);
    const response = await server.inject({ method: 'GET', url: '/swagger.json' });

    //console.log(JSON.stringify(response.result.definitions));
    expect(response.result.definitions.b).to.exists();
    expect(response.result.definitions.Model).to.exists();
    expect(response.result.definitions['Model 1']).to.exists();

    const isValid = await Validate.test(response.result);
    expect(isValid).to.be.true();
  });

  lab.test('reuseDefinitions = false', async () => {
    // forces two models even though the model hash is the same

    const tempRoutes = [
      {
        method: 'POST',
        path: '/store1/',
        options: {
          handler: Helper.defaultHandler,
          tags: ['api'],
          validate: {
            payload: Joi.object({
              a: Joi.number(),
              b: Joi.number(),
              operator: Joi.string(),
              equals: Joi.number()
            }).label('A')
          }
        }
      },
      {
        method: 'POST',
        path: '/store2/',
        options: {
          handler: Helper.defaultHandler,
          tags: ['api'],
          validate: {
            payload: Joi.object({
              a: Joi.number(),
              b: Joi.number(),
              operator: Joi.string(),
              equals: Joi.number()
            }).label('B')
          }
        }
      }
    ];

    const server = await Helper.createServer({ reuseDefinitions: false }, tempRoutes);

    const response = await server.inject({ method: 'GET', url: '/swagger.json' });

    //console.log(JSON.stringify(response.result));
    expect(response.statusCode).to.equal(200);
    expect(response.result.definitions.A).to.exist();
    expect(response.result.definitions.B).to.exist();
    const isValid = await Validate.test(response.result);
    expect(isValid).to.be.true();
  });

  lab.test('definitionPrefix = useLabel', async () => {
    // use the label as a prefix for dynamic model names

    const tempRoutes = [
      {
        method: 'POST',
        path: '/store1/',
        options: {
          handler: Helper.defaultHandler,
          tags: ['api'],
          validate: {
            payload: Joi.object({
              a: Joi.number(),
              b: Joi.number(),
              operator: Joi.string(),
              equals: Joi.number()
            }).label('A')
          }
        }
      },
      {
        method: 'POST',
        path: '/store2/',
        options: {
          handler: Helper.defaultHandler,
          tags: ['api'],
          validate: {
            payload: Joi.object({
              c: Joi.number(),
              v: Joi.number(),
              operator: Joi.string(),
              equals: Joi.number()
            }).label('A A')
          }
        }
      },
      {
        method: 'POST',
        path: '/store3/',
        options: {
          handler: Helper.defaultHandler,
          tags: ['api'],
          validate: {
            payload: Joi.object({
              c: Joi.number(),
              f: Joi.number(),
              operator: Joi.string(),
              equals: Joi.number()
            }).label('A')
          }
        }
      }
    ];

    const server = await Helper.createServer({ definitionPrefix: 'useLabel' }, tempRoutes);

    const response = await server.inject({ method: 'GET', url: '/swagger.json' });

    expect(response.statusCode).to.equal(200);
    expect(response.result.definitions.A).to.exist();
    expect(response.result.definitions['A A']).to.exist();
    expect(response.result.definitions['A 1']).to.exist();
    const isValid = await Validate.test(response.result);
    expect(isValid).to.be.true();
  });

  lab.test('test that optional array is not in swagger output', async () => {
    let testRoutes = [
      {
        method: 'POST',
        path: '/server/1/',
        options: {
          handler: Helper.defaultHandler,
          tags: ['api'],
          validate: {
            payload: Joi.object({
              a: Joi.number().required(),
              b: Joi.string().optional()
            }).label('test')
          }
        }
      }
    ];

    const server = await Helper.createServer({}, testRoutes);

    const response = await server.inject({ method: 'GET', url: '/swagger.json' });

    expect(response.statusCode).to.equal(200);
    expect(response.result.definitions.test).to.equal({
      type: 'object',
      properties: {
        a: {
          type: 'number'
        },
        b: {
          type: 'string'
        }
      },
      required: ['a']
    });
  });

  lab.test('test that name changing for required', async () => {
    const FormDependencyDefinition = Joi.object({
      id: Joi.number().required()
    }).label('FormDependencyDefinition');

    const ActionDefinition = Joi.object({
      id: Joi.number()
        .required()
        .allow(null),
      reminder: FormDependencyDefinition.required()
    }).label('ActionDefinition');

    let testRoutes = [
      {
        method: 'POST',
        path: '/server/',
        options: {
          handler: Helper.defaultHandler,
          tags: ['api'],
          validate: {
            payload: ActionDefinition
          }
        }
      }
    ];

    const server = await Helper.createServer({}, testRoutes);

    const response = await server.inject({ method: 'GET', url: '/swagger.json' });

    expect(response.statusCode).to.equal(200);
    expect(response.result.definitions.ActionDefinition).to.equal({
      type: 'object',
      properties: {
        id: {
          type: 'number'
        },
        reminder: {
          $ref: '#/definitions/FormDependencyDefinition'
        }
      },
      required: ['id', 'reminder']
    });
  });
});
Ejemplo n.º 26
0
Archivo: index.js Proyecto: hapijs/shot
'use strict';

const Hoek = require('@hapi/hoek');
const Joi = require('@hapi/joi');

const Request = require('./request');
const Response = require('./response');
const Symbols = require('./symbols');


const internals = {};


internals.options = Joi.object().keys({
    url: Joi.alternatives([
        Joi.string(),
        Joi.object().keys({
            protocol: Joi.string(),
            hostname: Joi.string(),
            port: Joi.any(),
            pathname: Joi.string().required(),
            query: Joi.any()
        })
    ])
        .required(),
    headers: Joi.object(),
    payload: Joi.any(),
    simulate: {
        end: Joi.boolean(),
        split: Joi.boolean(),
        error: Joi.boolean(),