コード例 #1
0
'use strict'

const Joi = require('joi')
const { invalidJSON } = require('../response-fixtures')

const isPlatform = Joi.string().regex(
  /^(osx|ios|tvos|watchos)( \| (osx|ios|tvos|watchos))*$/
)

const t = (module.exports = require('../create-service-tester')())

t.create('platform (valid)')
  .get('/AFNetworking.json')
  .expectJSONTypes(
    Joi.object().keys({
      name: 'platform',
      value: isPlatform,
    })
  )

t.create('platform (not found)')
  .get('/not-a-package.json')
  .expectJSON({ name: 'platform', value: 'not found' })

t.create('platform (connection error)')
  .get('/AFNetworking.json')
  .networkOff()
  .expectJSON({ name: 'platform', value: 'inaccessible' })

t.create('platform (unexpected response)')
  .get('/AFNetworking.json')
コード例 #2
0
ファイル: auth.js プロジェクト: screwdriver-cd/data-schema
'use strict';

const Joi = require('joi');

const SCHEMA_KEY = Joi.object().keys({
    key: Joi.string().label('Public Key for Verifying JWTs')
}).label('Public Key for Verifying JWTs Object');

const SCHEMA_TOKEN = Joi.object().keys({
    token: Joi.string().label('JSON Web Token')
}).label('JSON Web Token Object');

const SCHEMA_CRUMB = Joi.object().keys({
    crumb: Joi.string().label('Crumb to prevent CSRF')
}).label('Crumb to prevent CSRF Object');

const SCHEMA_CONTEXTS = Joi.array().items(
    Joi.object().keys({
        context: Joi.string().label('Context name'),
        displayName: Joi.string().label('Display name')
    }).label('Context Object')
).label('Array of Contexts');

module.exports = {
    key: SCHEMA_KEY,
    token: SCHEMA_TOKEN,
    crumb: SCHEMA_CRUMB,
    contexts: SCHEMA_CONTEXTS
};
コード例 #3
0
ファイル: token.js プロジェクト: mrb91002/OhSewMuch
'use strict';

const Joi = require('joi');

module.exports.post = {
  body: {
    userName: Joi.string()
      .min(3)
      .max(255)
      .label('User Name')
      .trim()
      .required(),
    password: Joi.string()
      .label('Password')
      .min(8)
      .trim()
      .required()
  }
};
コード例 #4
0
ファイル: validation.js プロジェクト: PseudoCorps/toothache
var Lab = require("lab"),
	Hapi = require("hapi"),
	Joi = require("joi"),
	MongoDB = require('mongodb').Db,
	Server = require('mongodb').Server,
	ObjectId = require('mongodb').ObjectID,
    Bcrypt = require('bcryptjs');

