diff --git a/app/controllers/api/v1/Auth.controller.js b/app/controllers/api/v1/Auth.controller.js
index 23edb8b..1346560 100644
--- a/app/controllers/api/v1/Auth.controller.js
+++ b/app/controllers/api/v1/Auth.controller.js
@@ -605,6 +605,13 @@ class AuthController extends Controller {
// Create a login tracking activity
await this.activity.login(req)
+ // If there are login messages, show those
+ const LoginMessage = this.models.get('LoginMessage')
+ const messages = await LoginMessage.for_user(user)
+ if ( messages.length > 0 ) {
+ await req.trap.begin('login_message', { session_only: true })
+ }
+
return res.api({
success: true,
session_created: !!req.body.create_session,
diff --git a/app/controllers/api/v1/System.controller.js b/app/controllers/api/v1/System.controller.js
index 0bc5658..f6a81c5 100644
--- a/app/controllers/api/v1/System.controller.js
+++ b/app/controllers/api/v1/System.controller.js
@@ -2,7 +2,7 @@ const { Controller } = require('libflitter')
class ReflectController extends Controller {
static get services() {
- return [...super.services, 'routers', 'models', 'activity']
+ return [...super.services, 'routers', 'models', 'activity', 'Vue']
}
async get_announcements(req, res, next) {
@@ -80,6 +80,30 @@ class ReflectController extends Controller {
await announcement.delete()
return res.api()
}
+
+ async show_login_message(req, res) {
+ const LoginMessage = this.models.get('LoginMessage')
+ const messages = await LoginMessage.for_user(req.user)
+ const message = messages[0]
+
+ return this.Vue.auth_message(res, {
+ message: `
${message.title}
${message.message}`,
+ next_destination: '/auth/login-message/dismiss',
+ })
+ }
+
+ async dismiss_login_message(req, res) {
+ const LoginMessage = this.models.get('LoginMessage')
+ const messages = await LoginMessage.for_user(req.user)
+ const message = messages[0]
+
+ await message.mark_seen()
+
+ if ( req.trap.has_trap('login_message') )
+ await req.trap.end()
+
+ return res.redirect(req.session?.auth?.flow || '/dash')
+ }
}
module.exports = exports = ReflectController
diff --git a/app/models/LoginMessage.model.js b/app/models/LoginMessage.model.js
new file mode 100644
index 0000000..76ca5f5
--- /dev/null
+++ b/app/models/LoginMessage.model.js
@@ -0,0 +1,39 @@
+const { Model } = require('flitter-orm')
+
+class LoginMessageModel extends Model {
+ static get schema() {
+ return {
+ seen: {type: Boolean, default: false},
+ expires: {type: Date, default: () => {
+ const date = new Date
+ date.setYear(date.getUTCFullYear() + 1)
+ return date
+ }},
+ title: String,
+ message: String,
+ user_id: String,
+ }
+ }
+
+ static async for_user(user) {
+ return this.find({ user_id: user.id, seen: false, expires: { $gt: new Date } })
+ }
+
+ static async create(user, title, message) {
+ const msg = new this({
+ message,
+ title,
+ user_id: user.id,
+ })
+
+ await msg.save()
+ return msg
+ }
+
+ async mark_seen() {
+ this.seen = true
+ return this.save()
+ }
+}
+
+module.exports = exports = LoginMessageModel
diff --git a/app/models/system/Announcement.model.js b/app/models/system/Announcement.model.js
index e738ac2..9e348bd 100644
--- a/app/models/system/Announcement.model.js
+++ b/app/models/system/Announcement.model.js
@@ -66,6 +66,8 @@ class AnnouncementModel extends Model {
await this.populate_emails()
} else if ( this.type === 'banner' ) {
await this.populate_banners()
+ } else if ( this.type === 'login' ) {
+ await this.populate_logins()
}
}
@@ -92,6 +94,14 @@ class AnnouncementModel extends Model {
await Message.create(user, `${this.title} - ${this.message}`)
}
}
+
+ async populate_logins() {
+ const users = await this.all_users()
+ const LoginMessage = this.models.get('LoginMessage')
+ for ( const user of users ) {
+ await LoginMessage.create(user, this.title, this.message)
+ }
+ }
}
module.exports = exports = AnnouncementModel
diff --git a/app/routing/routers/auth/forms.routes.js b/app/routing/routers/auth/forms.routes.js
index 9faf7b3..e979d67 100644
--- a/app/routing/routers/auth/forms.routes.js
+++ b/app/routing/routers/auth/forms.routes.js
@@ -66,6 +66,16 @@ const index = {
'controller::auth:Forms.logout_provider_clean_session',
'controller::auth:Forms.logout_provider_present_success',
],
+
+ '/login-message': [
+ 'middleware::auth:UserOnly',
+ 'controller::api:v1:System.show_login_message',
+ ],
+
+ '/login-message/dismiss': [
+ 'middleware::auth:UserOnly',
+ 'controller::api:v1:System.dismiss_login_message',
+ ],
},
post: {
diff --git a/config/traps.config.js b/config/traps.config.js
index a207296..064fbb0 100644
--- a/config/traps.config.js
+++ b/config/traps.config.js
@@ -21,6 +21,14 @@ const traps_config = {
'/api/v1/locale/batch',
],
},
+ login_message: {
+ redirect_to: '/auth/login-message',
+ allowed_routes: [
+ '/auth/logout',
+ '/auth/login-message',
+ '/auth/login-message/dismiss',
+ ],
+ },
},
}