diff --git a/app/assets/version.html b/app/assets/version.html new file mode 100644 index 0000000..19be3bf --- /dev/null +++ b/app/assets/version.html @@ -0,0 +1 @@ +796aaedc-91d9-4831-ae47-de330967e7b4 diff --git a/app/controllers/api/v1/Session.controller.js b/app/controllers/api/v1/Session.controller.js index 107ace3..72a8929 100644 --- a/app/controllers/api/v1/Session.controller.js +++ b/app/controllers/api/v1/Session.controller.js @@ -2,7 +2,7 @@ const { Controller } = require('libflitter') class SessionController extends Controller { static get services() { - return [...super.services, 'configs'] + return [...super.services, 'configs', 'models', 'auth'] } async get_session(req, res, next) { @@ -38,6 +38,41 @@ class SessionController extends Controller { }, } } + + async get_device_token(req, res, next) { + const DeviceToken = this.models.get('api:DeviceToken') + const token = await DeviceToken.grant_user(req.user) + + return res.api({ + token: token.token, + expiration_date: token.expiration_date, + }) + } + + async resume(req, res, next) { + const DeviceToken = this.models.get('api:DeviceToken') + const User = this.models.get('auth:User') + const token = await DeviceToken.findOne({ + token: req.params.token, + expiration_date: { $gt: new Date }, + }); + + if ( !token ) { + return res.status(404) + .message('Device token expired or invalid.') + .api() + } + + const user = await User.findById(token.user_id); + if ( !user ) { + return res.status(404) + .message('Device token expired or invalid.') + .api() + } + + await this.auth.get_provider().session(req, user) + return res.api() + } } module.exports = exports = SessionController diff --git a/app/models/api/DeviceToken.model.js b/app/models/api/DeviceToken.model.js new file mode 100644 index 0000000..e7689d9 --- /dev/null +++ b/app/models/api/DeviceToken.model.js @@ -0,0 +1,36 @@ +const { Model } = require('flitter-orm') +const uuid = require('uuid/v4') + +class DeviceTokenModel extends Model { + static get schema() { + return { + user_id: String, + create_date: { type: Date, default: () => new Date }, + expiration_date: { + type: Date, + default: () => { + const date = new Date(); + date.setMonth(date.getMonth() + 1); + return date; + } + }, + token: { + type: String, + default: () => { + return Array(5).fill('').map(_ => uuid()).join('').replace(/-/g, '') + } + }, + } + } + + static async grant_user(user) { + const tok = new this({ + user_id: user.id, + }) + + await tok.save() + return tok + } +} + +module.exports = exports = DeviceTokenModel diff --git a/app/routing/routers/api/v1/session.routes.js b/app/routing/routers/api/v1/session.routes.js index 46cd820..f2f05d8 100644 --- a/app/routing/routers/api/v1/session.routes.js +++ b/app/routing/routers/api/v1/session.routes.js @@ -8,6 +8,7 @@ const index = { get: { '/': [ 'controller::api:v1:Session.get_session' ], + '/device-token': [ 'controller::api:v1:Session.get_device_token' ], }, post: { diff --git a/app/routing/routers/index.routes.js b/app/routing/routers/index.routes.js index 184d65e..34928f6 100644 --- a/app/routing/routers/index.routes.js +++ b/app/routing/routers/index.routes.js @@ -60,7 +60,11 @@ const index = { * an array of canonical references to controller methods * or middleware that are applied in order. */ - post: {} + post: { + '/api/v1/session/resume/:token': [ + 'middleware::auth:GuestOnly', 'controller::api:v1:Session.resume', + ], + } }; module.exports = exports = index;