beforeEach(function () {
    app = loopback();
    app.set('legacyExplorer', false);
    ds = loopback.createDataSource('memory');
    Post = ds.createModel('post', {
      id: {type: Number, id: true},
      title: String,
      content: String
    });
    app.model(Post);

    Person = ds.createModel('person', {
      id: {type: Number, id: true},
      postId: Number,
      name: String
    });
    app.model(Person);
    Post.hasOne(Person, {as: 'author', foreignKey: 'postId'});
    Person.settings.plural = 'people';

    app.use(loopback.rest());
    JSONAPIComponent(app);
  });
Example #2
0
    it('should be able to override date and time format', function(done) {
      var contextOptions = {
        system: {
          datetimeFormat: 'YYYY-MM-DD@HH:mm:ssZ',
          timezoneFormat: 'ZZ' } };

      var app = loopback();
      app.use(context(contextOptions));
      app.use(function(req, resp) {
        var ctx = req.ctx;

        try {
          assert(ctx.get('system.datetime').indexOf('@') === 10);
          assert(ctx.get('system.timezone').indexOf(':') === -1);
          resp.send('done');
        } catch (error) {
          resp.send(error);
        }
      });

      request(app)
        .get('/foo')
        .expect(200, 'done', done);
    });
  beforeEach(function () {
    app = loopback()
    app.set('legacyExplorer', false)
    ds = loopback.createDataSource('memory')
    Post = ds.createModel('post', {
      id: {type: Number, id: true},
      title: String,
      content: String
    })
    app.model(Post)

    Comment = ds.createModel('comment', {
      id: {type: Number, id: true},
      postId: Number,
      title: String,
      comment: String
    })
    app.model(Comment)
    Post.hasMany(Comment, {as: 'comments', foreignKey: 'postId'})
    Comment.settings.plural = 'comments'
    Comment.belongsTo(Post, {as: 'post', foreignKey: 'postId'})
    app.use(loopback.rest())
    JSONAPIComponent(app, {restApiRoot: '/'})
  })
Example #4
0
const _ = require('lodash');
const Rx = require('rx');
const loopback = require('loopback');
const boot = require('loopback-boot');
const expressState = require('express-state');
const createDebugger = require('debug');

const { setupPassport } = require('./component-passport');

const log = createDebugger('fcc:server');
// force logger to always output
// this may be brittle
log.enabled = true;

Rx.config.longStackSupport = process.env.NODE_DEBUG !== 'production';
const app = loopback();

expressState.extend(app);
app.set('state namespace', '__fcc__');
app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(loopback.token());
app.disable('x-powered-by');

