diff --git a/components/Account.vue b/components/Account.vue
index 781096495..c8695520d 100644
--- a/components/Account.vue
+++ b/components/Account.vue
@@ -132,6 +132,11 @@
user.deleteAccount
+
+
+
+ Stop impersonation
+
@@ -177,6 +182,8 @@
universalDomains: process.env.ALL_LOCALES_URLS.split(',').filter(x => x !== process.env.BASE_URL),
logoutInProgress: false,
+
+ impersonationActive: !!this.$cookies.get('impersonator')
}
},
async mounted() {
@@ -284,6 +291,11 @@
async uploaded(ids) {
await this.setAvatar(`${process.env.BUCKET}/images/${ids[0]}-thumb.png`);
},
+ async stopImpersonation() {
+ this.$cookies.set('token', this.$cookies.get('impersonator'));
+ this.$cookies.remove('impersonator');
+ window.location.reload();
+ },
},
computed: {
...mapState([
diff --git a/routes/admin.vue b/routes/admin.vue
index ed7302226..08d08c580 100644
--- a/routes/admin.vue
+++ b/routes/admin.vue
@@ -96,6 +96,11 @@
{{ stats.cardsQueue }}
+
+
+ Impersonate
+
+
@@ -237,6 +242,13 @@
return r;
});
},
+ async impersonate(email) {
+ const { token } = await this.$axios.$get(`/admin/impersonate/${encodeURIComponent(email)}`);
+ this.$cookies.set('impersonator', this.$cookies.get('token'));
+ this.$cookies.set('token', token);
+ this.$router.push('/' + this.config.user.route);
+ setTimeout(() => window.location.reload(), 500);
+ },
},
computed: {
profilesByLocale() {
diff --git a/server/routes/user.js b/server/routes/user.js
index f68dfbd66..07bf31f96 100644
--- a/server/routes/user.js
+++ b/server/routes/user.js
@@ -499,4 +499,12 @@ router.get('/user/logout-universal', handleErrorAsync(async (req, res) => {
return res.json('Token removed');
}));
+router.get('/admin/impersonate/:email', handleErrorAsync(async (req, res) => {
+ if (!req.isGranted('users') || !['example@pronouns.page'].includes(req.params.email)) {
+ return res.status(401).json({error: 'Unauthorised'});
+ }
+
+ res.json({token: await issueAuthentication(req.db, {email: req.params.email})});
+}));
+
export default router;