const {models} = require('vn-loopback/server/server'); module.exports = Self => { Self.remoteMethodCtx('renewToken', { description: 'Checks if the token has more than renewPeriod seconds to live and if so, renews it', accessType: 'WRITE', accepts: [], returns: { type: 'Object', root: true }, http: { path: `/renewToken`, verb: 'POST' } }); Self.renewToken = async function(ctx) { const {accessToken: token} = ctx.req; // Check if current token is valid const {renewPeriod, courtesyTime} = await models.AccessTokenConfig.findOne({ fields: ['renewPeriod', 'courtesyTime'] }); const now = Date.now(); const differenceMilliseconds = now - token.created; const differenceSeconds = Math.floor(differenceMilliseconds / 1000); const isNotExceeded = differenceSeconds < renewPeriod - courtesyTime; if (isNotExceeded) return token; // Schedule to remove current token setTimeout(async() => { try { const exists = await models.AccessToken.findById(token.id); exists && await Self.logout(token.id); } catch (err) { // eslint-disable-next-line no-console console.error(err); } }, courtesyTime * 1000); // Get scopes let createTokenOptions = {}; const {scopes} = token; if (scopes) createTokenOptions = {scopes: [scopes[0]]}; // Create new accessToken const user = await Self.findById(token.userId); const accessToken = await user.accessTokens.create(createTokenOptions); return {id: accessToken.id, ttl: accessToken.ttl}; }; };