const createLogOnce = () => {
  let called = false;
  return str => {
    if (called) {
      return null;
    }
var loopback = require('loopback');
var boot = require('loopback-boot');

var client = module.exports = loopback();

// Bootstrap the application, configure models, datasources and middleware.
// Sub-apps like REST API are mounted via boot scripts.
boot(client, __dirname);
Example #6
0
describe('PROXY PLUGIN TESTS', function () {
    var app = loopback();
    var fakeServer = loopback();
    var global = {}
    var params = { target: 'http://localhost:3234', withPath: '/' }
    var pluginHandler = plugin(params, global);
    app.use(pluginHandler)
    var httpServer;
    before((done) => {
        httpServer = http
            .createServer(app)
            .listen(3232, done);
    })
    before((done) => {
        fakeServer.get('/api', function (req, res) {
            res.status(200).json({ name: 'potter' });
        });
        fakeServer.get('/fake2', function (req, res) {
            res.status(200).json({ name: 'tobi' });
        });
        fakeServer.get('/error', function (req, res) {
            res.sendStatus(500);
        });
        fakeServer.use((req, res, next) => {
            next()
        })
        fakeServer = fakeServer.listen(3234, done);
    })

    after(function () {
        fakeServer.close();
        httpServer.close();
    });

    it('should return 404 if route not found', (done) => {
        request(app)
            .get('/fake1')
            .expect(404)
            .end(done);
    });

    it('should return 200 if route found', (done) => {
        request(app)
            .get('/api')
            .expect(200)
            .end(done);
    });

    it('should return 500 like target', (done) => {
        request(app)
            .get('/error')
            .expect(500)
            .end(done);
    });

    it('should throw if target does not set', (done) => {
        params.target = undefined;
        request(app)
            .get('/fake2')
            .expect(502)
            .end(done);
    });
});
Example #7
0
  describe('System category variables', function() {
    var timeBeforeInvoke;
    var app = loopback();
    app.use(function(req, resp, next) {
      // trim the milliseconds, as the system.datetime procision is only
      // in seconds.
      timeBeforeInvoke = _.floor(Date.now(), -3);
      debug('time before context middleware - ', timeBeforeInvoke);
      next();
    });
    app.use(context());
    app.use(function(req, resp) {
      var ctxDateTime = Date.parse(req.ctx.get('system.datetime'));
      debug('get context datetime - ', ctxDateTime);

      // 1. Verify system.datetime property
      var timeAfterInvoke = Date.now();
      debug('record the time after context middleware - ', timeAfterInvoke);
      assert(_.inRange(ctxDateTime, timeBeforeInvoke, timeAfterInvoke + 1));

      // 2. Verify system.date and system.time property
      function toDateObject(date, time) {
        return new Date(date.year, date.month, date['day-of-month'],
                        time.hour, time.minute, time.seconds);
      }

      // the returned date/time is in UTC
      ctxDateTime = toDateObject(req.ctx.get('system.date'),
                                 req.ctx.get('system.time'));
      ctxDateTime = ctxDateTime.getTime();
      timeAfterInvoke = Date.now();
      assert(_.inRange(ctxDateTime, timeBeforeInvoke, timeAfterInvoke + 1));

      // 3. Verify timezone property
      var ctxTimezoneStr = req.ctx.get('system.timezone');
      var ctxTimezoneOffset = 0;
      var isBehindGMT = (ctxTimezoneStr[0] === '-');
      ctxTimezoneStr = ctxTimezoneStr.substring(1);
      ctxTimezoneStr.split(':').forEach(function(value, index) {
        if (index === 0) {
          ctxTimezoneOffset += 60 * parseInt(value, 10);
        } else {
          ctxTimezoneOffset += parseInt(value, 10);
        }
      });
      ctxTimezoneOffset = isBehindGMT ? ctxTimezoneOffset : -ctxTimezoneOffset;
      assert.equal((new Date()).getTimezoneOffset(), ctxTimezoneOffset);

      // 4. Verify system.time should contain hour, minute, and seconds
      var expectedProperties = [ 'hour', 'minute', 'seconds' ];
      expectedProperties.every(function(prop) {
        req.ctx.get('system.time').hasOwnProperty(prop);
      });

      // 5. system.date should contain day-of-week, day-of-month, month, and year
      expectedProperties = [ 'year', 'month', 'day-of-month', 'day-of-week' ];
      expectedProperties.every(function(prop) {
        req.ctx.get('system.date').hasOwnProperty(prop);
      });

      resp.send('done');
    });

    it('should produce correct date time values', function(done) {
      request(app)
        .post('/foo')
        .send('hello')
        .expect(200, 'done', done);
    });
  }); // end of System category variables test
Example #8
0
    describe('should produce req.path according to api.basepath', function() {
      var apiBasePath;
      var expectedRequestPath;
      var myapp = loopback();
      myapp.use(context());
      myapp.use(function(req, resp) {
        var ctx = req.ctx;

        // set the API basepath
        ctx.set('api.document.basePath', apiBasePath);
        ctx.set('_.api.path', req.get(API_PATH_HEADER));
        try {
          assert.strictEqual(ctx.get('request.path'), expectedRequestPath);
          resp.send('done');
        } catch (error) {
          resp.status(500).send(error);
        }
      });

      /**
       * @parameter basepath: the API basepath
       * @parameter requstPath: the URI to send
       * @parameter expect: the expected $(request.path) value
       * @parameter done: the mocha test callback
       */
      function sendRequest(basepath, apiPath, requestPath, expect, done) {
        apiBasePath = basepath;
        expectedRequestPath = expect;
        request(myapp)
          .get(requestPath)
          .set(API_PATH_HEADER, apiPath)
          .expect(200, 'done', done);
      }

      var testData = [
        // basePath is undefined in the swagger
        { base: undefined, apiPath: '/a/b', request: '/a/b', expect: '/a/b' },

        // basePath is '' in the swagger
        { base: '', apiPath: '/foo', request: '/foo', expect: '/foo' },
        { base: '', apiPath: '/foo/bar', request: '/foo/bar', expect: '/foo/bar' },

        // basePath is '/' in the swagger
        { base: '/', apiPath: '/foo', request: '/foo', expect: '/foo' },
        { base: '/', apiPath: '/foo/bar', request: '/foo/bar', expect: '/foo/bar' },
        { base: '/', apiPath: '/foo/bar', request: '/foo/bar?name=hello', expect: '/foo/bar' },

        // basePath is '/foo' in the swagger (one level)
        { base: '/foo', apiPath: '/', request: '/foo', expect: '/foo' },
        { base: '/foo', apiPath: '/', request: '/foo/', expect: '/foo/' },
        { base: '/foo', apiPath: '/bar', request: '/foo/bar', expect: '/foo/bar' },
        { base: '/foo', apiPath: '/bar/', request: '/foo/bar/', expect: '/foo/bar/' },
        { base: '/foo', apiPath: '/bar', request: '/foo/bar?=hello', expect: '/foo/bar' },

        // basePath is '/v1/test' in the swagger (two levels)
        { base: '/v1/test', apiPath: '/foo', request: '/v1/test/foo', expect: '/v1/test/foo' },

        // basePath does not start with '/' is invalid

        // basePath ends with '/'
        { base: '/v1/test/', apiPath: '/foo', request: '/v1/test/foo', expect: '/v1/test/foo' } ];

      testData.forEach(function(data) {
        it('$(request.path) should be "' + data.expect +
           '" when basepath=' + data.base +
           ' and request URI=' + data.request, function(done) {
          sendRequest(data.base, data.apiPath, data.request, data.expect, done);
        });
      });

      it('should work when api.basepath mismatch originalUrl', function(done) {
        apiBasePath = 'foot';
        request(myapp)
          .get('/foo/bar')
          .set(API_PATH_HEADER, '/bar')
          .expect(500, done);
      });
    });
Example #9
0
  describe('Request category variables', function() {
    var app = loopback();
    app.use(context());
    app.use(function(req, resp) {
      var ctx = req.ctx;

      ctx.set('api.document.basePath', '');
      ctx.set('_.api.path', req.get(API_PATH_HEADER));

      var result = {
        verb: ctx.get('request.verb'),
        uri: ctx.get('request.uri'),
        path: ctx.get('request.path'),
        search: ctx.get('request.search'),
        querystring: ctx.get('request.querystring'),
        headers: ctx.get('request.headers'),
        'content-type': ctx.get('request.content-type'),
        authorization: ctx.get('request.authorization') };

      // the '.' notation should also work the same as getter
      assert.strictEqual(ctx.request.verb, ctx.get('request.verb'));
      assert.strictEqual(ctx.request.uri, ctx.get('request.uri'));
      assert.strictEqual(ctx.request.path, ctx.get('request.path'));
      assert.strictEqual(ctx.request.search, ctx.get('request.search'));
      assert.strictEqual(ctx.request.querystring, ctx.get('request.querystring'));
      assert(_.isEqual(ctx.request.headers, ctx.get('request.headers')));
      assert.strictEqual(ctx.request['content-type'],
                         ctx.get('request.content-type'));
      assert.strictEqual(ctx.request.authorization,
                         ctx.get('request.authorization'));

      resp.send(result);
    });

    function verifyResponse(res, expected) {
      var variables = [ 'verb', 'path', 'search', 'querystring',
        'content-type', 'authorization' ];
      variables.forEach(function(value) {
        assert.strictEqual(res.body[value], expected[value],
                           'request.' + value);
      });

      // verify the uri
      var url = urlParser.parse(res.body.uri);
      assert.ok(url.protocol, 'should have protocol');
      assert.ok(url.hostname, 'should have hostname');
      assert.strictEqual(url.search ? url.pathname + url.search : url.pathname,
                         expected.uri);

      // remove the headers not in testing scope
      var headers = res.body.headers;
      var removeHeader = [ 'accept-encoding',
        'connection',
        'content-length',
        'content-type',
        'host',
        'user-agent',
        API_PATH_HEADER.toLowerCase() ];
      removeHeader.forEach(function(value) {
        delete headers[value];
      });

      assert(_.isEqual(headers, expected.headers));
    }

    it('should support "HTTP GET /"', function(done) {
      var expect = {
        verb: 'GET',
        uri: '/',
        path: '/',
        search: '',
        querystring: '',
        'content-type': undefined,
        authorization: undefined,
        headers: {} };
      request(app)
        .get('/')
        .set(API_PATH_HEADER, '/')
        .expect(function(res) {
          verifyResponse(res, expect);
        })
        .end(done);
    });

    it('should support "HTTP GET /x/y/z"', function(done) {
      var expect = {
        verb: 'GET',
        uri: '/x/y/z',
        path: '/x/y/z',
        search: '',
        querystring: '',
        'content-type': undefined,
        authorization: undefined,
        headers: {} };
      request(app)
        .get('/x/y/z')
        .set(API_PATH_HEADER, '/x/y/z')
        .expect(function(res) {
          verifyResponse(res, expect);
        })
        .end(done);
    });

    it('should support "HTTP GET /foo/bar?param1=1&param2=2"', function(done) {
      var expect = {
        verb: 'GET',
        uri: '/foo/bar?param1=1&param2=2',
        path: '/foo/bar',
        search: '?param1=1&param2=2',
        querystring: 'param1=1&param2=2',
        'content-type': undefined,
        authorization: undefined,
        headers: {} };
      request(app)
        .get('/foo/bar?param1=1&param2=2')
        .set(API_PATH_HEADER, '/foo/bar')
        .expect(function(res) {
          verifyResponse(res, expect);
        })
        .end(done);
    });

    it('should support "HTTP GET with headers"', function(done) {
      var expect = {
        verb: 'GET',
        uri: '/foo/bar?param1=1&param2=2',
        path: '/foo/bar',
        search: '?param1=1&param2=2',
        querystring: 'param1=1&param2=2',
        'content-type': undefined,
        authorization: undefined,
        headers: {
          'x-api-gateway': 'foo' } };
      request(app)
        .get('/foo/bar?param1=1&param2=2')
        .set(expect.headers)
        .set(API_PATH_HEADER, '/foo/bar')
        .expect(function(res) {
          verifyResponse(res, expect);
        })
        .end(done);
    });

    it('should support "HTTP POST /foo?x=1"', function(done) {
      var expect = {
        verb: 'POST',
        uri: '/foo?x=1',
        path: '/foo',
        search: '?x=1',
        querystring: 'x=1',
        'content-type': 'application/json',
        authorization: undefined,
        headers: {} };
      request(app)
        .post('/foo?x=1')
        .set(API_PATH_HEADER, '/foo')
        .send({ message: 'Hello World' })
        .expect(function(res) {
          verifyResponse(res, expect);
        })
        .end(done);
    });

    describe('should produce request.date variable', function() {
      it('value should be between client sends/receives request',
         function(done) {
           var myapp = loopback();
           myapp.use(context());
           myapp.use(function(req, resp) {
             resp.send({ 'request.date': req.ctx.get('request.date').getTime() });
           });

           var timeBeforeInvoke = Date.now();
           request(myapp)
             .get('/')
             .expect(function(res) {
               var timeAfterInvoke = Date.now();
               assert(_.inRange(res.body['request.date'],
                                timeBeforeInvoke, timeAfterInvoke + 1));
             })
             .end(done);
         });
    });

    describe('should normalize HTTP content-type', function() {
      var removeContentTypeURL = '/remove-content-type';
      var myapp = loopback();
      myapp.use(function(req, resp, next) {
        if (req.originalUrl === removeContentTypeURL) {
          req.headers['content-type'] = undefined;
        }
        next();
      });
      myapp.use(context());
      myapp.use(function(req, resp) {
        var ctx = req.ctx;
        resp.send(ctx.get('request.content-type'));
      });

      var origTypes = [
        'application/json',
        'application/vcard+json',
        'text/javascript',
        'application/javascript',
        'application/xml',
        'application/soap+xml',
        'text/xml' ];
      var normalizedTypes = [
        'application/json',
        'application/json',
        'application/json',
        'application/json',
        'application/xml',
        'application/xml',
        'application/xml' ];
      var payload = [
        { hello: 'world' },
        JSON.stringify({ hello: 'world' }),
        '"use strict;"',
        '"use strict;"',
        '<?xml version="1.0"?><hello/>',
        '<?xml version="1.0"?><hello/>',
        '<?xml version="1.0"?><hello/>' ];

      origTypes.forEach(function(type, index) {
        it('should normalize ' + type + ' to ' + normalizedTypes[index],
           function(done) {
             request(myapp)
               .post('/foo')
               .set('content-type', type)
               .send(payload[index])
               .expect(200, normalizedTypes[index], done);
           });
      });

      it('should not normalize application/octet-stream', function(done) {
        var type = 'application/octet-stream';
        request(myapp)
          .post('/foo')
          .set('content-type', type)
          .send(new Buffer([ 0x01, 0x02 ]))
          .expect(200, type, done);
      });

      it('should not normalized undefined/empty content type', function(done) {
        request(myapp)
          .post(removeContentTypeURL)
          .set('content-type', '')
          .send(new Buffer([ 0x01, 0x02 ]))
          .expect(200, '', done); // when res.send(undefined), '' is received
      });
    }); // end of 'should normalize HTTP content-type' test

    describe('should produce req.path according to api.basepath', function() {
      var apiBasePath;
      var expectedRequestPath;
      var myapp = loopback();
      myapp.use(context());
      myapp.use(function(req, resp) {
        var ctx = req.ctx;

        // set the API basepath
        ctx.set('api.document.basePath', apiBasePath);
        ctx.set('_.api.path', req.get(API_PATH_HEADER));
        try {
          assert.strictEqual(ctx.get('request.path'), expectedRequestPath);
          resp.send('done');
        } catch (error) {
          resp.status(500).send(error);
        }
      });

      /**
       * @parameter basepath: the API basepath
       * @parameter requstPath: the URI to send
       * @parameter expect: the expected $(request.path) value
       * @parameter done: the mocha test callback
       */
      function sendRequest(basepath, apiPath, requestPath, expect, done) {
        apiBasePath = basepath;
        expectedRequestPath = expect;
        request(myapp)
          .get(requestPath)
          .set(API_PATH_HEADER, apiPath)
          .expect(200, 'done', done);
      }

      var testData = [
        // basePath is undefined in the swagger
        { base: undefined, apiPath: '/a/b', request: '/a/b', expect: '/a/b' },

        // basePath is '' in the swagger
        { base: '', apiPath: '/foo', request: '/foo', expect: '/foo' },
        { base: '', apiPath: '/foo/bar', request: '/foo/bar', expect: '/foo/bar' },

        // basePath is '/' in the swagger
        { base: '/', apiPath: '/foo', request: '/foo', expect: '/foo' },
        { base: '/', apiPath: '/foo/bar', request: '/foo/bar', expect: '/foo/bar' },
        { base: '/', apiPath: '/foo/bar', request: '/foo/bar?name=hello', expect: '/foo/bar' },

        // basePath is '/foo' in the swagger (one level)
        { base: '/foo', apiPath: '/', request: '/foo', expect: '/foo' },
        { base: '/foo', apiPath: '/', request: '/foo/', expect: '/foo/' },
        { base: '/foo', apiPath: '/bar', request: '/foo/bar', expect: '/foo/bar' },
        { base: '/foo', apiPath: '/bar/', request: '/foo/bar/', expect: '/foo/bar/' },
        { base: '/foo', apiPath: '/bar', request: '/foo/bar?=hello', expect: '/foo/bar' },

        // basePath is '/v1/test' in the swagger (two levels)
        { base: '/v1/test', apiPath: '/foo', request: '/v1/test/foo', expect: '/v1/test/foo' },

        // basePath does not start with '/' is invalid

        // basePath ends with '/'
        { base: '/v1/test/', apiPath: '/foo', request: '/v1/test/foo', expect: '/v1/test/foo' } ];

      testData.forEach(function(data) {
        it('$(request.path) should be "' + data.expect +
           '" when basepath=' + data.base +
           ' and request URI=' + data.request, function(done) {
          sendRequest(data.base, data.apiPath, data.request, data.expect, done);
        });
      });

      it('should work when api.basepath mismatch originalUrl', function(done) {
        apiBasePath = 'foot';
        request(myapp)
          .get('/foo/bar')
          .set(API_PATH_HEADER, '/bar')
          .expect(500, done);
      });
    });

    describe('should parse HTTP authorization header', function() {
      var myapp = loopback();
      myapp.use(context());
      myapp.use(function(req, resp) {
        var ctx = req.ctx;
        if (ctx.get('request.authorization')) {
          resp.json(ctx.get('request.authorization'));
        } else {
          resp.send('');
        }
      });

      it('should parse basic auth header', function(done) {
        var username = '******';
        var password = '******';
        var encoded = (new Buffer(username + ':' + password))
            .toString('base64');

        request(myapp)
          .get('/')
          .auth(username, password)
          .expect(200, {
            scheme: 'Basic',
            params: [],
            token: encoded }, done);
      });

      it('should return undefined when no auth header', function(done) {
        request(myapp)
          .get('/')
          .expect(200, '', done);
      });
    }); // end of should parse HTTP authorization header test

    describe('should reject/ignore non-empty payload when needed', function() {
      var app = loopback();
      app.use(function(req, resp, next) {
        // Because unable to find a node module that can send payload with
        // GET, HEAD, and DELETE methods, use this middleware to override
        // the HTTP method name
        req.method = req.get('X-METHOD-NAME') || req.method;
        next();
      });
      app.use(context());
      app.use(function(req, resp) {
        debug('get context content');
        var ctx = req.ctx;
        resp.send({
          type: typeof ctx.get('request.body'),
          body: ctx.get('request.body').toString() });
      });
      app.use(function(error, req, resp, next) {
        debug('receive error: ', error);
        resp.status(500).json(error);
      });

      it('should ignore OPTIONS method w/ payload', function(done) {
        request(app)
          .options('/foo')
          .type('text')
          .send('hello world')
          .expect(200, { type: 'object', body: '' }, done);
      });

      [ 'GET', 'HEAD', 'DELETE' ].forEach(function(method) {
        // microgateway issue #4: should not reject a GET request with payload
        it.skip('should reject ' + method + ' method w/ payload', function(done) {
          request(app)
            .post('/foo')
            .set('X-METHOD-NAME', method)
            .type('text')
            .send('hello world')
            .expect(function(res) {
              assert.strictEqual(res.status, 500);
              // verify the error is rewritten
              delete res.body.name;
              delete res.body.message;
              assert(_.isEmpty(res.body));
            })
            .end(done);
        });
      });
    }); // end of 'should reject/ignore non-empty payload when needed' test
  }); // end of 'Request category variables test
Example #10
0
'use strict';

const http = require('http');
const loopback = require('loopback');
const boot = require('loopback-boot');

const app = module.exports = loopback();

// Attach Tree mixin
require(__dirname + '/../../../..')(app);

// Once the application bootstrapped
app.start = () => {
  // Mount API REST
  app.use(app.get('restApiRoot'), loopback.rest());
  // Start the web server
  const server = http.createServer(app);
  server.listen(app.get('port'), () => {
    app.emit('started');
  });
};
// Bootstrap the application, configure models, datasources and middleware.
boot(app, __dirname, (err) => {
  if (err) throw err;
  app.start();
});
Example #11
0
 return function(done) {
   var app = this.app = loopback();
   configureRestApiAndExplorer(app, restUrlBase);
   done();
 };
 before('setup loopback and configurator', function() {
   app = loopback();
   passportConfigurator = new PassportConfigurator(app);
 });
  return function(done) {
    var app = this.app = loopback({localRegistry: true, loadBuiltinModels : true});

    var customerProperties = {
      name: {type: String, required: true}
    };
    var customerOptions = {
      "relations": {
          "address": {
            "type": "embedsOne",
            "model": "Address",
            "property": "billingAddress",
            "options": {
              "validate": true,
              "forceId": false
            }
          }
      }
    }



    var addressProperties = {
      street: {type: String, required: true},
      city: {type: String, required: true},
      state: {type: String, required: true}
    };

    var Address = loopback.Model.extend('Address', addressProperties);

    app.model(Address);

    var BillingAddress = loopback.Model.extend('BillingAddress', addressProperties);

    app.model(BillingAddress);

    var OfficeAddress = loopback.Model.extend('OfficeAddress', addressProperties);

    app.model(OfficeAddress);

    var bookProperties = {
      name: {type: String, required: true}
    };

    var Book = loopback.Model.extend('Book', bookProperties);

    app.model(Book);

    var Address = loopback.Model.extend('Address', addressProperties);

    app.model(Address);

    var Address = loopback.Model.extend('Address', addressProperties);

    app.model(Address);

    var Customer = loopback.Model.extend('Customer', customerProperties, customerOptions);

    Customer.greet = function(msg, cb) {
      cb(null, 'Greetings... ' + msg);
    }

    Customer.remoteMethod(
        'greet',
        {
          accepts: {arg: 'msg', type: 'string'},
          returns: {arg: 'greeting', type: 'string'}
        }
    );

    app.model(Customer);

    visualize(app);
    app.use(app.get('restApiRoot') || '/', loopback.rest());
    done();
  };
Example #14
0
File: main.js Project: bot-b/CMS
var express = require("express"),
  session = require("express-session"),
  uuid = require("node-uuid"),
  path = require("path"),
  cors = require("cors"),
  shovelapps = require("./lib/shovelapps"),
  loopback = require("loopback");

// Using loopback I override the 
// previous server var that was 
// instantiated with express();
// loppback() returns an express() instance on steroids.
server = loopback();

server.enableAuth();

// set the view engine to ejs
server.set('view engine', 'ejs');

// Allow cross-domain requests
server.use(cors());
// Session 
server.use(session({
  genid: function(req) {
    return uuid.v1(); // use UUIDs for session IDs
  },
  secret: 'shovelapps',
  resave: true,
  saveUninitialized: true
}));
 before('set up loopback app', function() {
   app = loopback();
 });
masterApp.post('/setup', function(req, res, next) {
  var opts = req.body;
  var name = opts.name;
  var models = opts.models;
  var enableAuth = opts.enableAuth;
  var setupFn = compileSetupFn(name, opts.setupFn);

  if (!name)
    return next(new Error('"name" is a required parameter'));

  if (!models || typeof models !== 'object')
    return next(new Error('"models" must be a valid object'));

  // hack: clear the static model registry populated by previous test apps
  loopback.Model.modelBuilder.models = extend({}, initialModels);
  loopback.Model.modelBuilder.definitions = extend({}, initialDefinitions);

  lbApp = loopback();

  lbApp.dataSource('db', { connector: 'memory' });

  for (var m in models) {
    var model = null;
    var options = models[m].options || {};
    if (initialModels[m]) {
      model = initialModels[m];
      lbApp.model(model, extend({ dataSource: 'db' }, options));
    } else {
      model = lbApp.registry.createModel(
        m,
        models[m].properties || {},
        options
      );
      lbApp.model(model, { dataSource: 'db' });
    }
  }

  if (enableAuth)
    lbApp.enableAuth({ dataSource: 'db' });

  lbApp.set('restApiRoot', '/');
  lbApp.use(lbApp.get('restApiRoot'), loopback.rest());

  setupFn(lbApp, function(err, data) {
    if (err) {
      console.error('app setup function failed', err);
      res.send(500, err);
      return;
    }
    try {
      servicesScript = generateService(generator, lbApp, apiUrl, opts);
    } catch (err) {
      console.error('Cannot generate services script:', err.stack);
      servicesScript = 'throw new Error("Error generating services script.");';
    }

    servicesScript += '\nangular.module(' + JSON.stringify(name) + ')' +
      '.value("testData", ' + JSON.stringify(data, null, 2) + ');\n';

    res.send(200, { servicesUrl: baseUrl + 'services?' + name });
  }.bind(this));
});
Example #17
0
import loopback from 'loopback';
import boot from 'loopback-boot';
import ips from 'loopback-ds-ips-mixin';
import timestamp from 'loopback-ds-timestamp-mixin';
import readonly from 'loopback-ds-readonly-mixin';

import setupPassport from './passport';
import log from './utils/logger';
import { printBanner } from './utils/print-logo';

let app = loopback();

ips(app);
timestamp(app);
readonly(app);

app.use(loopback.compress());
app.use(loopback.context());

// Bootstrap the application, configure models, datasources and middleware.
// Sub-apps like REST API are mounted via boot scripts.
boot(app, __dirname);

setupPassport(app);

app.start = () => app.listen(() => {
  app.emit('started');
  printBanner();
  log.info('Web server listening at: %s', app.get('url'));
});
Example #18
0
import loopback from 'loopback'
import boot from 'loopback-boot'

let server = loopback()
boot(server, __dirname)

server.listen()

export default server
Example #19
0
  beforeEach(function() {
    app = loopback();

    // process.bootFlags is used by simple-app/boot/*.js scripts
    process.bootFlags = [];
  });
Example #20
0
module.exports = function(options) {
  options = options || {};

  var app = options.app;
  if (!app || !app.use) {
    app = loopback();
  }
  options.app = app;

  app.httpServer = options.server;
  app.set('view engine', 'ejs');
  app.set('json spaces', 2);
  app.set('trust proxy', 1);
  app.set('views', path.resolve(__dirname, 'views'));

  require('loopback-datatype-objectid')(app);

  return {
    locals: options,
    init: function() {
      app.client = options.client;
      app.web = options.web || app.client;
      app.paths = options.paths;
      require('./lib')(app, options);
      return Promise.resolve();
    },
    start: function() {
      if (options.building) {
        return;
      }

      var modelConfig = {
        models: app.configurator.load('model-config'),
        modelDefinitions: [],
        _definitions: {}
      };

      require('./lib/form')(app);
      require('./lib/finder')(app);
      require('./lib/edit')(app);

      return Promise.resolve()
        .then(function() {
          return modelGenerator(app, modelConfig);
        })
        .then(function() {
          return modelDefinitions(app, modelConfig);
        })
        .then(function() {
          app.modelConfig = modelConfig.models;
          return new Promise(function(resolve, reject) {
            var middleware = app.configurator.load('middleware', true);
            //console.log(modelConfig.modelDefinitions);

            var bootDirs = app.get('services_include').map(function(dir) {
              return path.join(dir, 'boot');
            });

            var bootOptions = {
              appRootDir: __dirname,
              models: modelConfig.models,
              modelDefinitions: modelConfig.modelDefinitions,
              middleware: middleware,
              dataSources: app.configurator.load('datasources'),
              bootDirs: bootDirs
            };

            boot(app, bootOptions, function(err) {
              if (err) {
                reject(err);
                return;
              }
              app.models().forEach(function(model) {
                disableAllMethods(model);
              });
              app.indexes.updateDatasources(['db', 'db_prd']);
              app.emit('booted');
              resolve();
            });
          });
        });
    }
  };
};
Example #21
0
import loopback from 'loopback'
import boot from 'loopback-boot'

let client = loopback()
boot(client)

export default client
Example #22
0
var async = require('async');
var _ = require('lodash');
var options = {
  appRootDir: __dirname,
  appConfigRootDir: __dirname,
  modelsRootDir: __dirname,
  dsRootDir: __dirname,
  mixinDirs: [],
  bootDirs: [],
  clientAppRootDir: '',
  skipConfigurePassport: false
}
options.bootDirs.push(path.join(__dirname, 'boot'));
module.exports.options = options;

var app = module.exports.loopback = loopback();
//preboot.injectOptions();

app.locals.apphome = __dirname;
app.start = function () {
  // start the web server
  return app.listen(function () {
    app.emit('started');
    var baseUrl = app.get('url').replace(/\/$/, '');
    console.log('Web server listening at: %s', baseUrl);
    if (app.get('loopback-component-explorer')) {
      var explorerPath = app.get('loopback-component-explorer').mountPath;
      console.log('Browse your REST API at %s%s', baseUrl, explorerPath);
    }
  });
};
Example #23
0
    describe('should normalize HTTP content-type', function() {
      var removeContentTypeURL = '/remove-content-type';
      var myapp = loopback();
      myapp.use(function(req, resp, next) {
        if (req.originalUrl === removeContentTypeURL) {
          req.headers['content-type'] = undefined;
        }
        next();
      });
      myapp.use(context());
      myapp.use(function(req, resp) {
        var ctx = req.ctx;
        resp.send(ctx.get('request.content-type'));
      });

      var origTypes = [
        'application/json',
        'application/vcard+json',
        'text/javascript',
        'application/javascript',
        'application/xml',
        'application/soap+xml',
        'text/xml' ];
      var normalizedTypes = [
        'application/json',
        'application/json',
        'application/json',
        'application/json',
        'application/xml',
        'application/xml',
        'application/xml' ];
      var payload = [
        { hello: 'world' },
        JSON.stringify({ hello: 'world' }),
        '"use strict;"',
        '"use strict;"',
        '<?xml version="1.0"?><hello/>',
        '<?xml version="1.0"?><hello/>',
        '<?xml version="1.0"?><hello/>' ];

      origTypes.forEach(function(type, index) {
        it('should normalize ' + type + ' to ' + normalizedTypes[index],
           function(done) {
             request(myapp)
               .post('/foo')
               .set('content-type', type)
               .send(payload[index])
               .expect(200, normalizedTypes[index], done);
           });
      });

      it('should not normalize application/octet-stream', function(done) {
        var type = 'application/octet-stream';
        request(myapp)
          .post('/foo')
          .set('content-type', type)
          .send(new Buffer([ 0x01, 0x02 ]))
          .expect(200, type, done);
      });

      it('should not normalized undefined/empty content type', function(done) {
        request(myapp)
          .post(removeContentTypeURL)
          .set('content-type', '')
          .send(new Buffer([ 0x01, 0x02 ]))
          .expect(200, '', done); // when res.send(undefined), '' is received
      });
    }); // end of 'should normalize HTTP content-type' test
Example #24
0
    uuid = require('node-uuid'),
    assign = require('lodash').assign,
    loopback = require('loopback'),
    boot = require('loopback-boot'),
    expressState = require('express-state'),
    path = require('path'),
    passportProviders = require('./passport-providers');

var setProfileFromGithub = require('./utils/auth').setProfileFromGithub;
var getSocialProvider = require('./utils/auth').getSocialProvider;
var getUsernameFromProvider = require('./utils/auth').getUsernameFromProvider;
var generateKey =
  require('loopback-component-passport/lib/models/utils').generateKey;

var isBeta = !!process.env.BETA;
var app = loopback();

expressState.extend(app);
app.set('state namespace', '__fcc__');

var PassportConfigurator =
  require('loopback-component-passport').PassportConfigurator;
var passportConfigurator = new PassportConfigurator(app);

app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(loopback.token());
app.disable('x-powered-by');

// adds passport initialization after session middleware phase is complete
Example #25
0
    describe('should contain headers properties', function() {
      var app = loopback();
      app.use(context());
      app.use(function(req, resp) {
        var ctx = req.ctx;

        // message.headers should be equal to request.headers
        function normalizeMessageHeaders() {
          var lowerCaseMessageHeaders = {};
          Object.getOwnPropertyNames(ctx.get('message.headers')).forEach(function(name) {
            lowerCaseMessageHeaders[name.toLowerCase()] = ctx.get('message.headers')[name];
          });
          return lowerCaseMessageHeaders;
        }

        assert(_.isEqual(normalizeMessageHeaders(),
                         ctx.get('request.headers')));

        // set additional headers. Header should be writable
        var headers = ctx.get('message.headers');
        headers['foo'] = 'bar';

        assert.strictEqual(ctx.get('message.headers').foo, 'bar');

        // modify message.headers should not change request.header
        assert(!_.isEqual(normalizeMessageHeaders(),
                          ctx.get('request.headers')));

        resp.send('done');
      });

      it('should work with HTTP GET method', function(done) {
        request(app)
          .get('/foo')
          .set('X-GATEWAY-FOO', 'bar')
          .set('DATE', new Date())
          .expect(200, 'done', done);
      });

      it('should work with HTTP POST method w/ JSON data', function(done) {
        var payload = { foo: 'bar' };
        request(app)
          .post('/foo')
          .set('content-type', 'application/json')
          .send(payload)
          .expect(200, 'done', done);
      });

      it('should work with HTTP POST method w/ TEXT data', function(done) {
        var payload = 'plain text';
        request(app)
          .post('/foo')
          .set('content-type', 'text/plain')
          .send(payload)
          .expect(200, 'done', done);
      });

      it('should work with HTTP POST method w/ TEXT data and JSON content-type',
         function(done) {
           var payload = 'plain text';
           request(app)
             .post('/foo')
             .set('content-type', 'application/json')
             .send(payload)
             .expect(200, 'done', done);
         });

      it('should work with HTTP POST method w/ BINARY data', function(done) {
        var payload = 'raw data';
        request(app)
          .post('/foo')
          .set('content-type', 'binary/octet-stream')
          .send(payload)
          .expect(200, 'done', done);
      });
    }); // end of 'should contain headers and body properties' test
// dependencies
var path = require('path');
var loopback = require('loopback');
var explorer = require('loopback-explorer');
var CONFIG = require('global.config');
var LOCAL_CONFIG = require('local.config');

// server
var server = module.exports = loopback();

// data source
// var db = loopback.createDataSource(LOCAL_CONFIG.db);
var db = loopback.createDataSource({
  connector: require('loopback-connector-mongodb'),
  database: 'todo-example'
});

// models
var User = require('models/user');
var Todo = require('models/todo');

// setup the model data sources
User.attachTo(db);
Todo.attachTo(db);
server.model(User);
server.model(Todo);

// TODO(ritch) this should be unecessary soon....
server.model(Todo.getChangeModel());

// root api path
 beforeEach(function() {
   app = loopback();
 });
Example #28
0
/**
 * Factory method that returns a loopback server object. This object can be used
 * as express middleware.
 *
 * @param {ServiceManager} serviceManager
 * @param {Minkelite} minkelite instance for tracing
 * @param {object} options Options object
 */
function server(serviceManager, minkelite, options) {
  var app = loopback();
  app.serviceManager = serviceManager;
  options = options || {};

  var duration1Day = 24 * 60 * 60 * 1000;
  options['ExpressUsageRecord.deleteWindow'] =
    options['ExpressUsageRecord.deleteWindow'] || String(duration1Day);

  for (var k in options) {
    if (!options.hasOwnProperty(k)) continue;
    app.set(k, options[k]);
  }

  var config;
  app.minkelite = minkelite;
  if (options.db) {
    app.dataSource('db', options.db);
  } else if (process.env.STRONGLOOP_MESH_DB) {
    // For backward compatibility with old way of specifying connection info
    // via environment variable.
    var dbUrl = url.parse(process.env.STRONGLOOP_MESH_DB || 'memory://');
    debug('Datasource URI: %j', dbUrl);

    config = {
      name: 'db',
      host: dbUrl.hostname,
      port: dbUrl.port,
      connector: dbUrl.protocol.slice(0, -1),
    };
    if (dbUrl.path) config.file = dbUrl.path;

    debug('Datasource config: %j', config);
    app.dataSource('db', config);
  } else {
    config = {connector: 'memory'};
    if (options.dbFilePath) config.file = options.dbFilePath;
    app.dataSource('db', config);
  }

  // Bootstrap the application, configure models, datasources and middleware.
  // Sub-apps like REST API are mounted via boot scripts.
  boot(app, __dirname);

  app.start = function(callback) {
    app.dataSources.db.autoupdate(function(err) {
      if (err) return callback(err);

      // start the web server
      app._server = app.listen(function() {
        var addr = this.address();
        app.emit('started', addr.port);
        console.log('Web server listening at port: %s', addr.port);
        if (callback) return callback(null, addr.port);
      });
    });
  };

  app.stop = function(callback) {
    if (this.minkelite)
      this.minkelite.shutdown();

    if (!this._server) {
      return cb();
    }
    this._server.close(cb);

    function cb() {
      app.emit('stopped');
      if (callback) callback();
    }
  };

  app.useDbWatcher = function(dbWatcher, callback) {
    var ServerService = app.models.ServerService;
    var ServiceInstance = app.models.ServiceInstance;
    var Executor = app.models.Executor;
    var Gateway = app.models.Gateway;

    async.parallel([
      ServerService.useDbWatcher.bind(null, dbWatcher),
      ServiceInstance.useDbWatcher.bind(null, dbWatcher),
      Executor.useDbWatcher.bind(null, dbWatcher),
      Gateway.useDbWatcher.bind(null, dbWatcher),
    ], callback);
  };

  app.handleModelUpdate = function(instanceId, uInfo, callback) {
    // These are all currently notifications, so callback is optional and unused
    // However, the unit tests need to know when models have been updated, so
    // take care to not callback until any actions are complete.
    if (!callback) {
      callback = assert.ifError;
    }

    var AgentTrace = app.models.AgentTrace;
    var ExpressUsageRecord = app.models.ExpressUsageRecord;
    var ProfileData = app.models.ProfileData;
    var ServiceInstance = app.models.ServiceInstance;
    var ServiceMetric = app.models.ServiceMetric;
    var ServiceProcess = app.models.ServiceProcess;

    switch (uInfo.cmd) {
      case 'started':
        // Note carefully that strong-pm doesn't actually pass the started cmd
        // directly, it first annotates it with a bunch of extra information.
        ServiceInstance.recordInstanceInfo(instanceId, uInfo, function(err) {
          if (err) return callback(err);
          ServiceProcess.recordFork(instanceId, uInfo, callback);
        });
        break;
      case 'fork':
        ServiceProcess.recordFork(instanceId, uInfo, callback);
        break;
      case 'exit':
        ServiceProcess.recordExit(instanceId, uInfo, callback);
        break;
      case 'listening':
        ServiceProcess.recordListeningEndpoint(instanceId, uInfo, callback);
        break;
      case 'object-tracking':
      case 'cpu-profiling':
      case 'heap-snapshot':
        ServiceProcess.recordProfilingState(instanceId, uInfo, callback);
        break;
      case 'status':
        ServiceInstance.recordStatusUpdate(instanceId, uInfo, callback);
        break;
      case 'metrics':
        ServiceMetric.recordMetrics(instanceId, uInfo, callback);
        break;
      case 'agent:trace':
        AgentTrace.recordTrace(instanceId, uInfo, callback);
        break;
      case 'trace:object':
        if (!app.minkelite)
          return callback();
        var record = JSON.parse(uInfo.record);
        app.minkelite.postRawPieces(record.version,
          record.packet.metadata.account_key,
          record.packet,
          callback);
        break;
      case 'express:usage-record':
        ExpressUsageRecord.recordUsage(instanceId, uInfo, callback);
        break;
      case 'cpu:profile-data':
        ProfileData.recordProfileData(instanceId, uInfo, callback);
        break;
      case 'status:wd':
        ServiceProcess.recordStatusWdUpdate(instanceId, uInfo, function(err) {
          if (err) return callback(err);

          // Work around for versions of supervisor which dont include appName
          // in status:wd message
          if (!uInfo.appName) {
            return process.nextTick(callback);
          }

          ServiceInstance.recordStatusWdUpdate(instanceId, uInfo, callback);
        });
        break;
      case 'debugger-status':
        ServiceProcess.recordDebuggerStatusUpdate(instanceId, uInfo, callback);
        break;
      default:
        debug('Unknown request: %j', uInfo);
        callback();
        break;
    }
  };

  app.setServiceCommit = function(serviceId, commit, callback) {
    var ServerService = app.models.ServerService;
    ServerService.setServiceCommit(serviceId, commit, callback);
  };

  return app;
}
var loopback = require('loopback'),
  boot = require('loopback-boot'),
  app = module.exports = loopback(),
  discoverApi = require('./discovery-and-build.js');

app.start = function() {
  // start the web server
  return app.listen(function() {
    app.emit('started');
    var baseUrl = app.get('url').replace(/\/$/, '');
    console.log('Web server listening at: %s', baseUrl);
    if (app.get('loopback-component-explorer')) {
      var explorerPath = app.get('loopback-component-explorer').mountPath;
      console.log('Browse your REST API at %s%s', baseUrl, explorerPath);
    }
  });
};
// discoverApi.discoverAndBuid(app);
// Bootstrap the application, configure models, datasources and middleware.
// Sub-apps like REST API are mounted via boot scripts.
discoverApi.discoverAndBuid(app).then(function() {
  boot(app, __dirname, function(err) {
    if (err) throw err;

    // start the server if `$ node server.js`
    // discoverApi.discoverAndBuid(app).then(function() {
    if (require.main === module) {
      app.start();
    }
    // });
  });
Example #30
0
var loopback = require('loopback');
var boot = require('loopback-boot');
var mcflyLoopback = require('mcfly-loopback');
mcflyLoopback.registerModels(loopback, 'rethinkdbdash');
var app = module.exports = loopback();


var app = module.exports = loopback();

app.start = function() {
    // start the web server
    return app.listen(function() {
        app.emit('started');
        console.log('Web server listening at: %s', app.get('url'));
    });
};

// Bootstrap the application, configure models, datasources and middleware.
// Sub-apps like REST API are mounted via boot scripts.
boot(app, __dirname, function(err) {
    if (err) throw err;

    // start the server if `$ node server.js`
    if (require.main === module)
        app.start();
});