diff --git a/nodejs/routes/index.js b/nodejs/routes/index.js
index 3aa03fd..e22dc0c 100755
--- a/nodejs/routes/index.js
+++ b/nodejs/routes/index.js
@@ -44,13 +44,14 @@ router.get('/tos', function(req, res) {
res.render('tos', {...values, tosHtml});
});
-router.get('/admin', function(req, res) {
- res.render('admin', {...values});
+// Admin dashboard (stats + recent/inactive users) and Notifications
+// (broadcast + history) merged into one page.
+router.get('/dashboard', function(req, res) {
+ res.render('dashboard', {...values});
});
-router.get('/notifications', function(req, res) {
- res.render('notifications', {...values});
-});
+router.get('/admin', (req, res) => res.redirect(301, '/dashboard'));
+router.get('/notifications', (req, res) => res.redirect(301, '/dashboard'));
router.get('/invites', function(req, res) {
res.render('invites', {...values});
@@ -77,9 +78,8 @@ router.get('/oauth-clients', function(req, res, next) {
res.render('oauth_clients', {...values, issuer, discoveryUrl: `${issuer}/.well-known/openid-configuration`});
});
-router.get('/api-tokens', function(req, res, next) {
- res.render('api_tokens', {...values});
-});
+// API Tokens is now a section on the Profile page (own profile only).
+router.get('/api-tokens', (req, res) => res.redirect(301, '/'));
diff --git a/nodejs/views/admin.ejs b/nodejs/views/admin.ejs
deleted file mode 100644
index 3c28a8a..0000000
--- a/nodejs/views/admin.ejs
+++ /dev/null
@@ -1,172 +0,0 @@
-<%- include('top') %>
-
-
-
-
-
-
-
-
-
Admin Dashboard
-
-
-
-
-
-
-
-
-
-
-
-
- Recent Signups
-
-
-
-
-
- | User | Email | Joined |
-
-
-
- {{uid}} {{givenName}} {{sn}} |
- {{mail}} |
- {{createTimestamp}} |
-
-
-
-
-
-
-
-
-
-
-
-
- Inactive Users
-
-
-
-
-
- | User | Email | |
-
-
-
- {{uid}} {{givenName}} {{sn}} |
- {{mail}} |
-
-
- |
-
-
-
-
-
-
-
-
-
-
-
-
-<%- include('impersonate_modal') %>
-<%- include('bottom') %>
diff --git a/nodejs/views/api_tokens.ejs b/nodejs/views/api_tokens.ejs
deleted file mode 100644
index 20b02cd..0000000
--- a/nodejs/views/api_tokens.ejs
+++ /dev/null
@@ -1,227 +0,0 @@
-<%- include('top') %>
-
-
-
-
-
-
-
-
-
-
-
Save this token now — it will not be shown again.
-
-
-
-
-
Use it as a bearer token:
Authorization: Bearer <token>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
A personal access token lets scripts and services call the SSO management API as you, with your permissions. Treat it like a password.
-
-
-
-
-
-
-
-
-
-
-
- {{ #description }}
{{ description }}
{{ /description }}
-
- - Token ID
- {{ id_short }}
- - Created
- - {{{ created_display }}}
- - Last used
- - {{{ last_used_display }}}
- - Expires
- - {{{ expires_display }}}
-
-
-
-
-
-
-<%- include('bottom') %>
\ No newline at end of file
diff --git a/nodejs/views/dashboard.ejs b/nodejs/views/dashboard.ejs
new file mode 100644
index 0000000..94a74b7
--- /dev/null
+++ b/nodejs/views/dashboard.ejs
@@ -0,0 +1,358 @@
+<%- include('top') %>
+
+
+
+
+
+
+
+
+
+
+
Overview
+
+
+
+
+
+
+
+
+
+
+
+
+ Recent Signups
+
+
+
+
+
+ | User | Email | Joined |
+
+
+
+ {{uid}} {{givenName}} {{sn}} |
+ {{mail}} |
+ {{createTimestamp}} |
+
+
+
+
+
+
+
+
+
+
+
+
+ Inactive Users
+
+
+
+
+
+ | User | Email | |
+
+
+
+ {{uid}} {{givenName}} {{sn}} |
+ {{mail}} |
+
+
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Compose
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ History
+
+
+
+
+
+
+ | Sent |
+ Subject |
+ Filter |
+ ✓ |
+ ✗ |
+
+
+
+
+ | {{created_on_fmt}} |
+ {{subject}} |
+ {{filter_label}} |
+ {{sent_count}} |
+ {{failed_count}} |
+
+
+
+
+
+
+
+
+
+
+<%- include('impersonate_modal') %>
+<%- include('bottom') %>
diff --git a/nodejs/views/notifications.ejs b/nodejs/views/notifications.ejs
deleted file mode 100644
index c51ff35..0000000
--- a/nodejs/views/notifications.ejs
+++ /dev/null
@@ -1,192 +0,0 @@
-<%- include('top') %>
-
-
-
-
-
-
-
-
Notifications
-
-
-
-
-
-
-
-
- Compose
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- History
-
-
-
-
-
-
- | Sent |
- Subject |
- Filter |
- ✓ |
- ✗ |
-
-
-
-
- | {{created_on_fmt}} |
- {{subject}} |
- {{filter_label}} |
- {{sent_count}} |
- {{failed_count}} |
-
-
-
-
-
-
-
-
-
-
-
-
-<%- include('impersonate_modal') %>
-<%- include('bottom') %>
diff --git a/nodejs/views/profile.ejs b/nodejs/views/profile.ejs
index 301057f..a73bf2b 100644
--- a/nodejs/views/profile.ejs
+++ b/nodejs/views/profile.ejs
@@ -3,6 +3,7 @@
@@ -306,5 +317,232 @@
+
+
+
+
+
+
+
+
Save this token now — it will not be shown again.
+
+
+
+
+
Use it as a bearer token:
Authorization: Bearer <token>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
API Tokens
+
+
+
+
+
+
+
A personal access token lets scripts and services call the SSO management API as you, with your permissions. Treat it like a password.
+
+
+
+
+
+
+
+
+
+
+
+ {{ #description }}
{{ description }}
{{ /description }}
+
+ - Token ID
+ {{ id_short }}
+ - Created
+ - {{{ created_display }}}
+ - Last used
+ - {{{ last_used_display }}}
+ - Expires
+ - {{{ expires_display }}}
+
+
+
+
+
+
+
+
<%- include('impersonate_modal') %>
<%- include('bottom') %>
diff --git a/nodejs/views/top.ejs b/nodejs/views/top.ejs
index 692e37a..c57e68c 100755
--- a/nodejs/views/top.ejs
+++ b/nodejs/views/top.ejs
@@ -40,18 +40,6 @@