@jskit-ai/auth-core 0.1.54 → 0.1.56
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/package.descriptor.mjs +2 -2
- package/package.json +3 -3
- package/src/server/authPolicyContextResolverRegistry.js +5 -0
- package/src/server/providers/FastifyAuthPolicyServiceProvider.js +11 -27
- package/src/shared/commands/authCommandValidators.js +231 -191
- package/src/shared/commands/authDevLoginAsCommand.js +19 -19
- package/src/shared/commands/authLoginOAuthCompleteCommand.js +26 -31
- package/src/shared/commands/authLoginOAuthStartCommand.js +29 -34
- package/src/shared/commands/authLoginOtpRequestCommand.js +18 -23
- package/src/shared/commands/authLoginOtpVerifyCommand.js +29 -22
- package/src/shared/commands/authLoginPasswordCommand.js +18 -23
- package/src/shared/commands/authLogoutCommand.js +8 -7
- package/src/shared/commands/authPasswordRecoveryCompleteCommand.js +33 -23
- package/src/shared/commands/authPasswordResetCommand.js +16 -21
- package/src/shared/commands/authPasswordResetRequestCommand.js +16 -21
- package/src/shared/commands/authRegisterCommand.js +18 -23
- package/src/shared/commands/authRegisterConfirmationResendCommand.js +15 -20
- package/src/shared/commands/authSessionReadCommand.js +11 -10
- package/test/authPolicyContextResolverRegistry.test.js +39 -1
- package/test/commandValidators.test.js +68 -2
- package/test/providerRuntime.test.js +20 -8
package/package.descriptor.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export default Object.freeze({
|
|
2
2
|
"packageVersion": 1,
|
|
3
3
|
"packageId": "@jskit-ai/auth-core",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.56",
|
|
5
5
|
"kind": "runtime",
|
|
6
6
|
"dependsOn": [
|
|
7
7
|
"@jskit-ai/value-app-config-shared"
|
|
@@ -69,7 +69,7 @@ export default Object.freeze({
|
|
|
69
69
|
"mutations": {
|
|
70
70
|
"dependencies": {
|
|
71
71
|
"runtime": {
|
|
72
|
-
"@jskit-ai/kernel": "0.1.
|
|
72
|
+
"@jskit-ai/kernel": "0.1.57",
|
|
73
73
|
"@fastify/cookie": "^11.0.2",
|
|
74
74
|
"@fastify/csrf-protection": "^7.1.0",
|
|
75
75
|
"@fastify/rate-limit": "^10.3.0"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jskit-ai/auth-core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.56",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "node --test"
|
|
@@ -46,10 +46,10 @@
|
|
|
46
46
|
"./shared/commands/authSessionReadCommand": "./src/shared/commands/authSessionReadCommand.js"
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@jskit-ai/kernel": "0.1.
|
|
49
|
+
"@jskit-ai/kernel": "0.1.57",
|
|
50
50
|
"@fastify/cookie": "^11.0.2",
|
|
51
51
|
"@fastify/csrf-protection": "^7.1.0",
|
|
52
52
|
"@fastify/rate-limit": "^10.3.0",
|
|
53
|
-
"
|
|
53
|
+
"json-rest-schema": "1.x.x"
|
|
54
54
|
}
|
|
55
55
|
}
|
|
@@ -50,6 +50,10 @@ function resolveAuthPolicyContextResolvers(scope) {
|
|
|
50
50
|
.map((entry) => entry.resolver);
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
+
function resolveComposedAuthPolicyContextResolver(scope) {
|
|
54
|
+
return composeAuthPolicyContextResolvers(resolveAuthPolicyContextResolvers(scope));
|
|
55
|
+
}
|
|
56
|
+
|
|
53
57
|
function mergeAuthPolicyContexts(contexts = []) {
|
|
54
58
|
const merged = {};
|
|
55
59
|
let hasValues = false;
|
|
@@ -120,6 +124,7 @@ export {
|
|
|
120
124
|
AUTH_POLICY_CONTEXT_RESOLVER_TAG,
|
|
121
125
|
registerAuthPolicyContextResolver,
|
|
122
126
|
resolveAuthPolicyContextResolvers,
|
|
127
|
+
resolveComposedAuthPolicyContextResolver,
|
|
123
128
|
mergeAuthPolicyContexts,
|
|
124
129
|
composeAuthPolicyContextResolvers
|
|
125
130
|
};
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { registerActionContextContributor } from "@jskit-ai/kernel/server/actions";
|
|
2
2
|
import { registerRouteVisibilityResolver } from "@jskit-ai/kernel/server/http";
|
|
3
3
|
import {
|
|
4
|
-
|
|
5
|
-
resolveAuthPolicyContextResolvers
|
|
4
|
+
resolveComposedAuthPolicyContextResolver
|
|
6
5
|
} from "../authPolicyContextResolverRegistry.js";
|
|
7
6
|
import { authPolicyPlugin } from "../lib/plugin.js";
|
|
8
7
|
import { createAuthActionContextContributor } from "../lib/actionContextContributor.js";
|
|
@@ -77,33 +76,10 @@ class FastifyAuthPolicyServiceProvider {
|
|
|
77
76
|
|
|
78
77
|
const env = app.has("jskit.env") ? app.make("jskit.env") : {};
|
|
79
78
|
const fastify = app.make("jskit.fastify");
|
|
80
|
-
const authService = app.make("authService");
|
|
81
|
-
const legacyResolveContext =
|
|
82
|
-
typeof app.has === "function" && app.has("auth.policy.contextResolver")
|
|
83
|
-
? app.make("auth.policy.contextResolver")
|
|
84
|
-
: null;
|
|
85
|
-
|
|
86
|
-
if (legacyResolveContext != null && typeof legacyResolveContext !== "function") {
|
|
87
|
-
throw new Error(
|
|
88
|
-
"FastifyAuthPolicyServiceProvider requires auth.policy.contextResolver to be a function when provided."
|
|
89
|
-
);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
const resolveContext = composeAuthPolicyContextResolvers([
|
|
93
|
-
...resolveAuthPolicyContextResolvers(app),
|
|
94
|
-
...(legacyResolveContext
|
|
95
|
-
? [
|
|
96
|
-
{
|
|
97
|
-
resolverId: "legacy.auth.policy.contextResolver",
|
|
98
|
-
order: 1000,
|
|
99
|
-
resolveAuthPolicyContext: legacyResolveContext
|
|
100
|
-
}
|
|
101
|
-
]
|
|
102
|
-
: [])
|
|
103
|
-
]);
|
|
104
79
|
|
|
105
80
|
const pluginDeps = {
|
|
106
81
|
resolveActor: async (request) => {
|
|
82
|
+
const authService = app.make("authService");
|
|
107
83
|
if (authService && typeof authService.authenticateRequest === "function") {
|
|
108
84
|
return authService.authenticateRequest(request);
|
|
109
85
|
}
|
|
@@ -114,7 +90,15 @@ class FastifyAuthPolicyServiceProvider {
|
|
|
114
90
|
};
|
|
115
91
|
},
|
|
116
92
|
hasPermission: defaultHasPermission,
|
|
117
|
-
|
|
93
|
+
resolveContext: async (input = {}) => {
|
|
94
|
+
const resolveContext = resolveComposedAuthPolicyContextResolver(app);
|
|
95
|
+
|
|
96
|
+
if (typeof resolveContext !== "function") {
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return resolveContext(input);
|
|
101
|
+
}
|
|
118
102
|
};
|
|
119
103
|
|
|
120
104
|
const plugin = authPolicyPlugin(
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createSchema } from "json-rest-schema";
|
|
2
|
+
import { deepFreeze } from "@jskit-ai/kernel/shared/support/deepFreeze";
|
|
2
3
|
import {
|
|
3
4
|
AUTH_ACCESS_TOKEN_MAX_LENGTH,
|
|
4
5
|
AUTH_EMAIL_MAX_LENGTH,
|
|
@@ -13,240 +14,279 @@ import {
|
|
|
13
14
|
import { AUTH_METHOD_IDS, AUTH_METHOD_KINDS } from "../authMethods.js";
|
|
14
15
|
import { OAUTH_PROVIDER_ID_PATTERN } from "../oauthProviders.js";
|
|
15
16
|
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
})
|
|
17
|
+
const oauthProviderFieldDefinition = deepFreeze({
|
|
18
|
+
type: "string",
|
|
19
|
+
minLength: 2,
|
|
20
|
+
maxLength: 32,
|
|
21
|
+
pattern: OAUTH_PROVIDER_ID_PATTERN
|
|
22
22
|
});
|
|
23
23
|
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
})
|
|
24
|
+
const authMethodIdFieldDefinition = deepFreeze({
|
|
25
|
+
type: "string",
|
|
26
|
+
minLength: 3,
|
|
27
|
+
maxLength: 38,
|
|
28
|
+
pattern: `^(?:${AUTH_METHOD_IDS.join("|")}|oauth:${OAUTH_PROVIDER_ID_PATTERN.slice(1, -1)})$`
|
|
30
29
|
});
|
|
31
30
|
|
|
32
|
-
const
|
|
33
|
-
|
|
31
|
+
const authMethodKindFieldDefinition = deepFreeze({
|
|
32
|
+
type: "string",
|
|
33
|
+
enum: AUTH_METHOD_KINDS
|
|
34
34
|
});
|
|
35
35
|
|
|
36
36
|
const OAUTH_RETURN_TO_PATTERN = "^(?:/(?!/).*$|https?://[^\\s]+)$";
|
|
37
37
|
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
})
|
|
38
|
+
const oauthReturnToFieldDefinition = deepFreeze({
|
|
39
|
+
type: "string",
|
|
40
|
+
minLength: 1,
|
|
41
|
+
maxLength: 1024,
|
|
42
|
+
pattern: OAUTH_RETURN_TO_PATTERN
|
|
44
43
|
});
|
|
45
44
|
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
45
|
+
const authEmailFieldDefinition = deepFreeze({
|
|
46
|
+
type: "string",
|
|
47
|
+
lowercase: true,
|
|
48
|
+
minLength: AUTH_EMAIL_MIN_LENGTH,
|
|
49
|
+
maxLength: AUTH_EMAIL_MAX_LENGTH,
|
|
50
|
+
pattern: AUTH_EMAIL_PATTERN
|
|
52
51
|
});
|
|
53
52
|
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
})
|
|
53
|
+
const authPasswordFieldDefinition = deepFreeze({
|
|
54
|
+
type: "string",
|
|
55
|
+
minLength: AUTH_PASSWORD_MIN_LENGTH,
|
|
56
|
+
maxLength: AUTH_PASSWORD_MAX_LENGTH
|
|
59
57
|
});
|
|
60
58
|
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
})
|
|
59
|
+
const authLoginPasswordFieldDefinition = deepFreeze({
|
|
60
|
+
type: "string",
|
|
61
|
+
minLength: 1,
|
|
62
|
+
maxLength: AUTH_LOGIN_PASSWORD_MAX_LENGTH
|
|
66
63
|
});
|
|
67
64
|
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
})
|
|
65
|
+
const authRecoveryTokenFieldDefinition = deepFreeze({
|
|
66
|
+
type: "string",
|
|
67
|
+
minLength: 1,
|
|
68
|
+
maxLength: AUTH_RECOVERY_TOKEN_MAX_LENGTH
|
|
73
69
|
});
|
|
74
70
|
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
})
|
|
71
|
+
const authAccessTokenFieldDefinition = deepFreeze({
|
|
72
|
+
type: "string",
|
|
73
|
+
minLength: 1,
|
|
74
|
+
maxLength: AUTH_ACCESS_TOKEN_MAX_LENGTH
|
|
80
75
|
});
|
|
81
76
|
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
})
|
|
77
|
+
const authRefreshTokenFieldDefinition = deepFreeze({
|
|
78
|
+
type: "string",
|
|
79
|
+
minLength: 1,
|
|
80
|
+
maxLength: AUTH_REFRESH_TOKEN_MAX_LENGTH
|
|
87
81
|
});
|
|
88
82
|
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
ok: Type.Boolean()
|
|
93
|
-
},
|
|
94
|
-
{
|
|
95
|
-
additionalProperties: false
|
|
96
|
-
}
|
|
97
|
-
)
|
|
83
|
+
const oauthProviderValidator = deepFreeze({
|
|
84
|
+
type: "string",
|
|
85
|
+
...oauthProviderFieldDefinition
|
|
98
86
|
});
|
|
99
87
|
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
ok: Type.Boolean(),
|
|
104
|
-
message: Type.String({ minLength: 1 })
|
|
105
|
-
},
|
|
106
|
-
{
|
|
107
|
-
additionalProperties: false
|
|
108
|
-
}
|
|
109
|
-
)
|
|
88
|
+
const authMethodIdValidator = deepFreeze({
|
|
89
|
+
type: "string",
|
|
90
|
+
...authMethodIdFieldDefinition
|
|
110
91
|
});
|
|
111
92
|
|
|
112
|
-
const
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
ok: Type.Boolean(),
|
|
116
|
-
requiresEmailConfirmation: Type.Boolean(),
|
|
117
|
-
username: Type.Optional(Type.String({ minLength: 1, maxLength: 120 })),
|
|
118
|
-
message: Type.Optional(Type.String({ minLength: 1 }))
|
|
119
|
-
},
|
|
120
|
-
{
|
|
121
|
-
additionalProperties: false
|
|
122
|
-
}
|
|
123
|
-
)
|
|
93
|
+
const authMethodKindValidator = deepFreeze({
|
|
94
|
+
type: "string",
|
|
95
|
+
enum: AUTH_METHOD_KINDS
|
|
124
96
|
});
|
|
125
97
|
|
|
126
|
-
const
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
ok: Type.Boolean(),
|
|
130
|
-
username: Type.String({ minLength: 1, maxLength: 120 })
|
|
131
|
-
},
|
|
132
|
-
{
|
|
133
|
-
additionalProperties: false
|
|
134
|
-
}
|
|
135
|
-
)
|
|
98
|
+
const oauthReturnToValidator = deepFreeze({
|
|
99
|
+
type: "string",
|
|
100
|
+
...oauthReturnToFieldDefinition
|
|
136
101
|
});
|
|
137
102
|
|
|
138
|
-
const
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
ok: Type.Boolean(),
|
|
142
|
-
username: Type.String({ minLength: 1, maxLength: 120 }),
|
|
143
|
-
email: authEmailValidator.schema
|
|
144
|
-
},
|
|
145
|
-
{
|
|
146
|
-
additionalProperties: false
|
|
147
|
-
}
|
|
148
|
-
)
|
|
103
|
+
const authEmailValidator = deepFreeze({
|
|
104
|
+
type: "string",
|
|
105
|
+
...authEmailFieldDefinition
|
|
149
106
|
});
|
|
150
107
|
|
|
151
|
-
const
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
ok: Type.Boolean(),
|
|
155
|
-
provider: Type.Optional(oauthProviderValidator.schema),
|
|
156
|
-
username: Type.String({ minLength: 1, maxLength: 120 }),
|
|
157
|
-
email: authEmailValidator.schema
|
|
158
|
-
},
|
|
159
|
-
{
|
|
160
|
-
additionalProperties: false
|
|
161
|
-
}
|
|
162
|
-
)
|
|
108
|
+
const authPasswordValidator = deepFreeze({
|
|
109
|
+
type: "string",
|
|
110
|
+
...authPasswordFieldDefinition
|
|
163
111
|
});
|
|
164
112
|
|
|
165
|
-
const
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
ok: Type.Boolean(),
|
|
169
|
-
userId: Type.String({ minLength: 1 }),
|
|
170
|
-
username: Type.String({ minLength: 1, maxLength: 120 }),
|
|
171
|
-
email: authEmailValidator.schema
|
|
172
|
-
},
|
|
173
|
-
{
|
|
174
|
-
additionalProperties: false
|
|
175
|
-
}
|
|
176
|
-
)
|
|
113
|
+
const authLoginPasswordValidator = deepFreeze({
|
|
114
|
+
type: "string",
|
|
115
|
+
...authLoginPasswordFieldDefinition
|
|
177
116
|
});
|
|
178
117
|
|
|
179
|
-
const
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
ok: Type.Boolean()
|
|
183
|
-
},
|
|
184
|
-
{
|
|
185
|
-
additionalProperties: false
|
|
186
|
-
}
|
|
187
|
-
)
|
|
118
|
+
const authRecoveryTokenValidator = deepFreeze({
|
|
119
|
+
type: "string",
|
|
120
|
+
...authRecoveryTokenFieldDefinition
|
|
188
121
|
});
|
|
189
122
|
|
|
190
|
-
const
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
id: oauthProviderValidator.schema,
|
|
194
|
-
label: Type.String({ minLength: 1, maxLength: 120 })
|
|
195
|
-
},
|
|
196
|
-
{
|
|
197
|
-
additionalProperties: false
|
|
198
|
-
}
|
|
199
|
-
)
|
|
200
|
-
});
|
|
201
|
-
|
|
202
|
-
const sessionResponseValidator = Object.freeze({
|
|
203
|
-
schema: Type.Object(
|
|
204
|
-
{
|
|
205
|
-
authenticated: Type.Boolean(),
|
|
206
|
-
username: Type.Optional(Type.String({ minLength: 1, maxLength: 120 })),
|
|
207
|
-
email: Type.Optional(authEmailValidator.schema),
|
|
208
|
-
permissions: Type.Optional(Type.Array(Type.String({ minLength: 1, maxLength: 200 }))),
|
|
209
|
-
csrfToken: Type.String({ minLength: 1 }),
|
|
210
|
-
oauthProviders: Type.Array(oauthProviderCatalogEntryValidator.schema),
|
|
211
|
-
oauthDefaultProvider: Type.Union([oauthProviderValidator.schema, Type.Null()])
|
|
212
|
-
},
|
|
213
|
-
{
|
|
214
|
-
additionalProperties: false
|
|
215
|
-
}
|
|
216
|
-
)
|
|
123
|
+
const authAccessTokenValidator = deepFreeze({
|
|
124
|
+
type: "string",
|
|
125
|
+
...authAccessTokenFieldDefinition
|
|
217
126
|
});
|
|
218
127
|
|
|
219
|
-
const
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
|
|
128
|
+
const authRefreshTokenValidator = deepFreeze({
|
|
129
|
+
type: "string",
|
|
130
|
+
...authRefreshTokenFieldDefinition
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
const okOutputValidator = deepFreeze({
|
|
134
|
+
schema: createSchema({
|
|
135
|
+
ok: { type: "boolean", required: true }
|
|
136
|
+
}),
|
|
137
|
+
mode: "replace"
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
const okMessageOutputValidator = deepFreeze({
|
|
141
|
+
schema: createSchema({
|
|
142
|
+
ok: { type: "boolean", required: true },
|
|
143
|
+
message: { type: "string", required: true, minLength: 1 }
|
|
144
|
+
}),
|
|
145
|
+
mode: "replace"
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
const registerOutputValidator = deepFreeze({
|
|
149
|
+
schema: createSchema({
|
|
150
|
+
ok: { type: "boolean", required: true },
|
|
151
|
+
requiresEmailConfirmation: { type: "boolean", required: true },
|
|
152
|
+
username: { type: "string", required: false, minLength: 1, maxLength: 120 },
|
|
153
|
+
message: { type: "string", required: false, minLength: 1 }
|
|
154
|
+
}),
|
|
155
|
+
mode: "replace"
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
const loginOutputValidator = deepFreeze({
|
|
159
|
+
schema: createSchema({
|
|
160
|
+
ok: { type: "boolean", required: true },
|
|
161
|
+
username: { type: "string", required: true, minLength: 1, maxLength: 120 }
|
|
162
|
+
}),
|
|
163
|
+
mode: "replace"
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
const otpVerifyOutputValidator = deepFreeze({
|
|
167
|
+
schema: createSchema({
|
|
168
|
+
ok: { type: "boolean", required: true },
|
|
169
|
+
username: { type: "string", required: true, minLength: 1, maxLength: 120 },
|
|
170
|
+
email: { ...authEmailFieldDefinition, required: true }
|
|
171
|
+
}),
|
|
172
|
+
mode: "replace"
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
const oauthCompleteOutputValidator = deepFreeze({
|
|
176
|
+
schema: createSchema({
|
|
177
|
+
ok: { type: "boolean", required: true },
|
|
178
|
+
provider: { ...oauthProviderFieldDefinition, required: false },
|
|
179
|
+
username: { type: "string", required: true, minLength: 1, maxLength: 120 },
|
|
180
|
+
email: { ...authEmailFieldDefinition, required: true }
|
|
181
|
+
}),
|
|
182
|
+
mode: "replace"
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
const devLoginAsOutputValidator = deepFreeze({
|
|
186
|
+
schema: createSchema({
|
|
187
|
+
ok: { type: "boolean", required: true },
|
|
188
|
+
userId: { type: "string", required: true, minLength: 1 },
|
|
189
|
+
username: { type: "string", required: true, minLength: 1, maxLength: 120 },
|
|
190
|
+
email: { ...authEmailFieldDefinition, required: true }
|
|
191
|
+
}),
|
|
192
|
+
mode: "replace"
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
const logoutOutputValidator = deepFreeze({
|
|
196
|
+
schema: createSchema({
|
|
197
|
+
ok: { type: "boolean", required: true }
|
|
198
|
+
}),
|
|
199
|
+
mode: "replace"
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
const oauthProviderCatalogEntrySchema = createSchema({
|
|
203
|
+
id: { ...oauthProviderFieldDefinition, required: true },
|
|
204
|
+
label: { type: "string", required: true, minLength: 1, maxLength: 120 }
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
const oauthProviderCatalogEntryOutputValidator = deepFreeze({
|
|
208
|
+
schema: oauthProviderCatalogEntrySchema,
|
|
209
|
+
mode: "replace"
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
const sessionOutputSchema = createSchema({
|
|
213
|
+
authenticated: { type: "boolean", required: true },
|
|
214
|
+
username: { type: "string", required: false, minLength: 1, maxLength: 120 },
|
|
215
|
+
email: { ...authEmailFieldDefinition, required: false },
|
|
216
|
+
permissions: {
|
|
217
|
+
type: "array",
|
|
218
|
+
required: false,
|
|
219
|
+
items: {
|
|
220
|
+
type: "string",
|
|
221
|
+
minLength: 1,
|
|
222
|
+
maxLength: 200
|
|
229
223
|
}
|
|
230
|
-
|
|
224
|
+
},
|
|
225
|
+
csrfToken: { type: "string", required: true, minLength: 1 },
|
|
226
|
+
oauthProviders: {
|
|
227
|
+
type: "array",
|
|
228
|
+
required: true,
|
|
229
|
+
items: oauthProviderCatalogEntrySchema
|
|
230
|
+
},
|
|
231
|
+
oauthDefaultProvider: {
|
|
232
|
+
...oauthProviderFieldDefinition,
|
|
233
|
+
required: true,
|
|
234
|
+
nullable: true
|
|
235
|
+
}
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
const sessionOutputValidator = deepFreeze({
|
|
239
|
+
schema: sessionOutputSchema,
|
|
240
|
+
mode: "replace"
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
const sessionUnavailableOutputSchema = createSchema({
|
|
244
|
+
error: { type: "string", required: true, minLength: 1 },
|
|
245
|
+
csrfToken: { type: "string", required: true, minLength: 1 },
|
|
246
|
+
oauthProviders: {
|
|
247
|
+
type: "array",
|
|
248
|
+
required: true,
|
|
249
|
+
items: oauthProviderCatalogEntrySchema
|
|
250
|
+
},
|
|
251
|
+
oauthDefaultProvider: {
|
|
252
|
+
...oauthProviderFieldDefinition,
|
|
253
|
+
required: true,
|
|
254
|
+
nullable: true
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
const sessionUnavailableOutputValidator = deepFreeze({
|
|
259
|
+
schema: sessionUnavailableOutputSchema,
|
|
260
|
+
mode: "replace"
|
|
231
261
|
});
|
|
232
262
|
|
|
233
263
|
function createCommandMessages({
|
|
234
264
|
fields = {},
|
|
235
265
|
defaultMessage = "Invalid value."
|
|
236
266
|
} = {}) {
|
|
237
|
-
return
|
|
267
|
+
return deepFreeze({
|
|
238
268
|
apiValidation: "Validation failed.",
|
|
239
|
-
fields:
|
|
269
|
+
fields: {
|
|
240
270
|
...(fields && typeof fields === "object" ? fields : {})
|
|
241
|
-
}
|
|
242
|
-
keywords:
|
|
271
|
+
},
|
|
272
|
+
keywords: {
|
|
243
273
|
additionalProperties: "Unexpected field."
|
|
244
|
-
}
|
|
274
|
+
},
|
|
245
275
|
default: String(defaultMessage || "Invalid value.")
|
|
246
276
|
});
|
|
247
277
|
}
|
|
248
278
|
|
|
249
279
|
export {
|
|
280
|
+
authEmailFieldDefinition,
|
|
281
|
+
authPasswordFieldDefinition,
|
|
282
|
+
authLoginPasswordFieldDefinition,
|
|
283
|
+
authRecoveryTokenFieldDefinition,
|
|
284
|
+
authAccessTokenFieldDefinition,
|
|
285
|
+
authRefreshTokenFieldDefinition,
|
|
286
|
+
oauthProviderFieldDefinition,
|
|
287
|
+
authMethodIdFieldDefinition,
|
|
288
|
+
authMethodKindFieldDefinition,
|
|
289
|
+
oauthReturnToFieldDefinition,
|
|
250
290
|
authEmailValidator,
|
|
251
291
|
authPasswordValidator,
|
|
252
292
|
authLoginPasswordValidator,
|
|
@@ -257,16 +297,16 @@ export {
|
|
|
257
297
|
authMethodIdValidator,
|
|
258
298
|
authMethodKindValidator,
|
|
259
299
|
oauthReturnToValidator,
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
300
|
+
okOutputValidator,
|
|
301
|
+
okMessageOutputValidator,
|
|
302
|
+
registerOutputValidator,
|
|
303
|
+
loginOutputValidator,
|
|
304
|
+
otpVerifyOutputValidator,
|
|
305
|
+
oauthCompleteOutputValidator,
|
|
306
|
+
devLoginAsOutputValidator,
|
|
307
|
+
logoutOutputValidator,
|
|
308
|
+
oauthProviderCatalogEntryOutputValidator,
|
|
309
|
+
sessionOutputValidator,
|
|
310
|
+
sessionUnavailableOutputValidator,
|
|
271
311
|
createCommandMessages
|
|
272
312
|
};
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createSchema } from "json-rest-schema";
|
|
2
2
|
import { recordIdInputSchema } from "@jskit-ai/kernel/shared/validators";
|
|
3
|
-
import {
|
|
3
|
+
import { deepFreeze } from "@jskit-ai/kernel/shared/support/deepFreeze";
|
|
4
4
|
import {
|
|
5
5
|
authEmailValidator,
|
|
6
6
|
createCommandMessages,
|
|
7
|
-
|
|
7
|
+
devLoginAsOutputValidator
|
|
8
8
|
} from "./authCommandValidators.js";
|
|
9
9
|
|
|
10
10
|
const AUTH_DEV_LOGIN_AS_MESSAGES = createCommandMessages({
|
|
@@ -21,18 +21,18 @@ const AUTH_DEV_LOGIN_AS_MESSAGES = createCommandMessages({
|
|
|
21
21
|
defaultMessage: "Provide a valid user id or email."
|
|
22
22
|
});
|
|
23
23
|
|
|
24
|
-
const authDevLoginAsBodyValidator =
|
|
25
|
-
schema:
|
|
26
|
-
{
|
|
27
|
-
|
|
28
|
-
|
|
24
|
+
const authDevLoginAsBodyValidator = deepFreeze({
|
|
25
|
+
schema: createSchema({
|
|
26
|
+
userId: {
|
|
27
|
+
...recordIdInputSchema,
|
|
28
|
+
required: false
|
|
29
29
|
},
|
|
30
|
-
{
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
email: {
|
|
31
|
+
...authEmailValidator,
|
|
32
|
+
required: false
|
|
33
33
|
}
|
|
34
|
-
),
|
|
35
|
-
|
|
34
|
+
}),
|
|
35
|
+
mode: "patch",
|
|
36
36
|
messages: {
|
|
37
37
|
...AUTH_DEV_LOGIN_AS_MESSAGES,
|
|
38
38
|
keywords: {
|
|
@@ -42,16 +42,16 @@ const authDevLoginAsBodyValidator = Object.freeze({
|
|
|
42
42
|
}
|
|
43
43
|
});
|
|
44
44
|
|
|
45
|
-
const authDevLoginAsCommand =
|
|
45
|
+
const authDevLoginAsCommand = deepFreeze({
|
|
46
46
|
command: "auth.dev.loginAs",
|
|
47
|
-
operation:
|
|
47
|
+
operation: {
|
|
48
48
|
method: "POST",
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
body: authDevLoginAsBodyValidator,
|
|
50
|
+
response: devLoginAsOutputValidator,
|
|
51
51
|
messages: AUTH_DEV_LOGIN_AS_MESSAGES,
|
|
52
52
|
idempotent: false,
|
|
53
|
-
invalidates:
|
|
54
|
-
}
|
|
53
|
+
invalidates: ["auth.session.read"]
|
|
54
|
+
}
|
|
55
55
|
});
|
|
56
56
|
|
|
57
57
|
export { AUTH_DEV_LOGIN_AS_MESSAGES, authDevLoginAsBodyValidator, authDevLoginAsCommand };
|