// Internal config stuff
var CRUD = {
    collection: 'resources3',
    create: {
        bcrypt: 'password',
        date: 'created',
        payload: Joi.object().keys({
            email: Joi.string().required(),
            password: Joi.string().required()
        }),
        defaults: {
            access: 'normal',
            activated: false
        },
    },
    update: {
        bcrypt: 'password',
        date: 'updated',
        payload: Joi.object().keys({
            email: Joi.string(),
            password: Joi.string()
        })
    },    
コード例 #5
0
      }
    }
  },

  {
    method: 'POST',
    path: '/auth/login',
    config: {
      description: 'Validate login credentials',
      auth: {
        strategy: 'session',
        mode: 'try'
      },
      validate: {
        payload: {
          email: Joi.string().required(),
          password: Joi.string().required()
        }
      },
      handler: Promise.coroutine(function*(request, reply){

        const body = request.payload;
        const db = request.server.plugins.db.mongo;

        try {

          // ensure that the user exists
          const Users = db.col('users');
          const user = yield Users.findOne({ email: body.email });

          if (!user) {
コード例 #6
0
import "babel-polyfill"
import vogels from "vogels"
import Joi from "joi"
import _ from "lodash"
import {count, min, max} from "./statistics"
vogels.AWS.config.loadFromPath("credentials.json")
const table = vogels.define("webgl_result", {
    hashKey: "name",
    timestamps: true,
    schema: {
        name: Joi.string(),
        platform_name: Joi.string(),
        platform_version: Joi.string(),
        browser_name: Joi.string(),
        browser_version: Joi.string(),
        max: Joi.array(),
        min: Joi.array(),
        count: Joi.array(),
        index: Joi.array()
    }
})
const statistics = vogels.define("webgl_statistic", {
    hashKey: "id",
    timestamps: true,
    schema: {
        id: Joi.string(),
        extensions: Joi.object(),
        parameters: Joi.object(),
        platform_name: Joi.string(),
        platform_version: Joi.string(),
        browser_name: Joi.string(),
コード例 #7
0
ファイル: config.js プロジェクト: epochtalk/epochtalk
  */
exports.addRoles = {
  auth: { strategy: 'jwt' },
  plugins: {
    acls: 'adminUsers.addRoles',
    mod_log: {
      type: 'adminUsers.addRoles',
      data: {
        usernames: 'payload.usernames',
        role_id: 'payload.role_id'
      }
    }
  },
  validate: {
    payload: {
      usernames: Joi.array().items(Joi.string().required()).unique().min(1).required(),
      role_id: Joi.string().required()
    }
  },
  pre: [ { method: 'auth.admin.users.addRole(server, auth, payload.role_id, payload.usernames)' } ],
  handler: function(request, reply) {
    var usernames = request.payload.usernames;
    var roleId = request.payload.role_id;
    var promise = request.db.roles.addRoles(usernames, roleId)
    .tap(function(users) {
      return Promise.map(users, function(user) {
        var notification = {
          channel: { type: 'user', id: user.id },
          data: { action: 'reauthenticate' }
        };
        request.server.plugins.notifications.systemNotification(notification);
コード例 #8
0
ファイル: pdf.js プロジェクト: EnvironmentAgency/fmp-app
              strictEpsg4326: false
            }
          ]
        }
      }

      try {
        const result = await Wreck.post(printUrl, options)
        const date = new Date().toISOString()
        return h.response(result.payload)
          .encoding('binary')
          .type('application/pdf')
          .header('content-disposition', `attachment; filename=flood-map-planning-${date}.pdf;`)
          .state('pdf-download', id.toString())
      } catch (err) {
        return Boom.badImplementation((err && err.message) || 'An error occured during PDF generation', err)
      }
    },
    validate: {
      payload: {
        id: Joi.number().required(),
        zone: Joi.string().required().allow('FZ1', 'FZ2', 'FZ3', 'FZ3a', ''),
        reference: Joi.string().allow('').max(13).trim(),
        scale: Joi.number().allow(2500, 10000, 25000, 50000).required(),
        polygon: Joi.string().required().allow(''),
        center: Joi.array().required().allow('')
      }
    }
  }
}
コード例 #9
0
/**
 * Instantiate a task-graph template from YAML string
 *
 * options:
 * {
 *   owner:         '*****@*****.**',  // Owner emails
 *   source:        'http://...'         // Source file this was instantiated from
 *   revision:      '...',               // Revision hash string
 *   comment:       'try: ...',          // Latest commit comment
 *   project:       'try',               // Treeherder project name
 *   level          '2',                 // SCM Level
 *   revision_hash: '...',               // Revision hash for treeherder resultset
 *   pushlog_id:    '...',               // Pushlog id based on json-pushes
 *   url:           '...',               // Repository url
 *   importScopes:  true,                // When true scopes from tasks will be
 *                                       // imported to the graph level.
 * }
 *
 * In in addition to options provided above the following paramters is available
 * to templates:
 *  - `now` date-time string for now,
 *  - `from-now` modifier taking a relative date as 'X days Y hours Z minutes'
 *  - `as-slugid` modifier converting a label to a slugid
 *
 */
export default function instantiate(template, options) {
  // Validate options
  Joi.assert(options, Joi.object({
    owner: Joi.string().required(),
    source: Joi.string().required(),
    revision: Joi.string().required(),
    project: Joi.string().required(),
    level: [Joi.number().required(), Joi.string().required()],
    revision_hash: Joi.string().required(),
    comment: Joi.string().default(""),
    pushlog_id: Joi.string().required(),
    url: Joi.string().required(),
    importScopes: Joi.boolean().required(),
    error: Joi.string()
  }));

  // Create label cache, so we provide the same slugids for the same label
  let labelsToSlugids = {};

  function fromNow() {
    return function(text, render) {
      return render(relativeTime(parseTime(text)).toJSON());
    }
  }

  function asSlugId() {
    return function(label, render) {
      let result = labelsToSlugids[label];
      if (result === undefined) {
        result = labelsToSlugids[label] = slugid.nice();
      }
      return render(result);
    }
  }

  // Parameterize template
  template = mustache.render(template, {
    now: new Date().toJSON(),
    owner: options.owner,
    source: options.source,
    revision: options.revision,
    comment: options.comment,
    level: options.level,
    project: options.project,
    revision_hash: options.revision_hash,
    pushlog_id: options.pushlog_id,
    url: options.url,
    from_now: fromNow,
    as_slugid: asSlugId
  });

  // Parse template
  let graph = yaml.safeLoad(template);

  // If we are not importing scopes just return the graph...
  if (!options.importScopes || !graph.tasks) {
    return graph;
  }

  // Root scopes in the graph...
  let scopes = new Set(graph.scopes || []);

  // Traverse all the scopes and add them to the root...
  for (let task of graph.tasks) {
    let inner = task.task;
    if (inner.scopes) {
      // Only add scopes once...
      for (let scope of inner.scopes) {
        scopes.add(scope);
      }
    }
  }
  graph.scopes = Array.from(scopes);
  return graph;
};
コード例 #10
0
ファイル: node.js プロジェクト: gingerwizard/kibana
export function logstashNodeRoute(server) {
  /**
   * Logstash Node request.
   *
   * This will fetch all data required to display a Logstash Node page.
   *
   * The current details returned are:
   *
   * - Logstash Node Summary (Status)
   * - Metrics
   */
  server.route({
    method: 'POST',
    path: '/api/monitoring/v1/clusters/{clusterUuid}/logstash/node/{logstashUuid}',
    config: {
      validate: {
        params: Joi.object({
          clusterUuid: Joi.string().required(),
          logstashUuid: Joi.string().required()
        }),
        payload: Joi.object({
          ccs: Joi.string().optional(),
          timeRange: Joi.object({
            min: Joi.date().required(),
            max: Joi.date().required()
          }).required(),
          is_advanced: Joi.boolean().required()
        })
      }
    },
    async handler(req) {
      const config = server.config();
      const ccs = req.payload.ccs;
      const clusterUuid = req.params.clusterUuid;
      const lsIndexPattern = prefixIndexPattern(config, 'xpack.monitoring.logstash.index_pattern', ccs);
      const logstashUuid = req.params.logstashUuid;

      let metricSet;
      if (req.payload.is_advanced) {
        metricSet = metricSetAdvanced;
      } else {
        metricSet = metricSetOverview;
        // set the cgroup option if needed
        const showCgroupMetricsLogstash = config.get('xpack.monitoring.ui.container.logstash.enabled');
        const metricCpu = metricSet.find(m => m.name === 'logstash_node_cpu_metric');
        if (showCgroupMetricsLogstash) {
          metricCpu.keys = ['logstash_node_cgroup_quota_as_cpu_utilization'];
        } else {
          metricCpu.keys = ['logstash_node_cpu_utilization'];
        }
      }

      try {
        const [ metrics, nodeSummary ] = await Promise.all([
          getMetrics(req, lsIndexPattern, metricSet),
          getNodeInfo(req, lsIndexPattern, { clusterUuid, logstashUuid }),
        ]);

        return {
          metrics,
          nodeSummary,
        };
      } catch(err) {
        throw handleError(err, req);
      }
    }
  });
}
コード例 #11
0
'use strict';

const Joi = require('joi');

const HABITAT_MODE = Joi
    .string().valid([
        'remote',
        'local'
    ])
    .description('Mode of the Habitat command')
    .example('remote');

const HABITAT_FILE = Joi
    .string()
    .description('File path of the Habitat artifact')
    .example('./foobar.hart');

const HABITAT_PACKAGE = Joi
    .string()
    .description('Package of the Habitat command')
    .example('core/git/2.14.1');

const HABITAT_COMMAND = Joi
    .string()
    .description('Executable of the Habitat command')
    .example('git');

const SCHEMA_HABITAT = Joi.object()
    .keys({
        mode: HABITAT_MODE,
        file: HABITAT_FILE
コード例 #12
0
 regexStrings.map(regexStr => Joi.string().regex(new RegExp(regexStr)))
コード例 #13
0
/*
 Copyright [2016] [Relevance Lab]

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 */
var Joi = require('joi');

var blueprintFrameValidator = module.exports = {};

blueprintFrameValidator.create = {
    body: {
        "blueprintId": Joi.string().max(40).required(),
        "environmentId": Joi.string().max(40).required()
    }
};
コード例 #14
0
var vogels = require('../index'),
    _      = require('lodash'),
    util   = require('util'),
    AWS    = vogels.AWS,
    Joi    = require('joi'),
    async  = require('async');

AWS.config.loadFromPath(process.env.HOME + '/.ec2/credentials.json');

// http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GSI.html

var GameScore = vogels.define('example-global-index', {
  hashKey : 'userId',
  rangeKey : 'gameTitle',
  schema : {
    userId           : Joi.string(),
    gameTitle        : Joi.string(),
    topScore         : Joi.number(),
    topScoreDateTime : Joi.date(),
    wins             : Joi.number(),
    losses           : Joi.number()
  },
  indexes : [{
    hashKey : 'gameTitle',
    rangeKey : 'topScore',
    name : 'GameTitleIndex',
    type : 'global',
    projection: { NonKeyAttributes: [ 'wins' ], ProjectionType: 'INCLUDE' }
  }]
});
コード例 #15
0
import Joi from 'joi';

export default {
	// POST /api/users
	createUser: {
		body: {
			username: Joi.string().required(),
			password: Joi.string().required(),
			email: Joi.string().email()
		}
	},

	// UPDATE /api/users/:userId
	getUser: {
		headers: {
			'x-access-token': Joi.string().required()
		}
	}
};
コード例 #16
0
 * API to add a project type
 */
import config from 'config';
import validate from 'express-validation';
import _ from 'lodash';
import Joi from 'joi';
import { middleware as tcMiddleware } from 'tc-core-library-js';
import util from '../../../util';
import models from '../../../models';

const permissions = tcMiddleware.permissions;

const schema = {
  params: {
    version: Joi.number().integer().positive().required(),
    key: Joi.string().max(45).required(),
  },
  body: {
    param: Joi.object().keys({
      config: Joi.object().required(),

      createdAt: Joi.any().strip(),
      updatedAt: Joi.any().strip(),
      deletedAt: Joi.any().strip(),
      createdBy: Joi.any().strip(),
      updatedBy: Joi.any().strip(),
      deletedBy: Joi.any().strip(),
    }).required(),
  },
};
コード例 #17
0
ファイル: model.js プロジェクト: Kevnz/joi-model
    it('is able to process a complex schema and throw an error when a condition is not met', function(done) {

        var adult = Joi.object({
            name: Joi.string().required(),
            job: Joi.string()
        });

        var child = Joi.object({
            name: Joi.string().required(),
            age: Joi.number().min(0).max(17).required()
        });

        var family = Joi.object({
            surname: Joi.string().required(),
            adults: Joi.array().includes(adult).min(1).max(2).required(),
            children: Joi.array().includes(child).max(4)
        });

        var FamilyModel = joiModel(family);

        var family = new FamilyModel({
            surname: 'Smith',
            adults: [{
                name: 'John',
                job: 'Clerk'
            }, {
                name: 'Jane',
                job: 'Programmer'
            }],
            children: [{
                name: 'Jimmy',
                age: 3
            }, {
                name: 'Jenny',
                age: 5
            }]
        });

        family.children.push({
            name: 'Betty',
            age: 3
        });

        family.children.push({
            name: 'Harry',
            age: 2
        });

        var err;
        try {
            family.children.push({
                name: 'Missy',
                age: 1.5
            });
        } catch(e) {
            err = e;
        }

        expect(err).to.exist;
        expect(err.message).to.contain('must include less than (or equal to) 4 items');

        done();
    });
コード例 #18
0
ファイル: index.js プロジェクト: NameFILIP/webpack-validator
export const EXTERNALS_MESSAGE = `There was something wrong with how you specified the externals.
Webpack documentation excerpt:

As value an object, a string, a function, a RegExp and an array is accepted.

- string: An exact matched dependency becomes external. The same string is used as external dependency.
- object: If an dependency matches exactly a property of the object, the property value is used as dependency. The property value may contain a dependency type prefixed and separated with a space. If the property value is true the property name is used instead. If the property value is false the externals test is aborted and the dependency is not external. See example below.
- function: function(context, request, callback(err, result)) The function is called on each dependency. If a result is passed to the callback function this value is handled like a property value of an object (above bullet point).
- RegExp: Every matched dependency becomes external. The matched text is used as the request for the external dependency. Because the request is the exact code used to generate the external code hook, if you are matching a commonjs package (e.g. ‘../some/package.js’), instead use the function external strategy. You can import the package via callback(null, "require('" + request + "')", which generates a module.exports = require('../some/package.js');, using require outside of webpack context.
- array: Multiple values of the scheme (recursive).

(see https://webpack.github.io/docs/configuration.html#externals )`
/* eslint-enable max-len */

const externalObjectSchema = Joi.object().pattern(/.+/, [
  Joi.string(),
  Joi.boolean(),
  Joi.object().pattern(/.+/, [Joi.string(), Joi.boolean()]),
])

const externalSchema = [
  externalObjectSchema,
  Joi.string(),
  Joi.func().arity(3),
  Joi.object().type(RegExp),
]

export default Joi.array()
  .items(externalSchema)
  .single()
  .options({ language: { array: {
コード例 #19
0
var database = require("./database.json");

server.route({
    path: "/users",
    method: "GET",
    handler: function(request, reply) {
		reply(Object.keys(database));
    }
});

server.route({
    path: "/users/{username}",
    method: "GET",
    config: {
        validate: {
            params: { username: Joi.string().token() }
        },
        handler: function(request, reply) {
            if (database[request.params.username]) {
                reply(database[request.params.username]);
            } else {
                reply(Hapi.error.notFound("User not found."));
            }
        }
    }
});
 
server.route({
    path: "/users/{username}",
    method: "PUT",
    config: {
コード例 #20
0
module.exports.payloadMethod = function (method, t) {
  const test = t.test
  const fastify = require('..')()
  const upMethod = method.toUpperCase()
  const loMethod = method.toLowerCase()

  const opts = {
    schema: {
      body: {
        type: 'object',
        properties: {
          hello: {
            type: 'integer'
          }
        }
      }
    }
  }

  const ajv = new Ajv({ coerceTypes: true, removeAdditional: true })
  const optsWithCustomValidator = {
    schema: {
      body: {
        type: 'object',
        properties: {
          hello: {
            type: 'integer'
          }
        },
        additionalProperties: false
      }
    },
    schemaCompiler: function (schema) {
      return ajv.compile(schema)
    }
  }

  const optsWithJoiValidator = {
    schema: {
      body: Joi.object().keys({
        hello: Joi.string().required()
      }).required()
    },
    schemaCompiler: function (schema) {
      return schema.validate.bind(schema)
    }
  }

  test(`${upMethod} can be created`, t => {
    t.plan(1)
    try {
      fastify[loMethod]('/', opts, function (req, reply) {
        reply.send(req.body)
      })
      fastify[loMethod]('/custom', optsWithCustomValidator, function (req, reply) {
        reply.send(req.body)
      })
      fastify[loMethod]('/joi', optsWithJoiValidator, function (req, reply) {
        reply.send(req.body)
      })

      fastify.register(function (fastify2, opts, next) {
        fastify2.setSchemaCompiler(function schema (schema) {
          return body => ({ error: new Error('From custom schema compiler!') })
        })
        const withInstanceCustomCompiler = {
          schema: {
            body: {
              type: 'object',
              properties: { },
              additionalProperties: false
            }
          }
        }
        fastify2[loMethod]('/plugin', withInstanceCustomCompiler, (req, reply) => reply.send({ hello: 'never here!' }))

        const optsWithCustomValidator2 = {
          schema: {
            body: {
              type: 'object',
              properties: { },
              additionalProperties: false
            }
          },
          schemaCompiler: function (schema) {
            return function (body) {
              return { error: new Error('Always fail!') }
            }
          }
        }
        fastify2[loMethod]('/plugin/custom', optsWithCustomValidator2, (req, reply) => reply.send({ hello: 'never here!' }))

        next()
      })
      t.pass()
    } catch (e) {
      t.fail()
    }
  })

  fastify.listen(0, function (err) {
    if (err) {
      t.error(err)
    }

    fastify.server.unref()

    test(`${upMethod} - correctly replies`, t => {
      if (upMethod === 'HEAD') {
        t.plan(2)
        sget({
          method: upMethod,
          url: 'http://localhost:' + fastify.server.address().port
        }, (err, response) => {
          t.error(err)
          t.strictEqual(response.statusCode, 200)
        })
      } else {
        t.plan(3)
        sget({
          method: upMethod,
          url: 'http://localhost:' + fastify.server.address().port,
          body: {
            hello: 42
          },
          json: true
        }, (err, response, body) => {
          t.error(err)
          t.strictEqual(response.statusCode, 200)
          t.deepEqual(body, { hello: 42 })
        })
      }
    })

    test(`${upMethod} - 400 on bad parameters`, t => {
      t.plan(3)
      sget({
        method: upMethod,
        url: 'http://localhost:' + fastify.server.address().port,
        body: {
          hello: 'world'
        },
        json: true
      }, (err, response, body) => {
        t.error(err)
        t.strictEqual(response.statusCode, 400)
        t.deepEqual(body, {
          error: 'Bad Request',
          message: 'body.hello should be integer',
          statusCode: 400
        })
      })
    })

    test(`${upMethod} - input-validation coerce`, t => {
      t.plan(3)
      sget({
        method: upMethod,
        url: 'http://localhost:' + fastify.server.address().port,
        body: {
          hello: '42'
        },
        json: true
      }, (err, response, body) => {
        t.error(err)
        t.strictEqual(response.statusCode, 200)
        t.deepEqual(body, { hello: 42 })
      })
    })

    test(`${upMethod} - input-validation custom schema compiler`, t => {
      t.plan(3)
      sget({
        method: upMethod,
        url: 'http://localhost:' + fastify.server.address().port + '/custom',
        body: {
          hello: '42',
          world: 55
        },
        json: true
      }, (err, response, body) => {
        t.error(err)
        t.strictEqual(response.statusCode, 200)
        t.deepEqual(body, { hello: 42 })
      })
    })

    test(`${upMethod} - input-validation joi schema compiler ok`, t => {
      t.plan(3)
      sget({
        method: upMethod,
        url: 'http://localhost:' + fastify.server.address().port + '/joi',
        body: {
          hello: '42'
        },
        json: true
      }, (err, response, body) => {
        t.error(err)
        t.strictEqual(response.statusCode, 200)
        t.deepEqual(body, { hello: 42 })
      })
    })

    test(`${upMethod} - input-validation joi schema compiler ko`, t => {
      t.plan(3)
      sget({
        method: upMethod,
        url: 'http://localhost:' + fastify.server.address().port + '/joi',
        body: {
          hello: 44
        },
        json: true
      }, (err, response, body) => {
        t.error(err)
        t.strictEqual(response.statusCode, 400)
        t.deepEqual(body, {
          error: 'Bad Request',
          message: 'child "hello" fails because ["hello" must be a string]',
          statusCode: 400
        })
      })
    })

    test(`${upMethod} - input-validation instance custom schema compiler encapsulated`, t => {
      t.plan(3)
      sget({
        method: upMethod,
        url: 'http://localhost:' + fastify.server.address().port + '/plugin',
        body: { },
        json: true
      }, (err, response, body) => {
        t.error(err)
        t.strictEqual(response.statusCode, 400)
        t.deepEqual(body, {
          error: 'Bad Request',
          message: 'From custom schema compiler!',
          statusCode: '400'
        })
      })
    })

    test(`${upMethod} - input-validation custom schema compiler encapsulated`, t => {
      t.plan(3)
      sget({
        method: upMethod,
        url: 'http://localhost:' + fastify.server.address().port + '/plugin/custom',
        body: { },
        json: true
      }, (err, response, body) => {
        t.error(err)
        t.strictEqual(response.statusCode, 400)
        t.deepEqual(body, {
          error: 'Bad Request',
          message: 'Always fail!',
          statusCode: '400'
        })
      })
    })
  })
}
コード例 #21
0
module.exports = (pattern, options = {}) => {
    const schemas = [{
        input: pattern,
        schema: Joi.alternatives([
            Joi.string(),
            Joi.array().items(Joi.string())
        ]),
    }, {
        input: options,
        schema: Joi.object({
            input: Joi.object({
                options: Joi.object()
            }),
            output: Joi.object({
                filename: Joi.string(),
                svg: Joi.object({
                    sizes: Joi.boolean()
                }),
                chunk: Joi.object({
                    name: Joi.string(),
                    keep: Joi.boolean()
                }),
                svg4everybody: Joi.alternatives([
                    Joi.boolean(),
                    Joi.object()
                ]),
                svgo: Joi.alternatives([
                    Joi.boolean(),
                    Joi.object()
                ])
            }),
            sprite: Joi.object({
                prefix: Joi.alternatives([
                    Joi.string(),
                    Joi.valid(false),
                    Joi.func(),
                ]),
                gutter: Joi.alternatives([
                    Joi.number(),
                    Joi.valid(false)
                ]),
                generate: Joi.object({
                    title: Joi.boolean(),
                    symbol: Joi.alternatives([
                        Joi.boolean(),
                        Joi.string()
                    ]),
                    use: Joi.boolean(),
                    view: Joi.alternatives([
                        Joi.boolean(),
                        Joi.string()
                    ])
                })
            }),
            styles: Joi.alternatives([
                Joi.boolean(),
                Joi.string(),
                Joi.object({
                    filename: Joi.string(),
                    format: Joi.string().valid('data', 'fragment'),
                    variables: Joi.object({
                        sprites: Joi.string(),
                        sizes: Joi.string(),
                        variables: Joi.string(),
                        mixin: Joi.string()
                    })
                })
            ])
        })
    }];

    schemas.forEach((schema) => {
        const validator = Joi.validate(schema.input, schema.schema, {
            abortEarly: false
        });

        if ( validator.error ) {
            throw Error(validator.error);
        }
    });
};
コード例 #22
0
<body>

    ${ content }

</body>
</html>
`;

    return html;
};

internals.measurementSchema = Joi.object({
    sid: Joi.number().integer().required(),
    value: Joi.number().required(),
    // if more measurement types are added, we have to update here and in the sql template
    type: Joi.string().required(),
    desc: Joi.string().allow([''])
});

exports.register = function (server, options, next){


    // insert measurements into a test table (client 0003)

    // http://localhost:8000/api/v1/readings?mac=aa-bb-cc&battery=294.12&data[0][sid]=1&data[0][value]=20.1&data[0][type]=t&data[0][desc]=microfone_1

    // http://spinon.ddns.net/api/v1/readings?mac=aa-bb-cc&battery=294.12&data[0][sid]=1&data[0][value]=20.1&data[0][type]=t&data[0][desc]=microfone_1
    server.route({
        path: '/api/v1/readings',
        method: 'GET',
        config: {
コード例 #23
0
describe('meta className test', function() {

    var server;

    var schema1 = Joi.object({
       _id: Joi.any().required(),
       name: Joi.string().required()
    }).meta({
       className: 'User'
    });

    var schema2 = schema1.keys({
        name: Joi.string().optional()
    })

    var schemaGet = Joi.object({
       methodGet: Joi.string().required()
    })

    var schemaPost = Joi.object({
       methodpost: Joi.string().required()
    })

    var schemaDelete = Joi.object({
       methoddelete: Joi.string().required()
    }).meta({
       className: 'deletedUser'
    });

    var routes = [
      {
        method: 'GET',
        path: '/test/one',
        handler: defaultHandler,
        config: {
          tags: ['api'],
          response: {schema : schema1}
        }
      }, {
        method: 'GET',
        path: '/test/two',
        handler: defaultHandler,
        config: {
          tags: ['api'],
          response: {schema : schema2}
        }
      }, {
        method: 'GET',
        path: '/test/method/{id}',
        handler: defaultHandler,
        config: {
          tags: ['api'],
          response: {schema : schemaGet}
        }
      }, {
        method: 'POST',
        path: '/test/method/{id}',
        handler: defaultHandler,
        config: {
          tags: ['api'],
          response: {schema : schemaPost}
        }
      }, {
        method: 'DELETE',
        path: '/test/method/{id}',
        handler: defaultHandler,
        config: {
          tags: ['api'],
          response: {schema : schemaDelete}
        }
      }
    ];



    beforeEach(function(done) {
      server = new Hapi.Server();
      server.connection({ host: 'test' });
      server.route( routes );
      server.register({register: require('../lib/index.js')}, function(err) {
        assert.ifError(err);
        done();
      });
    });

    afterEach(function(done) {
      server.stop(function() {
        server = null;
        done();
      });
    });


    it('returned meta based classname', function(done) {
      server.inject({ method: 'GET', url: '/docs?path=test '}, function (response) {
        //console.log(JSON.stringify(response.result));

        var optionCLassModel = JSON.parse(JSON.stringify(response.result.models.User));
        assert.deepEqual(optionCLassModel, {
          "id": "User",
          "type": "object",
          "properties": {
              "_id": {
                  "type": "any",
                  "required": true
              },
              "name": {
                  "type": "string",
                  "required": true
              }
          }
        });
        done();
      });
    });




    it('return a classname based on path_method', function(done) {
      server.inject({ method: 'GET', url: '/docs?path=test '}, function (response) {

        var pathMethodModel = JSON.parse(JSON.stringify(response.result.models.testmethodid_GET_response));
        //console.log(JSON.stringify(pathMethodModel));

        assert.deepEqual(pathMethodModel, {
            "id": "testmethodid_GET_response",
            "type": "object",
            "properties": {
                "methodGet": {
                    "type": "string",
                    "required": true
                }
            }
        });
        done();
      });
    });


    it('return a shortid based classname', function(done) {
      server.inject({ method: 'GET', url: '/docs?path=test '}, function (response) {

        var name = response.result.apis[4].operations[0].type;
        //console.log(name)

        var shortidModel = JSON.parse(JSON.stringify(response.result.models[name]));
        //console.log(JSON.stringify(shortidModel));

        assert.deepEqual(shortidModel, {
            "id": name,
            "type": "object",
            "properties": {
                "_id": {
                    "type": "any",
                    "required": true
                },
                "name": {
                    "type": "string",
                    "required": false
                }
            }
        });
        done();
      });
    });

});
コード例 #24
0
exports.register = function (server, options, next){


    // insert measurements into a test table (client 0003)

    // http://localhost:8000/api/v1/readings?mac=aa-bb-cc&battery=294.12&data[0][sid]=1&data[0][value]=20.1&data[0][type]=t&data[0][desc]=microfone_1

    // http://spinon.ddns.net/api/v1/readings?mac=aa-bb-cc&battery=294.12&data[0][sid]=1&data[0][value]=20.1&data[0][type]=t&data[0][desc]=microfone_1
    server.route({
        path: '/api/v1/readings',
        method: 'GET',
        config: {

            validate: {

                query: {
                    mac: Joi.string().required(),
                    battery: Joi.number(),
                    data: Joi.array().items(internals.measurementSchema).min(1).required()
                },

                options: {
                    allowUnknown: true
                }
            }

        },

        handler: function (request, reply) {

            console.log(request.query);
            //return reply("xyz");

            const mac = request.query.mac;
            request.query.data.forEach((obj) => {

                // mac is not part of the data objects
                obj.mac = mac;

                // the keys in the query string and the names of the columns in db do not match;
                // correct in the data objects
                obj.description = obj.desc;  // the column in the table is 'description'
                obj.val = obj.value;  // the column in the table is 'val'
                
                // note: the other keys in the query string match the names of the columns
            });


            const query = `
                select * from insert_measurements_test(' ${ JSON.stringify(request.query.data) } ')
            `;
            //console.log(query);

            Db.query(query)
                .then(function (result){

                    return reply({ newRecords: result.length, ts: new Date().toISOString() });
                })
                .catch(function (err){

                    Utils.logErr(err, ['api-measurements']);
                    return reply(err);
                });
        }
    });

/*
    server.route({
        path: "/api/readings",
        method: "GET",
        config: {
            handler: function(request, reply) {

                request.query.id = request.query.id || null;
                request.query.t1 = request.query.t1 || null;
                request.query.t2 = request.query.t2 || null;
                request.query.h1 = request.query.h1 || null;
                request.query.h2 = request.query.h2 || null;

                var doc = { 
                    ts: Date.now(),
                    time: new Date().toISOString(),
                    id: request.query.id,
                    t1: request.query.t1,
                    t2: request.query.t2,
                    h1: request.query.h1,
                    h2: request.query.h2,
                };

                internals.db.insert(doc, function (err, newDoc) {

                    if(err){
                        return reply(Boom.badImplementation(err));
                    }

                    return reply(newDoc);
                });
               
               
            },

            validate: {
                query: {
                    id: Joi.string(),
                    t1: Joi.number(),
                    t2: Joi.number(),
                    h1: Joi.number(),
                    h2: Joi.number(),

                }
            }

        }
    });
*/
/*
    server.route({
        path: "/show-readings",
        method: "GET",
        config: {
            handler: function(request, reply) {

                var queryConditions = {};
                var age = request.query.age;
                console.log(age)

                // ...?age=2d
                var agePeriod = age.substr(-1);                    
                if((agePeriod==='d' || agePeriod==='h') && age.length >= 2){
                    var ageValue = age.substring(0, age.length-1);

                    var timeLength;
                    if(agePeriod==='h'){
                        timeLength = Number(ageValue)*internals['oneHour']
                    }
                    else{
                        timeLength = Number(ageValue)*internals['oneDay']
                    }

                    var d = new Date(Date.now() - timeLength);
                    queryConditions['ts'] = { $gt: d.getTime() };
                }

                internals.db
                    .find(queryConditions, {_id: 0, ts: 0})
                    .sort({ 
                        "ts": request.query.sort==="asc" ? 1 : -1 
                    })
                    .exec(function (err, docs) {
                        
                        // docs = docs.map(function(doc){
                        //     return {
                        //         time: doc.time,
                        //         h1: doc.h1,
                        //         h2: doc.h2,
                        //         t1: doc.t1,
                        //         t2: doc.t2,
                        //         id: doc.id
                        //     }
                        // });

                        if(request.query.format==="json"){

                            var html = internals.getJsonHtml(JsonMarkup(docs));
                            //console.log(html);

                            return reply(html)
                         }
                        else if(request.query.format==="csv"){

                            CsvStringify(docs, {header: true}, function(err, csv){

                                return reply(csv)
                                    .code(200)
                                    .header('content-type', 'text/csv')
                                    .header('content-disposition', 'attachment; filename="spinon_readings.csv"')
                            })  
                        }
                    });
               
            },

            validate: {
                query: {
                    "order-by": Joi.any().valid("ts").default("ts"),
                    "sort": Joi.any().valid("asc", "desc").default("asc"),
                    "format": Joi.any().valid("csv", "json").default("json"),
                    "age": Joi.any()

                }
            }

        }
    });
*/
    // example: /show-readings-new?client=permalab&table=measurements   (will show records from the last 24 hours by default)
    // example: /show-readings-new?client=permalab&table=measurements&age=48
    server.route({
        path: '/show-readings-new',
        method: 'GET',
        config: {
            validate: {
                query: {
                    'client': Joi.string().required(),
                    'age': Joi.number().integer().min(1).default(24).optional(), 
                    'table': Joi.string().valid('measurements').required()
                }
            }
        },
        handler: function (request, reply) {

            const clientCode = Utils.getClientCode(request.query.client);
            if (!clientCode){
                return reply(Boom.badRequest('invalid client'));
            }

            const queryOptions = {
                clientCode: clientCode,
                age: request.query.age,
                table: request.query.table
            };

            const query = `
                select * from read_measurements(' ${ JSON.stringify(queryOptions) } ')
            `;
            console.log(query);

            Db.query(query)
                .then(function (data){

                    data.forEach((obj) => {

                        obj.ts = obj.ts.toISOString().slice(0, -5);
                    });

                    return reply(Utils.jsonMarkup(data));
                })
                .catch(function (err){

                    Utils.logErr(err, ['show-readings-new']);
                    return reply(err);
                });
        }
    });



    server.expose('nedb', internals.db);

    return next();
};
コード例 #25
0
'use strict'

const Joi = require('joi')
const { BaseJsonService } = require('..')

const schema = Joi.object({
  state: Joi.string()
    .valid('ABORTED', 'FAILED', 'FINISHED', 'PENDING', 'STARTING', 'RUNNING')
    .required(),
  grade: Joi.alternatives()
    .when('state', {
      is: 'FINISHED',
      then: Joi.string().regex(/^[ABCDEF][+-]?$/),
      otherwise: Joi.only(null),
    })
    .required(),
  score: Joi.alternatives()
    .when('state', {
      is: 'FINISHED',
      then: Joi.number()
        .integer()
        .min(0)
        .max(200),
      otherwise: Joi.only(null),
    })
    .required(),
}).required()

const queryParamSchema = Joi.object({
  publish: Joi.equal(''),
}).required()
コード例 #26
0
ファイル: cpan.js プロジェクト: RedSparr0w/shields
'use strict'

const Joi = require('joi')
const { BaseJsonService } = require('..')

const schema = Joi.object({
  version: Joi.string().required(),
  license: Joi.array()
    .items(Joi.string())
    .min(1)
    .required(),
}).required()

module.exports = class BaseCpanService extends BaseJsonService {
  async fetch({ packageName }) {
    const url = `https://fastapi.metacpan.org/v1/release/${packageName}`
    return this._requestJson({ schema, url })
  }

  static get defaultBadgeData() {
    return { label: 'cpan' }
  }
}
コード例 #27
0
ファイル: submit.js プロジェクト: wbkd/ddj-catalogue-backend
var Hapi = require('hapi');
var Joi = require('joi');
var isUri = require('isuri');
var Mailer = require('./mailer');

var urlPattern = new RegExp(/^(https?:\/\/)([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/);

var validationScheme = {
    email: Joi.string().email()
};

module.exports.submitProject = function(req, reply) {
  // TODO: check if url exists in DB

  var projectUrl = req.payload.url,
    projectDescription = req.payload.description || 'Keine Anmerkungen',
    isValidUrl = isUri.test(projectUrl);

  if(!isValidUrl){
    return reply({ error: 'Bitte geben Sie eine gültige URL an.' });
  }

  Mailer.sendProjectSubmitMail({url : projectUrl, description: projectDescription} , function(error,message){

    if(error){
      return reply(Hapi.error.badRequest('Technische Störung. Projekt konnte nicht eingereicht werden.')); 
    }

    reply({message : 'successfully submitted'});
  });
};
コード例 #28
0
ファイル: user.js プロジェクト: brave/vault
    user = await users.findOne({ userId: userId })
    if (!user) { return reply(boom.notFound('user entry does not exist: ' + userId)) }

    result = underscore.extend(underscore.omit(user, '_id', 'keychains'), { timestamp: user.timestamp.toString() })

    reply(helper.add_nonce_data(result))
  }
},

  description: 'Returns user entry information',
  notes: 'Consult <a href="https://github.com/brave/vault/wiki/Principles#globalstate">Global State Principles</a>.',
  tags: [ 'api' ],

  validate:
    { params: { userId: Joi.string().guid().required().description('the identity of the user entry') } },

  response: { schema: Joi.any() }
}

/*
   PUT /v1/users/{userId}
        create/update (entry MAY already exist)

   i'd rather this be a POST for creation and a PUT for update, instead of a PUT for upsert
   however, using a POST implies that the server generates the userId, which is contrary to "the model"
 */

v1.write =
{ handler: function (runtime) {
  return async function (request, reply) {
コード例 #29
0
ファイル: list.js プロジェクト: shrutijalewar/note-taker-1
'use strict';

var Joi = require('Joi'),
    Note = require('../../../models/note');

module.exports = {
  description: 'Show all Notes',
  tags:['notes'],
  validate: {
    params: {
      limit: Joi.string()
    }
  },
  handler: function(request, reply){
    Note.list(request.auth.credentials.id, request.params.limit || 10, function(err, result){
      reply(result);
    });
  }
};
コード例 #30
0
ファイル: pageByUser.js プロジェクト: epochtalk/epochtalk
  * @apiSuccess {string} posts.board_id The id of the board containing the post
  * @apiSuccess {string} posts.thread_title The title of the thread the post is in
  * @apiSuccess {string} posts.avatar The avatar of the user who made the post
  * @apiSuccess {object} posts.user Object containing user data about the author of the post
  * @apiSuccess {string} posts.user.id The id of the user
  *
  * @apiError (Error 500) InternalServerError There was an issue paging posts for user
  */
module.exports = {
  method: 'GET',
  path: '/api/posts/user/{username}',
  config: {
    app: { hook: 'posts.pageByUser' },
    auth: { mode: 'try', strategy: 'jwt' },
    validate: {
      params: { username: Joi.string().required() },
      query: {
        page: Joi.number().integer().min(1).default(1),
        limit: Joi.number().integer().min(1).max(100).default(25),
        desc: Joi.boolean().default(true)
      }
    },
    pre: [
      { method: 'auth.posts.pageByUser(server, auth, params.username)', assign: 'auth' },
      { method: 'hooks.preProcessing' },
      [
        { method: 'hooks.parallelProcessing', assign: 'parallelProcessed' },
        { method: processing, assign: 'processed' },
      ],
      { method: 'hooks.merge' },
      { method: 'common.posts.parseOut(parser, pre.processed.posts)' },