@semapps/auth 1.1.4 → 1.2.0
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/dist/index.d.ts +8 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/middlewares/localLogout.d.ts +2 -0
- package/dist/middlewares/localLogout.js +6 -0
- package/dist/middlewares/localLogout.js.map +1 -0
- package/dist/middlewares/redirectToFront.d.ts +2 -0
- package/dist/middlewares/redirectToFront.js +15 -0
- package/dist/middlewares/redirectToFront.js.map +1 -0
- package/dist/middlewares/saveRedirectUrl.d.ts +2 -0
- package/dist/middlewares/saveRedirectUrl.js +9 -0
- package/dist/middlewares/saveRedirectUrl.js.map +1 -0
- package/dist/middlewares/sendToken.d.ts +2 -0
- package/dist/middlewares/sendToken.js +6 -0
- package/dist/middlewares/sendToken.js.map +1 -0
- package/dist/mixins/auth.d.ts +98 -0
- package/dist/mixins/auth.js +235 -0
- package/dist/mixins/auth.js.map +1 -0
- package/dist/mixins/auth.sso.d.ts +76 -0
- package/dist/mixins/auth.sso.js +82 -0
- package/dist/mixins/auth.sso.js.map +1 -0
- package/dist/services/account.d.ts +122 -0
- package/dist/services/account.js +324 -0
- package/dist/services/account.js.map +1 -0
- package/dist/services/auth.cas.d.ts +100 -0
- package/dist/services/auth.cas.js +43 -0
- package/dist/services/auth.cas.js.map +1 -0
- package/dist/services/auth.local.d.ts +143 -0
- package/dist/services/auth.local.js +229 -0
- package/dist/services/auth.local.js.map +1 -0
- package/dist/services/auth.oidc.d.ts +102 -0
- package/dist/services/auth.oidc.js +63 -0
- package/dist/services/auth.oidc.js.map +1 -0
- package/dist/services/jwt.d.ts +50 -0
- package/dist/services/jwt.js +111 -0
- package/dist/services/jwt.js.map +1 -0
- package/dist/services/mail.d.ts +31 -0
- package/dist/services/mail.js +52 -0
- package/dist/services/mail.js.map +1 -0
- package/dist/services/migration.d.ts +18 -0
- package/dist/services/migration.js +33 -0
- package/dist/services/migration.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/index.ts +17 -0
- package/middlewares/localLogout.ts +6 -0
- package/middlewares/{redirectToFront.js → redirectToFront.ts} +2 -2
- package/middlewares/{saveRedirectUrl.js → saveRedirectUrl.ts} +2 -2
- package/middlewares/{sendToken.js → sendToken.ts} +2 -2
- package/mixins/auth.sso.ts +100 -0
- package/mixins/{auth.js → auth.ts} +86 -67
- package/package.json +15 -9
- package/services/account.ts +382 -0
- package/services/auth.cas.ts +56 -0
- package/services/auth.local.ts +276 -0
- package/services/{auth.oidc.js → auth.oidc.ts} +21 -9
- package/services/jwt.ts +127 -0
- package/services/mail.ts +67 -0
- package/services/migration.ts +43 -0
- package/tsconfig.json +10 -0
- package/index.js +0 -9
- package/middlewares/localLogout.js +0 -6
- package/mixins/auth.sso.js +0 -93
- package/services/account.js +0 -315
- package/services/auth.cas.js +0 -45
- package/services/auth.local.js +0 -238
- package/services/jwt.js +0 -101
- package/services/mail.js +0 -49
- package/services/migration.js +0 -29
package/dist/index.d.ts
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
import AuthCASService from './services/auth.cas.ts';
|
2
|
+
import AuthLocalService from './services/auth.local.ts';
|
3
|
+
import AuthOIDCService from './services/auth.oidc.ts';
|
4
|
+
import AuthAccountService from './services/account.ts';
|
5
|
+
import AuthJWTService from './services/jwt.ts';
|
6
|
+
import AuthMigrationService from './services/migration.ts';
|
7
|
+
import AuthMailService from './services/mail.ts';
|
8
|
+
export { AuthCASService, AuthLocalService, AuthOIDCService, AuthAccountService, AuthJWTService, AuthMigrationService, AuthMailService };
|
package/dist/index.js
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
import AuthCASService from "./services/auth.cas.js";
|
2
|
+
import AuthLocalService from "./services/auth.local.js";
|
3
|
+
import AuthOIDCService from "./services/auth.oidc.js";
|
4
|
+
import AuthAccountService from "./services/account.js";
|
5
|
+
import AuthJWTService from "./services/jwt.js";
|
6
|
+
import AuthMigrationService from "./services/migration.js";
|
7
|
+
import AuthMailService from "./services/mail.js";
|
8
|
+
export { AuthCASService, AuthLocalService, AuthOIDCService, AuthAccountService, AuthJWTService, AuthMigrationService, AuthMailService };
|
9
|
+
//# sourceMappingURL=index.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,cAAc,MAAM,wBAAwB,CAAC;AACpD,OAAO,gBAAgB,MAAM,0BAA0B,CAAC;AACxD,OAAO,eAAe,MAAM,yBAAyB,CAAC;AACtD,OAAO,kBAAkB,MAAM,uBAAuB,CAAC;AACvD,OAAO,cAAc,MAAM,mBAAmB,CAAC;AAC/C,OAAO,oBAAoB,MAAM,yBAAyB,CAAC;AAC3D,OAAO,eAAe,MAAM,oBAAoB,CAAC;AAEjD,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,eAAe,EACf,kBAAkB,EAClB,cAAc,EACd,oBAAoB,EACpB,eAAe,EAChB,CAAC"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"localLogout.js","sourceRoot":"","sources":["../../middlewares/localLogout.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,GAAG,CAAC,GAAQ,EAAE,GAAQ,EAAE,IAAS,EAAE,EAAE;IACpD,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,kBAAkB;IAChC,IAAI,EAAE,CAAC;AACT,CAAC,CAAC;AAEF,eAAe,WAAW,CAAC"}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
const redirectToFront = (req, res) => {
|
2
|
+
// Redirect browser to the redirect URL pushed in session
|
3
|
+
const redirectUrl = new URL(req.session.redirectUrl);
|
4
|
+
if (req.user) {
|
5
|
+
// If a token was stored, add it to the URL so that the client may use it
|
6
|
+
if (req.user.token)
|
7
|
+
redirectUrl.searchParams.set('token', req.user.token);
|
8
|
+
redirectUrl.searchParams.set('new', req.user.newUser ? 'true' : 'false');
|
9
|
+
}
|
10
|
+
// Redirect using NodeJS HTTP
|
11
|
+
res.writeHead(302, { Location: redirectUrl.toString() });
|
12
|
+
res.end();
|
13
|
+
};
|
14
|
+
export default redirectToFront;
|
15
|
+
//# sourceMappingURL=redirectToFront.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"redirectToFront.js","sourceRoot":"","sources":["../../middlewares/redirectToFront.ts"],"names":[],"mappings":"AAAA,MAAM,eAAe,GAAG,CAAC,GAAQ,EAAE,GAAQ,EAAE,EAAE;IAC7C,yDAAyD;IACzD,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IACrD,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;QACb,yEAAyE;QACzE,IAAI,GAAG,CAAC,IAAI,CAAC,KAAK;YAAE,WAAW,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1E,WAAW,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IAC3E,CAAC;IACD,6BAA6B;IAC7B,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAE,WAAW,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IACzD,GAAG,CAAC,GAAG,EAAE,CAAC;AACZ,CAAC,CAAC;AAEF,eAAe,eAAe,CAAC"}
|
@@ -0,0 +1,9 @@
|
|
1
|
+
const saveRedirectUrl = (req, res, next) => {
|
2
|
+
// Persist referer on the session to get it back after redirection
|
3
|
+
// If the redirectUrl is already in the session, use it as default value
|
4
|
+
req.session.redirectUrl =
|
5
|
+
req.query.redirectUrl || (req.session && req.session.redirectUrl) || req.headers.referer || '/';
|
6
|
+
next();
|
7
|
+
};
|
8
|
+
export default saveRedirectUrl;
|
9
|
+
//# sourceMappingURL=saveRedirectUrl.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"saveRedirectUrl.js","sourceRoot":"","sources":["../../middlewares/saveRedirectUrl.ts"],"names":[],"mappings":"AAAA,MAAM,eAAe,GAAG,CAAC,GAAQ,EAAE,GAAQ,EAAE,IAAS,EAAE,EAAE;IACxD,kEAAkE;IAClE,wEAAwE;IACxE,GAAG,CAAC,OAAO,CAAC,WAAW;QACrB,GAAG,CAAC,KAAK,CAAC,WAAW,IAAI,CAAC,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,OAAO,IAAI,GAAG,CAAC;IAClG,IAAI,EAAE,CAAC;AACT,CAAC,CAAC;AAEF,eAAe,eAAe,CAAC"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"sendToken.js","sourceRoot":"","sources":["../../middlewares/sendToken.ts"],"names":[],"mappings":"AAAA,MAAM,SAAS,GAAG,CAAC,GAAQ,EAAE,GAAQ,EAAE,EAAE;IACvC,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAC;IAClD,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;AACvG,CAAC,CAAC;AAEF,eAAe,SAAS,CAAC"}
|
@@ -0,0 +1,98 @@
|
|
1
|
+
/**
|
2
|
+
* Auth Mixin that handles authentication and authorization for routes
|
3
|
+
* that requested this.
|
4
|
+
*
|
5
|
+
* The authorization and authentication actions check for a valid `authorization` header.
|
6
|
+
* If the bearer token is a server-signed JWT identifying the user, `ctx.meta.tokenPayload` and
|
7
|
+
* `ctx.meta.webId` are set. Setting either `authorization` or `authentication` suffices.
|
8
|
+
*
|
9
|
+
* # Authentication
|
10
|
+
* In the `authenticate` action, the webId is set to `anon`, if no `authorization` header is present.
|
11
|
+
*
|
12
|
+
* # Authorization
|
13
|
+
* In contrast, the `authorize` action throws an unauthorized error,
|
14
|
+
* if no `authorization` header is present.
|
15
|
+
* @see https://moleculer.services/docs/0.13/moleculer-web.html#Authentication
|
16
|
+
*
|
17
|
+
* ## Capability Authorization
|
18
|
+
* Additionally, the `authorize` action supports capability authorization based on
|
19
|
+
* Verifiable Credentials (VCs), if `opts.authorizeWithCapability` is set to `true`.
|
20
|
+
*
|
21
|
+
* **WARNING**: This does not make any assertions about the validity of the capabilities'
|
22
|
+
* content (`credentialSubject`). What *is* checked:
|
23
|
+
* - the delegation chain was correct
|
24
|
+
* - all signatures are valid
|
25
|
+
* - the `controller`s of the keys (`verificationMethod`) used in the proofs to sign
|
26
|
+
* the VC capabilities and presentation are correct. I.e. the controller resolves to
|
27
|
+
* the WebId/controller identifier document (CID) which lists the key.\
|
28
|
+
* This means that *you know who signed the presentation and capabilities* on the way.
|
29
|
+
*
|
30
|
+
* NO BUSINESS LOGIC IS CHECKED.\
|
31
|
+
* It is still necessary to verify if the request itself is valid.
|
32
|
+
* There would be no error when the `credentialSubject` says: "A is allowed to read B"
|
33
|
+
* while the statement is actually made by "C" and not by "B".\
|
34
|
+
*
|
35
|
+
* @see https://moleculer.services/docs/0.13/moleculer-web.html#Authorization
|
36
|
+
*
|
37
|
+
* @example Configuration for a new route
|
38
|
+
* ```js
|
39
|
+
* ctx.call('api.addRoute', {
|
40
|
+
* path: path.join(basePath, '/your/route'),
|
41
|
+
* name: 'your-route-name',
|
42
|
+
* aliases: {
|
43
|
+
* 'GET /': 'your.action.here',
|
44
|
+
* },
|
45
|
+
* // Set to true, to run authorization action.
|
46
|
+
* authorization: true,
|
47
|
+
* // Set to true, to run authenticate action.
|
48
|
+
* authentication: false,
|
49
|
+
* });
|
50
|
+
* ```
|
51
|
+
*
|
52
|
+
* @type {import('moleculer').ServiceSchema}
|
53
|
+
*/
|
54
|
+
declare const AuthMixin: {
|
55
|
+
settings: {
|
56
|
+
baseUrl: null;
|
57
|
+
jwtPath: null;
|
58
|
+
capabilitiesPath: undefined;
|
59
|
+
registrationAllowed: boolean;
|
60
|
+
reservedUsernames: never[];
|
61
|
+
minPasswordLength: number;
|
62
|
+
minUsernameLength: number;
|
63
|
+
webIdSelection: never[];
|
64
|
+
accountSelection: never[];
|
65
|
+
accountsDataset: string;
|
66
|
+
podProvider: boolean;
|
67
|
+
};
|
68
|
+
dependencies: string[];
|
69
|
+
created(this: Moleculer.Service<Moleculer.ServiceSettingSchema>): Promise<void>;
|
70
|
+
started(this: Moleculer.Service<Moleculer.ServiceSettingSchema>): Promise<void>;
|
71
|
+
actions: {
|
72
|
+
authenticate: {
|
73
|
+
handler(ctx: Moleculer.Context<Optionalize<{
|
74
|
+
[x: string]: any;
|
75
|
+
}>, {}, Moleculer.GenericObject>): Promise<any>;
|
76
|
+
};
|
77
|
+
authorize: {
|
78
|
+
handler(ctx: Moleculer.Context<Optionalize<{
|
79
|
+
[x: string]: any;
|
80
|
+
}>, {}, Moleculer.GenericObject>): Promise<any>;
|
81
|
+
};
|
82
|
+
impersonate: {
|
83
|
+
handler(ctx: Moleculer.Context<Optionalize<{
|
84
|
+
[x: string]: any;
|
85
|
+
}>, {}, Moleculer.GenericObject>): Promise<any>;
|
86
|
+
};
|
87
|
+
};
|
88
|
+
methods: {
|
89
|
+
validateCapability(ctx: any, token: any): Promise<any>;
|
90
|
+
getStrategy(): never;
|
91
|
+
getApiRoutes(): never;
|
92
|
+
pickWebIdData(data: any): any;
|
93
|
+
pickAccountData(data: any): {
|
94
|
+
[k: string]: any;
|
95
|
+
};
|
96
|
+
};
|
97
|
+
};
|
98
|
+
export default AuthMixin;
|
@@ -0,0 +1,235 @@
|
|
1
|
+
// @ts-expect-error TS(7016): Could not find a declaration file for module 'pass... Remove this comment to see the full error message
|
2
|
+
import passport from 'passport';
|
3
|
+
// @ts-expect-error TS(2614): Module '"moleculer-web"' has no exported member 'E... Remove this comment to see the full error message
|
4
|
+
import { Errors as E } from 'moleculer-web';
|
5
|
+
import { TripleStoreAdapter } from '@semapps/triplestore';
|
6
|
+
import AuthAccountService from "../services/account.js";
|
7
|
+
import AuthJWTService from "../services/jwt.js";
|
8
|
+
/**
|
9
|
+
* Auth Mixin that handles authentication and authorization for routes
|
10
|
+
* that requested this.
|
11
|
+
*
|
12
|
+
* The authorization and authentication actions check for a valid `authorization` header.
|
13
|
+
* If the bearer token is a server-signed JWT identifying the user, `ctx.meta.tokenPayload` and
|
14
|
+
* `ctx.meta.webId` are set. Setting either `authorization` or `authentication` suffices.
|
15
|
+
*
|
16
|
+
* # Authentication
|
17
|
+
* In the `authenticate` action, the webId is set to `anon`, if no `authorization` header is present.
|
18
|
+
*
|
19
|
+
* # Authorization
|
20
|
+
* In contrast, the `authorize` action throws an unauthorized error,
|
21
|
+
* if no `authorization` header is present.
|
22
|
+
* @see https://moleculer.services/docs/0.13/moleculer-web.html#Authentication
|
23
|
+
*
|
24
|
+
* ## Capability Authorization
|
25
|
+
* Additionally, the `authorize` action supports capability authorization based on
|
26
|
+
* Verifiable Credentials (VCs), if `opts.authorizeWithCapability` is set to `true`.
|
27
|
+
*
|
28
|
+
* **WARNING**: This does not make any assertions about the validity of the capabilities'
|
29
|
+
* content (`credentialSubject`). What *is* checked:
|
30
|
+
* - the delegation chain was correct
|
31
|
+
* - all signatures are valid
|
32
|
+
* - the `controller`s of the keys (`verificationMethod`) used in the proofs to sign
|
33
|
+
* the VC capabilities and presentation are correct. I.e. the controller resolves to
|
34
|
+
* the WebId/controller identifier document (CID) which lists the key.\
|
35
|
+
* This means that *you know who signed the presentation and capabilities* on the way.
|
36
|
+
*
|
37
|
+
* NO BUSINESS LOGIC IS CHECKED.\
|
38
|
+
* It is still necessary to verify if the request itself is valid.
|
39
|
+
* There would be no error when the `credentialSubject` says: "A is allowed to read B"
|
40
|
+
* while the statement is actually made by "C" and not by "B".\
|
41
|
+
*
|
42
|
+
* @see https://moleculer.services/docs/0.13/moleculer-web.html#Authorization
|
43
|
+
*
|
44
|
+
* @example Configuration for a new route
|
45
|
+
* ```js
|
46
|
+
* ctx.call('api.addRoute', {
|
47
|
+
* path: path.join(basePath, '/your/route'),
|
48
|
+
* name: 'your-route-name',
|
49
|
+
* aliases: {
|
50
|
+
* 'GET /': 'your.action.here',
|
51
|
+
* },
|
52
|
+
* // Set to true, to run authorization action.
|
53
|
+
* authorization: true,
|
54
|
+
* // Set to true, to run authenticate action.
|
55
|
+
* authentication: false,
|
56
|
+
* });
|
57
|
+
* ```
|
58
|
+
*
|
59
|
+
* @type {import('moleculer').ServiceSchema}
|
60
|
+
*/
|
61
|
+
const AuthMixin = {
|
62
|
+
settings: {
|
63
|
+
baseUrl: null,
|
64
|
+
jwtPath: null,
|
65
|
+
capabilitiesPath: undefined,
|
66
|
+
registrationAllowed: true,
|
67
|
+
reservedUsernames: [],
|
68
|
+
minPasswordLength: 1,
|
69
|
+
minUsernameLength: 1,
|
70
|
+
webIdSelection: [],
|
71
|
+
accountSelection: [],
|
72
|
+
accountsDataset: 'settings',
|
73
|
+
podProvider: false
|
74
|
+
},
|
75
|
+
dependencies: ['api'],
|
76
|
+
async created() {
|
77
|
+
const { jwtPath, reservedUsernames, minPasswordLength, minUsernameLength, accountsDataset, podProvider } = this.settings;
|
78
|
+
// @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "auth.jwt"; se... Remove this comment to see the full error message
|
79
|
+
this.broker.createService({
|
80
|
+
mixins: [AuthJWTService],
|
81
|
+
settings: { jwtPath }
|
82
|
+
});
|
83
|
+
// @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "auth.account"... Remove this comment to see the full error message
|
84
|
+
this.broker.createService({
|
85
|
+
mixins: [AuthAccountService],
|
86
|
+
settings: { reservedUsernames, minPasswordLength, minUsernameLength },
|
87
|
+
adapter: new TripleStoreAdapter({ type: 'AuthAccount', dataset: accountsDataset })
|
88
|
+
});
|
89
|
+
},
|
90
|
+
async started() {
|
91
|
+
if (!this.passportId)
|
92
|
+
throw new Error('this.passportId must be set in the service creation.');
|
93
|
+
this.passport = passport;
|
94
|
+
this.passport.serializeUser((user, done) => {
|
95
|
+
done(null, user);
|
96
|
+
});
|
97
|
+
this.passport.deserializeUser((user, done) => {
|
98
|
+
done(null, user);
|
99
|
+
});
|
100
|
+
this.strategy = await this.getStrategy();
|
101
|
+
this.passport.use(this.passportId, this.strategy);
|
102
|
+
const { pathname: basePath } = new URL(this.settings.baseUrl);
|
103
|
+
for (const route of this.getApiRoutes(basePath)) {
|
104
|
+
await this.broker.call('api.addRoute', { route });
|
105
|
+
}
|
106
|
+
},
|
107
|
+
actions: {
|
108
|
+
authenticate: {
|
109
|
+
// See https://moleculer.services/docs/0.13/moleculer-web.html#Authentication
|
110
|
+
async handler(ctx) {
|
111
|
+
const { route, req, res } = ctx.params;
|
112
|
+
// Extract method and token from authorization header.
|
113
|
+
const [method, token] = req.headers.authorization?.split(' ') || [];
|
114
|
+
if (!token) {
|
115
|
+
// No token
|
116
|
+
// @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'.
|
117
|
+
ctx.meta.webId = 'anon';
|
118
|
+
return Promise.resolve(null);
|
119
|
+
}
|
120
|
+
if (method === 'Bearer') {
|
121
|
+
const payload = await ctx.call('auth.jwt.verifyServerSignedToken', { token });
|
122
|
+
if (payload) {
|
123
|
+
// @ts-expect-error TS(2339): Property 'tokenPayload' does not exist on type '{}... Remove this comment to see the full error message
|
124
|
+
ctx.meta.tokenPayload = payload;
|
125
|
+
// @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'.
|
126
|
+
ctx.meta.webId = payload.webId;
|
127
|
+
return Promise.resolve(payload);
|
128
|
+
}
|
129
|
+
// Check if token is a capability.
|
130
|
+
if (route.opts.authorizeWithCapability) {
|
131
|
+
return this.validateCapability(ctx, token);
|
132
|
+
}
|
133
|
+
// Invalid token
|
134
|
+
// TODO make sure token is deleted client-side
|
135
|
+
return Promise.reject(new E.UnAuthorizedError(E.ERR_INVALID_TOKEN));
|
136
|
+
}
|
137
|
+
// No valid auth method given.
|
138
|
+
// @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'.
|
139
|
+
ctx.meta.webId = 'anon';
|
140
|
+
return Promise.resolve(null);
|
141
|
+
}
|
142
|
+
},
|
143
|
+
authorize: {
|
144
|
+
// See https://moleculer.services/docs/0.13/moleculer-web.html#Authorization
|
145
|
+
async handler(ctx) {
|
146
|
+
const { route, req, res } = ctx.params;
|
147
|
+
// Extract token from authorization header (do not take the Bearer part)
|
148
|
+
/** @type {[string, string]} */
|
149
|
+
const [method, token] = req.headers.authorization && req.headers.authorization.split(' ');
|
150
|
+
if (!token) {
|
151
|
+
return Promise.reject(new E.UnAuthorizedError(E.ERR_NO_TOKEN));
|
152
|
+
}
|
153
|
+
if (method !== 'Bearer') {
|
154
|
+
return Promise.reject(new E.UnAuthorizedError(E.ERR_INVALID_TOKEN));
|
155
|
+
}
|
156
|
+
// Validate if the token was signed by server (registered user).
|
157
|
+
const serverSignedPayload = await ctx.call('auth.jwt.verifyServerSignedToken', { token });
|
158
|
+
if (serverSignedPayload) {
|
159
|
+
// @ts-expect-error TS(2339): Property 'tokenPayload' does not exist on type '{}... Remove this comment to see the full error message
|
160
|
+
ctx.meta.tokenPayload = serverSignedPayload;
|
161
|
+
// @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'.
|
162
|
+
ctx.meta.webId = serverSignedPayload.webId;
|
163
|
+
return Promise.resolve(serverSignedPayload);
|
164
|
+
}
|
165
|
+
// Check if token is a capability.
|
166
|
+
if (route.opts.authorizeWithCapability) {
|
167
|
+
return this.validateCapability(ctx, token);
|
168
|
+
}
|
169
|
+
return Promise.reject(new E.UnAuthorizedError(E.ERR_INVALID_TOKEN));
|
170
|
+
}
|
171
|
+
},
|
172
|
+
impersonate: {
|
173
|
+
async handler(ctx) {
|
174
|
+
const { webId } = ctx.params;
|
175
|
+
return await ctx.call('auth.jwt.generateServerSignedToken', {
|
176
|
+
payload: {
|
177
|
+
webId
|
178
|
+
}
|
179
|
+
});
|
180
|
+
}
|
181
|
+
}
|
182
|
+
},
|
183
|
+
methods: {
|
184
|
+
async validateCapability(ctx, token) {
|
185
|
+
// We accept VC Presentations to invoke capabilities here. It must be encoded as JWT.
|
186
|
+
// We do not use the VC-JOSE spec to sign and envelop presentations. Instead we go
|
187
|
+
// with embedded signatures. This way, the signature persists within the resource.
|
188
|
+
const hasCapabilityService = ctx.broker.registry.actions.isAvailable('crypto.vc.verifier.verifyCapabilityPresentation');
|
189
|
+
if (!hasCapabilityService)
|
190
|
+
return Promise.reject(new E.UnAuthorizedError(E.ERR_INVALID_TOKEN));
|
191
|
+
// Decode JTW to JSON.
|
192
|
+
const decodedToken = await ctx.call('auth.jwt.decodeToken', { token });
|
193
|
+
if (!decodedToken)
|
194
|
+
return Promise.reject(new E.UnAuthorizedError(E.ERR_INVALID_TOKEN));
|
195
|
+
// Verify that decoded JSON token is a valid VC presentation.
|
196
|
+
const { verified: isCapSignatureVerified, presentation: verifiedPresentation, presentationResult } = await ctx.call('crypto.vc.verifier.verifyCapabilityPresentation', {
|
197
|
+
verifiablePresentation: decodedToken,
|
198
|
+
options: {
|
199
|
+
maxChainLength: ctx.params.route.opts.maxChainLength
|
200
|
+
}
|
201
|
+
});
|
202
|
+
if (!isCapSignatureVerified)
|
203
|
+
return Promise.reject(new E.UnAuthorizedError(E.ERR_INVALID_TOKEN));
|
204
|
+
// VC Capability is verified.
|
205
|
+
ctx.meta.webId = presentationResult?.results?.[0]?.purposeResult?.holder || 'anon';
|
206
|
+
ctx.meta.authorization = { capabilityPresentation: verifiedPresentation };
|
207
|
+
return Promise.resolve(verifiedPresentation);
|
208
|
+
},
|
209
|
+
getStrategy() {
|
210
|
+
throw new Error('getStrategy must be implemented by the service');
|
211
|
+
},
|
212
|
+
getApiRoutes() {
|
213
|
+
throw new Error('getApiRoutes must be implemented by the service');
|
214
|
+
},
|
215
|
+
pickWebIdData(data) {
|
216
|
+
if (this.settings.webIdSelection.length > 0) {
|
217
|
+
return Object.fromEntries(this.settings.webIdSelection.filter((key) => key in data).map((key) => [key, data[key]]));
|
218
|
+
}
|
219
|
+
else {
|
220
|
+
// TODO do not return anything if webIdSelection is empty, to conform with pickAccountData
|
221
|
+
return data || {};
|
222
|
+
}
|
223
|
+
},
|
224
|
+
pickAccountData(data) {
|
225
|
+
if (this.settings.accountSelection.length > 0) {
|
226
|
+
return Object.fromEntries(this.settings.accountSelection.filter((key) => key in data).map((key) => [key, data[key]]));
|
227
|
+
}
|
228
|
+
else {
|
229
|
+
return {};
|
230
|
+
}
|
231
|
+
}
|
232
|
+
}
|
233
|
+
};
|
234
|
+
export default AuthMixin;
|
235
|
+
//# sourceMappingURL=auth.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../mixins/auth.ts"],"names":[],"mappings":"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"}
|
@@ -0,0 +1,76 @@
|
|
1
|
+
declare const AuthSSOMixin: {
|
2
|
+
mixins: {
|
3
|
+
settings: {
|
4
|
+
baseUrl: null;
|
5
|
+
jwtPath: null;
|
6
|
+
capabilitiesPath: undefined;
|
7
|
+
registrationAllowed: boolean;
|
8
|
+
reservedUsernames: never[];
|
9
|
+
minPasswordLength: number;
|
10
|
+
minUsernameLength: number;
|
11
|
+
webIdSelection: never[];
|
12
|
+
accountSelection: never[];
|
13
|
+
accountsDataset: string;
|
14
|
+
podProvider: boolean;
|
15
|
+
};
|
16
|
+
dependencies: string[];
|
17
|
+
created(this: Moleculer.Service<Moleculer.ServiceSettingSchema>): Promise<void>;
|
18
|
+
started(this: Moleculer.Service<Moleculer.ServiceSettingSchema>): Promise<void>;
|
19
|
+
actions: {
|
20
|
+
authenticate: {
|
21
|
+
handler(ctx: Moleculer.Context<Optionalize<{
|
22
|
+
[x: string]: any;
|
23
|
+
}>, {}, Moleculer.GenericObject>): Promise<any>;
|
24
|
+
};
|
25
|
+
authorize: {
|
26
|
+
handler(ctx: Moleculer.Context<Optionalize<{
|
27
|
+
[x: string]: any;
|
28
|
+
}>, {}, Moleculer.GenericObject>): Promise<any>;
|
29
|
+
};
|
30
|
+
impersonate: {
|
31
|
+
handler(ctx: Moleculer.Context<Optionalize<{
|
32
|
+
[x: string]: any;
|
33
|
+
}>, {}, Moleculer.GenericObject>): Promise<any>;
|
34
|
+
};
|
35
|
+
};
|
36
|
+
methods: {
|
37
|
+
validateCapability(ctx: any, token: any): Promise<any>;
|
38
|
+
getStrategy(): never;
|
39
|
+
getApiRoutes(): never;
|
40
|
+
pickWebIdData(data: any): any;
|
41
|
+
pickAccountData(data: any): {
|
42
|
+
[k: string]: any;
|
43
|
+
};
|
44
|
+
};
|
45
|
+
}[];
|
46
|
+
settings: {
|
47
|
+
baseUrl: null;
|
48
|
+
jwtPath: null;
|
49
|
+
registrationAllowed: boolean;
|
50
|
+
reservedUsernames: never[];
|
51
|
+
webIdSelection: never[];
|
52
|
+
sessionSecret: string;
|
53
|
+
selectSsoData: null;
|
54
|
+
};
|
55
|
+
actions: {
|
56
|
+
loginOrSignup: {
|
57
|
+
handler(ctx: Moleculer.Context<Optionalize<{
|
58
|
+
[x: string]: any;
|
59
|
+
}>, {}, Moleculer.GenericObject>): Promise<{
|
60
|
+
token: any;
|
61
|
+
newUser: boolean;
|
62
|
+
}>;
|
63
|
+
};
|
64
|
+
};
|
65
|
+
methods: {
|
66
|
+
getApiRoutes(basePath: any): {
|
67
|
+
path: string;
|
68
|
+
name: string;
|
69
|
+
use: any[];
|
70
|
+
aliases: {
|
71
|
+
'GET /': any[];
|
72
|
+
};
|
73
|
+
}[];
|
74
|
+
};
|
75
|
+
};
|
76
|
+
export default AuthSSOMixin;
|
@@ -0,0 +1,82 @@
|
|
1
|
+
import path from 'path';
|
2
|
+
// @ts-expect-error TS(7016): Could not find a declaration file for module 'expr... Remove this comment to see the full error message
|
3
|
+
import session from 'express-session';
|
4
|
+
import AuthMixin from "./auth.js";
|
5
|
+
import saveRedirectUrl from "../middlewares/saveRedirectUrl.js";
|
6
|
+
import redirectToFront from "../middlewares/redirectToFront.js";
|
7
|
+
import localLogout from "../middlewares/localLogout.js";
|
8
|
+
const AuthSSOMixin = {
|
9
|
+
mixins: [AuthMixin],
|
10
|
+
settings: {
|
11
|
+
baseUrl: null,
|
12
|
+
jwtPath: null,
|
13
|
+
registrationAllowed: true,
|
14
|
+
reservedUsernames: [],
|
15
|
+
webIdSelection: [],
|
16
|
+
// SSO-specific settings
|
17
|
+
sessionSecret: 's€m@pps',
|
18
|
+
selectSsoData: null
|
19
|
+
},
|
20
|
+
actions: {
|
21
|
+
loginOrSignup: {
|
22
|
+
async handler(ctx) {
|
23
|
+
const { ssoData } = ctx.params;
|
24
|
+
const profileData = this.settings.selectSsoData ? await this.settings.selectSsoData(ssoData) : ssoData;
|
25
|
+
// TODO use UUID to identify unique accounts with SSO
|
26
|
+
const existingAccounts = await ctx.call('auth.account.find', { query: { email: profileData.email } });
|
27
|
+
let accountData;
|
28
|
+
let webId;
|
29
|
+
let newUser;
|
30
|
+
if (existingAccounts.length > 0) {
|
31
|
+
accountData = existingAccounts[0];
|
32
|
+
webId = accountData.webId;
|
33
|
+
newUser = false;
|
34
|
+
// TODO update account with recent profileData information
|
35
|
+
ctx.emit('auth.connected', { webId, accountData, ssoData }, { meta: { webId: null, dataset: null } });
|
36
|
+
}
|
37
|
+
else {
|
38
|
+
if (!this.settings.registrationAllowed) {
|
39
|
+
throw new Error('registration.not-allowed');
|
40
|
+
}
|
41
|
+
accountData = await ctx.call('auth.account.create', {
|
42
|
+
uuid: profileData.uuid,
|
43
|
+
email: profileData.email,
|
44
|
+
username: profileData.username
|
45
|
+
});
|
46
|
+
webId = await ctx.call('webid.createWebId', this.pickWebIdData({ nick: accountData.username, ...profileData }));
|
47
|
+
newUser = true;
|
48
|
+
// Link the webId with the account
|
49
|
+
await ctx.call('auth.account.attachWebId', { accountUri: accountData['@id'], webId });
|
50
|
+
ctx.emit('auth.registered', { webId, profileData, accountData, ssoData }, { meta: { webId: null, dataset: null } });
|
51
|
+
}
|
52
|
+
const token = await ctx.call('auth.jwt.generateServerSignedToken', { payload: { webId } });
|
53
|
+
return { token, newUser };
|
54
|
+
}
|
55
|
+
}
|
56
|
+
},
|
57
|
+
methods: {
|
58
|
+
getApiRoutes(basePath) {
|
59
|
+
const sessionMiddleware = session({ secret: this.settings.sessionSecret, maxAge: null });
|
60
|
+
return [
|
61
|
+
{
|
62
|
+
path: path.join(basePath, '/auth'),
|
63
|
+
name: 'auth',
|
64
|
+
use: [sessionMiddleware, this.passport.initialize(), this.passport.session()],
|
65
|
+
aliases: {
|
66
|
+
'GET /': [saveRedirectUrl, this.passport.authenticate(this.passportId, { session: false }), redirectToFront]
|
67
|
+
}
|
68
|
+
},
|
69
|
+
{
|
70
|
+
path: path.join(basePath, '/auth/logout'),
|
71
|
+
name: 'auth-logout',
|
72
|
+
use: [sessionMiddleware, this.passport.initialize(), this.passport.session()],
|
73
|
+
aliases: {
|
74
|
+
'GET /': [saveRedirectUrl, localLogout, redirectToFront]
|
75
|
+
}
|
76
|
+
}
|
77
|
+
];
|
78
|
+
}
|
79
|
+
}
|
80
|
+
};
|
81
|
+
export default AuthSSOMixin;
|
82
|
+
//# sourceMappingURL=auth.sso.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"auth.sso.js","sourceRoot":"","sources":["../../mixins/auth.sso.ts"],"names":[],"mappings":"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"}
|