UNPKG

@gluestack-v2/glue-plugin-service-gateway

Version:

Gluestack V2 service Gateway Plugin

199 lines (170 loc) 7.7 kB
'use strict'; const ApiGateway = require('moleculer-web'); const cors = require('cors'); var multiparty = require('multiparty'); /** * @typedef {import('moleculer').ServiceSchema} ServiceSchema Moleculer's Service Schema * @typedef {import('moleculer').Context} Context Moleculer's Context * @typedef {import('http').IncomingMessage} IncomingRequest Incoming HTTP Request * @typedef {import('http').ServerResponse} ServerResponse HTTP Server Response * @typedef {import('moleculer-web').ApiSettingsSchema} ApiSettingsSchema API Setting Schema */ module.exports = { name: 'api', mixins: [ApiGateway], /** @type {ApiSettingsSchema} More info about settings: https://moleculer.services/docs/0.14/moleculer-web.html */ settings: { // Exposed port port: process.env.PORT || 3003, // Exposed IP ip: '0.0.0.0', // Global Express middlewares. More info: https://moleculer.services/docs/0.14/moleculer-web.html#Middlewares use: [cors()], routes: [ { path: '/api', // ***Update Whitlisted services here*** // Route-level Express middlewares. More info: https://moleculer.services/docs/0.14/moleculer-web.html#Middlewares use: [], // Enable/disable parameter merging method. More info: https://moleculer.services/docs/0.14/moleculer-web.html#Disable-merging mergeParams: true, // Enable authentication. Implement the logic into `authenticate` method. More info: https://moleculer.services/docs/0.14/moleculer-web.html#Authentication authentication: false, // Enable authorization. Implement the logic into `authorize` method. More info: https://moleculer.services/docs/0.14/moleculer-web.html#Authorization authorization: false, // The auto-alias feature allows you to declare your route alias directly in your services. // The gateway will dynamically build the full routes from service schema. autoAliases: true, aliases: { 'POST /upload'(req, response) { const form = new multiparty.Form(); const ref = this; form.parse(req, function (err, fields, files) { if (files !== undefined) { const file = files.file[0]; ref.broker .call('storage.uploadFile', { file, }) .then((res) => { response.end(res); }) .catch((res) => { response.end(err); }); } else { response.end( 'No file Found, Showing random image' ); } }); }, }, /** * Before call hook. You can check the request. * @param {Context} ctx * @param {Object} route * @param {IncomingRequest} req * @param {ServerResponse} res * @param {Object} data * onBeforeCall(ctx, route, req, res) { // Set request headers to context meta ctx.meta.userAgent = req.headers["user-agent"]; }, */ /** * After call hook. You can modify the data. * @param {Context} ctx * @param {Object} route * @param {IncomingRequest} req * @param {ServerResponse} res * @param {Object} data onAfterCall(ctx, route, req, res, data) { // Async function which return with Promise return doSomething(ctx, res, data); }, */ // Calling options. More info: https://moleculer.services/docs/0.14/moleculer-web.html#Calling-options callingOptions: {}, bodyParsers: { json: { strict: false, limit: '1MB', }, urlencoded: { extended: true, limit: '1MB', }, }, // Mapping policy setting. More info: https://moleculer.services/docs/0.14/moleculer-web.html#Mapping-policy mappingPolicy: 'all', // Available values: "all", "restrict" // Enable/disable logging logging: true, }, ], // Do not log client side errors (does not log an error response when the error.code is 400<=X<500) log4XXResponses: false, // Logging the request parameters. Set to any log level to enable it. E.g. "info" logRequestParams: null, // Logging the response data. Set to any log level to enable it. E.g. "info" logResponseData: null, // Serve assets from "public" folder. More info: https://moleculer.services/docs/0.14/moleculer-web.html#Serve-static-files assets: { folder: 'public', // Options to `server-static` module options: {}, }, }, methods: { /** * Authenticate the request. It check the `Authorization` token value in the request header. * Check the token value & resolve the user by the token. * The resolved user will be available in `ctx.meta.user` * * PLEASE NOTE, IT'S JUST AN EXAMPLE IMPLEMENTATION. DO NOT USE IN PRODUCTION! * * @param {Context} ctx * @param {Object} route * @param {IncomingRequest} req * @returns {Promise} */ async authenticate(ctx, route, req) { // Read the token from header const auth = req.headers['authorization']; if (auth && auth.startsWith('Bearer')) { const token = auth.slice(7); // Check the token. Tip: call a service which verify the token. E.g. `accounts.resolveToken` if (token == '123456') { // Returns the resolved user. It will be set to the `ctx.meta.user` return { id: 1, name: 'John Doe' }; } else { // Invalid token throw new ApiGateway.Errors.UnAuthorizedError( ApiGateway.Errors.ERR_INVALID_TOKEN ); } } else { // No token. Throw an error or do nothing if anonymous access is allowed. // throw new E.UnAuthorizedError(E.ERR_NO_TOKEN); return null; } }, /** * Authorize the request. Check that the authenticated user has right to access the resource. * * PLEASE NOTE, IT'S JUST AN EXAMPLE IMPLEMENTATION. DO NOT USE IN PRODUCTION! * * @param {Context} ctx * @param {Object} route * @param {IncomingRequest} req * @returns {Promise} */ async authorize(ctx, route, req) { // Get the authenticated user. const user = ctx.meta.user; // It check the `auth` property in action schema. if (req.$action.auth == 'required' && !user) { throw new ApiGateway.Errors.UnAuthorizedError('NO_RIGHTS'); } }, }, };