@semapps/auth 0.7.0 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/mixins/auth.js CHANGED
@@ -19,21 +19,23 @@ const AuthMixin = {
19
19
  accountsDataset: 'settings',
20
20
  podProvider: false
21
21
  },
22
- dependencies: ['api', 'webid'],
22
+ dependencies: ['api'],
23
23
  async created() {
24
24
  const { jwtPath, reservedUsernames, accountsDataset, podProvider } = this.settings;
25
25
 
26
- this.broker.createService(AuthJWTService, {
26
+ this.broker.createService({
27
+ mixins: [AuthJWTService],
27
28
  settings: { jwtPath }
28
29
  });
29
30
 
30
- this.broker.createService(AuthAccountService, {
31
+ this.broker.createService({
32
+ mixins: [AuthAccountService],
31
33
  settings: { reservedUsernames },
32
34
  adapter: new TripleStoreAdapter({ type: 'AuthAccount', dataset: accountsDataset })
33
35
  });
34
36
 
35
37
  if (podProvider) {
36
- this.broker.createService(CapabilitiesService, { settings: { path: this.settings.capabilitiesPath } });
38
+ this.broker.createService({ mixins: [CapabilitiesService], settings: { path: this.settings.capabilitiesPath } });
37
39
  }
38
40
  },
39
41
  async started() {
@@ -51,7 +53,9 @@ const AuthMixin = {
51
53
 
52
54
  this.passport.use(this.passportId, this.strategy);
53
55
 
54
- for (const route of this.getApiRoutes()) {
56
+ const { pathname: basePath } = new URL(this.settings.baseUrl);
57
+
58
+ for (const route of this.getApiRoutes(basePath)) {
55
59
  await this.broker.call('api.addRoute', { route });
56
60
  }
57
61
  },
@@ -1,3 +1,4 @@
1
+ const path = require('path');
1
2
  const session = require('express-session');
2
3
  const AuthMixin = require('./auth');
3
4
  const saveRedirectUrl = require('../middlewares/saveRedirectUrl');
@@ -33,8 +34,7 @@ const AuthSSOMixin = {
33
34
  webId = accountData.webId;
34
35
  newUser = false;
35
36
 
36
- // TODO update account with recent information
37
- // await ctx.call('webid.edit', profileData, { meta: { webId } });
37
+ // TODO update account with recent profileData information
38
38
 
39
39
  ctx.emit('auth.connected', { webId, accountData, ssoData }, { meta: { webId: null, dataset: null } });
40
40
  } else {
@@ -47,7 +47,7 @@ const AuthSSOMixin = {
47
47
  email: profileData.email,
48
48
  username: profileData.username
49
49
  });
50
- webId = await ctx.call('webid.create', this.pickWebIdData({ nick: accountData.username, ...profileData }));
50
+ webId = await ctx.call('webid.createWebId', this.pickWebIdData({ nick: accountData.username, ...profileData }));
51
51
  newUser = true;
52
52
 
53
53
  // Link the webId with the account
@@ -66,11 +66,11 @@ const AuthSSOMixin = {
66
66
  }
67
67
  },
68
68
  methods: {
69
- getApiRoutes() {
69
+ getApiRoutes(basePath) {
70
70
  const sessionMiddleware = session({ secret: this.settings.sessionSecret, maxAge: null });
71
71
  return [
72
72
  {
73
- path: '/auth',
73
+ path: path.join(basePath, '/auth'),
74
74
  name: 'auth',
75
75
  use: [sessionMiddleware, this.passport.initialize(), this.passport.session()],
76
76
  aliases: {
@@ -78,7 +78,7 @@ const AuthSSOMixin = {
78
78
  }
79
79
  },
80
80
  {
81
- path: '/auth/logout',
81
+ path: path.join(basePath, '/auth/logout'),
82
82
  name: 'auth-logout',
83
83
  use: [sessionMiddleware, this.passport.initialize(), this.passport.session()],
84
84
  aliases: {
package/package.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "name": "@semapps/auth",
3
- "version": "0.7.0",
3
+ "version": "0.8.1",
4
4
  "description": "Authentification module for SemApps",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Virtual Assembly",
7
7
  "dependencies": {
8
- "@semapps/ldp": "0.7.0",
9
- "@semapps/middlewares": "0.7.0",
10
- "@semapps/mime-types": "0.7.0",
11
- "@semapps/triplestore": "0.7.0",
8
+ "@semapps/ldp": "0.8.1",
9
+ "@semapps/middlewares": "0.8.1",
10
+ "@semapps/mime-types": "0.8.1",
11
+ "@semapps/triplestore": "0.8.1",
12
12
  "bcrypt": "^5.0.1",
13
13
  "express-session": "^1.17.0",
14
14
  "jsonwebtoken": "^8.5.1",
@@ -29,5 +29,5 @@
29
29
  "engines": {
30
30
  "node": ">=14"
31
31
  },
32
- "gitHead": "793f935c61e5f4e87ac17ee1dd41a968f12678b4"
32
+ "gitHead": "c056166a50822060e229c20efd2eb6ee666fc743"
33
33
  }
@@ -88,6 +88,12 @@ module.exports = {
88
88
  const accounts = await this._find(ctx, { query: { email } });
89
89
  return accounts.length > 0;
90
90
  },
91
+ /** Overwrite find method, to filter accounts with tombstone. */
92
+ async find(ctx) {
93
+ /** @type {object[]} */
94
+ const accounts = await this._find(ctx, ctx.params);
95
+ return accounts.filter(account => !account.deletedAt);
96
+ },
91
97
  async findByUsername(ctx) {
92
98
  const { username } = ctx.params;
93
99
  const accounts = await this._find(ctx, { query: { username } });
@@ -184,6 +190,34 @@ module.exports = {
184
190
  '@id': account['@id'],
185
191
  ...params
186
192
  });
193
+ },
194
+ async deleteByWebId(ctx) {
195
+ const { webId } = ctx.params;
196
+ const account = await ctx.call('auth.account.findByWebId', { webId });
197
+
198
+ if (account) {
199
+ await this._remove(ctx, { id: account['@id'] });
200
+ return true;
201
+ }
202
+
203
+ return false;
204
+ },
205
+ // Remove email and password from an account, set deletedAt timestamp.
206
+ async setTombstone(ctx) {
207
+ const { webId } = ctx.params;
208
+ const account = await ctx.call('auth.account.findByWebId', { webId });
209
+
210
+ return await this._update(ctx, {
211
+ // Set all values to undefined...
212
+ ...Object.fromEntries(Object.keys(account).map(key => [key, null])),
213
+ '@id': account['@id'],
214
+ // ...except for
215
+ webId: account.webId,
216
+ username: account.username,
217
+ podUri: account.podUri,
218
+ // And add a deletedAt date.
219
+ deletedAt: new Date().toISOString()
220
+ });
187
221
  }
188
222
  },
189
223
  methods: {
@@ -1,9 +1,11 @@
1
+ const path = require('path');
1
2
  const { Strategy } = require('passport-local');
2
3
  const AuthMixin = require('../mixins/auth');
3
4
  const sendToken = require('../middlewares/sendToken');
4
5
  const { MoleculerError } = require('moleculer').Errors;
5
6
  const AuthMailService = require('./mail');
6
7
 
8
+ /** @type {import('moleculer').ServiceSchema} */
7
9
  const AuthLocalService = {
8
10
  name: 'auth',
9
11
  mixins: [AuthMixin],
@@ -27,13 +29,15 @@ const AuthLocalService = {
27
29
  }
28
30
  }
29
31
  },
32
+ dependencies: ['webid'],
30
33
  async created() {
31
34
  const { mail } = this.settings;
32
35
 
33
36
  this.passportId = 'local';
34
37
 
35
38
  if (mail !== false) {
36
- await this.broker.createService(AuthMailService, {
39
+ this.broker.createService({
40
+ mixins: [AuthMailService],
37
41
  settings: {
38
42
  ...mail
39
43
  }
@@ -43,6 +47,8 @@ const AuthLocalService = {
43
47
  actions: {
44
48
  async signup(ctx) {
45
49
  const { username, email, password, interactionId, ...rest } = ctx.params;
50
+ // This is going to get in our way otherwise when waiting for completions.
51
+ ctx.meta.skipObjectsWatcher = true;
46
52
 
47
53
  if (username && username.length < 2) {
48
54
  throw new Error('The username must be at least 2 characters long');
@@ -56,7 +62,7 @@ const AuthLocalService = {
56
62
  });
57
63
 
58
64
  const profileData = { nick: username, email, ...rest };
59
- const webId = await ctx.call('webid.create', this.pickWebIdData(profileData));
65
+ const webId = await ctx.call('webid.createWebId', this.pickWebIdData(profileData));
60
66
 
61
67
  // Link the webId with the account
62
68
  accountData = await ctx.call('auth.account.attachWebId', { accountUri: accountData['@id'], webId });
@@ -148,9 +154,9 @@ const AuthLocalService = {
148
154
  }
149
155
  );
150
156
  },
151
- getApiRoutes() {
157
+ getApiRoutes(basePath) {
152
158
  const loginRoute = {
153
- path: '/auth/login',
159
+ path: path.join(basePath, '/auth/login'),
154
160
  name: 'auth-login',
155
161
  use: [this.passport.initialize()],
156
162
  aliases: {
@@ -159,7 +165,7 @@ const AuthLocalService = {
159
165
  };
160
166
 
161
167
  const logoutRoute = {
162
- path: '/auth/logout',
168
+ path: path.join(basePath, '/auth/logout'),
163
169
  name: 'auth-logout',
164
170
  aliases: {
165
171
  'GET /': 'auth.logout'
@@ -167,7 +173,7 @@ const AuthLocalService = {
167
173
  };
168
174
 
169
175
  const signupRoute = {
170
- path: '/auth/signup',
176
+ path: path.join(basePath, '/auth/signup'),
171
177
  name: 'auth-signup',
172
178
  aliases: {
173
179
  'POST /': 'auth.signup'
@@ -175,7 +181,7 @@ const AuthLocalService = {
175
181
  };
176
182
 
177
183
  const formRoute = {
178
- path: '/auth',
184
+ path: path.join(basePath, '/auth'),
179
185
  name: 'auth',
180
186
  aliases: {
181
187
  'GET /': 'auth.redirectToForm'
@@ -183,14 +189,14 @@ const AuthLocalService = {
183
189
  };
184
190
 
185
191
  const resetPasswordRoute = {
186
- path: '/auth/reset_password',
192
+ path: path.join(basePath, '/auth/reset_password'),
187
193
  name: 'auth-reset-password',
188
194
  aliases: {
189
195
  'POST /': 'auth.resetPassword'
190
196
  }
191
197
  };
192
198
  const setNewPasswordRoute = {
193
- path: '/auth/new_password',
199
+ path: path.join(basePath, '/auth/new_password'),
194
200
  name: 'auth-new-password',
195
201
  aliases: {
196
202
  'POST /': 'auth.setNewPassword'
@@ -198,7 +204,7 @@ const AuthLocalService = {
198
204
  };
199
205
 
200
206
  const accountSettingsRoute = {
201
- path: '/auth/account',
207
+ path: path.join(basePath, '/auth/account'),
202
208
  name: 'auth-account',
203
209
  aliases: {
204
210
  'GET /': 'auth.account.findSettingsByWebId',