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;