@jskit-ai/auth-core 0.1.4

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.
Files changed (55) hide show
  1. package/package.descriptor.mjs +95 -0
  2. package/package.json +51 -0
  3. package/src/client/authApi.js +1 -0
  4. package/src/client/index.js +2 -0
  5. package/src/client/providers/AccessCoreClientProvider.js +23 -0
  6. package/src/client/providers/FastifyAuthPolicyClientProvider.js +13 -0
  7. package/src/client/signOutFlow.js +1 -0
  8. package/src/server/inviteTokens.js +41 -0
  9. package/src/server/lib/actionContextContributor.js +36 -0
  10. package/src/server/lib/authPolicySupport.js +38 -0
  11. package/src/server/lib/errors.js +20 -0
  12. package/src/server/lib/index.js +3 -0
  13. package/src/server/lib/objectUtils.js +5 -0
  14. package/src/server/lib/plugin.js +247 -0
  15. package/src/server/lib/routeMeta.js +64 -0
  16. package/src/server/lib/routeVisibilityResolver.js +25 -0
  17. package/src/server/lib/tokens.js +3 -0
  18. package/src/server/membershipAccess.js +67 -0
  19. package/src/server/providers/AccessCoreServiceProvider.js +35 -0
  20. package/src/server/providers/FastifyAuthPolicyServiceProvider.js +124 -0
  21. package/src/server/utils.js +26 -0
  22. package/src/server/validators.js +183 -0
  23. package/src/shared/authApi.js +50 -0
  24. package/src/shared/authConstraints.js +13 -0
  25. package/src/shared/authMethods.js +170 -0
  26. package/src/shared/authPaths.js +24 -0
  27. package/src/shared/commands/authCommandValidators.js +255 -0
  28. package/src/shared/commands/authLoginOAuthCompleteCommand.js +68 -0
  29. package/src/shared/commands/authLoginOAuthStartCommand.js +72 -0
  30. package/src/shared/commands/authLoginOtpRequestCommand.js +56 -0
  31. package/src/shared/commands/authLoginOtpVerifyCommand.js +64 -0
  32. package/src/shared/commands/authLoginPasswordCommand.js +57 -0
  33. package/src/shared/commands/authLogoutCommand.js +23 -0
  34. package/src/shared/commands/authPasswordRecoveryCompleteCommand.js +67 -0
  35. package/src/shared/commands/authPasswordResetCommand.js +49 -0
  36. package/src/shared/commands/authPasswordResetRequestCommand.js +50 -0
  37. package/src/shared/commands/authRegisterCommand.js +57 -0
  38. package/src/shared/commands/authSessionReadCommand.js +26 -0
  39. package/src/shared/index.js +3 -0
  40. package/src/shared/inputNormalization.js +1 -0
  41. package/src/shared/inviteTokens.js +38 -0
  42. package/src/shared/oauthCallbackParams.js +5 -0
  43. package/src/shared/oauthProviders.js +66 -0
  44. package/src/shared/signOutFlow.js +28 -0
  45. package/test/actionContextContributor.test.js +44 -0
  46. package/test/authApi.test.js +47 -0
  47. package/test/authMethods.test.js +95 -0
  48. package/test/authPaths.test.js +17 -0
  49. package/test/commandValidators.test.js +33 -0
  50. package/test/plugin.test.js +250 -0
  51. package/test/providerRuntime.test.js +114 -0
  52. package/test/routeMeta.test.js +95 -0
  53. package/test/routeVisibilityResolver.test.js +34 -0
  54. package/test/serverUtils.test.js +28 -0
  55. package/test/signOutFlow.test.js +67 -0
@@ -0,0 +1,255 @@
1
+ import { Type } from "typebox";
2
+ import {
3
+ AUTH_ACCESS_TOKEN_MAX_LENGTH,
4
+ AUTH_EMAIL_MAX_LENGTH,
5
+ AUTH_EMAIL_MIN_LENGTH,
6
+ AUTH_EMAIL_PATTERN,
7
+ AUTH_LOGIN_PASSWORD_MAX_LENGTH,
8
+ AUTH_PASSWORD_MAX_LENGTH,
9
+ AUTH_PASSWORD_MIN_LENGTH,
10
+ AUTH_RECOVERY_TOKEN_MAX_LENGTH,
11
+ AUTH_REFRESH_TOKEN_MAX_LENGTH
12
+ } from "../authConstraints.js";
13
+ import { AUTH_METHOD_IDS, AUTH_METHOD_KINDS } from "../authMethods.js";
14
+ import { OAUTH_PROVIDER_ID_PATTERN } from "../oauthProviders.js";
15
+
16
+ const oauthProviderValidator = Object.freeze({
17
+ schema: Type.String({
18
+ minLength: 2,
19
+ maxLength: 32,
20
+ pattern: OAUTH_PROVIDER_ID_PATTERN
21
+ })
22
+ });
23
+
24
+ const authMethodIdValidator = Object.freeze({
25
+ schema: Type.String({
26
+ minLength: 3,
27
+ maxLength: 38,
28
+ pattern: `^(?:${AUTH_METHOD_IDS.join("|")}|oauth:${OAUTH_PROVIDER_ID_PATTERN.slice(1, -1)})$`
29
+ })
30
+ });
31
+
32
+ const authMethodKindValidator = Object.freeze({
33
+ schema: Type.Union(AUTH_METHOD_KINDS.map((kind) => Type.Literal(kind)))
34
+ });
35
+
36
+ const OAUTH_RETURN_TO_PATTERN = "^(?:/(?!/).*$|https?://[^\\s]+)$";
37
+
38
+ const oauthReturnToValidator = Object.freeze({
39
+ schema: Type.String({
40
+ minLength: 1,
41
+ maxLength: 1024,
42
+ pattern: OAUTH_RETURN_TO_PATTERN
43
+ })
44
+ });
45
+
46
+ const authEmailValidator = Object.freeze({
47
+ schema: Type.String({
48
+ minLength: AUTH_EMAIL_MIN_LENGTH,
49
+ maxLength: AUTH_EMAIL_MAX_LENGTH,
50
+ pattern: AUTH_EMAIL_PATTERN
51
+ })
52
+ });
53
+
54
+ const authPasswordValidator = Object.freeze({
55
+ schema: Type.String({
56
+ minLength: AUTH_PASSWORD_MIN_LENGTH,
57
+ maxLength: AUTH_PASSWORD_MAX_LENGTH
58
+ })
59
+ });
60
+
61
+ const authLoginPasswordValidator = Object.freeze({
62
+ schema: Type.String({
63
+ minLength: 1,
64
+ maxLength: AUTH_LOGIN_PASSWORD_MAX_LENGTH
65
+ })
66
+ });
67
+
68
+ const authRecoveryTokenValidator = Object.freeze({
69
+ schema: Type.String({
70
+ minLength: 1,
71
+ maxLength: AUTH_RECOVERY_TOKEN_MAX_LENGTH
72
+ })
73
+ });
74
+
75
+ const authAccessTokenValidator = Object.freeze({
76
+ schema: Type.String({
77
+ minLength: 1,
78
+ maxLength: AUTH_ACCESS_TOKEN_MAX_LENGTH
79
+ })
80
+ });
81
+
82
+ const authRefreshTokenValidator = Object.freeze({
83
+ schema: Type.String({
84
+ minLength: 1,
85
+ maxLength: AUTH_REFRESH_TOKEN_MAX_LENGTH
86
+ })
87
+ });
88
+
89
+ const okResponseValidator = Object.freeze({
90
+ schema: Type.Object(
91
+ {
92
+ ok: Type.Boolean()
93
+ },
94
+ {
95
+ additionalProperties: false
96
+ }
97
+ )
98
+ });
99
+
100
+ const okMessageResponseValidator = Object.freeze({
101
+ schema: Type.Object(
102
+ {
103
+ ok: Type.Boolean(),
104
+ message: Type.String({ minLength: 1 })
105
+ },
106
+ {
107
+ additionalProperties: false
108
+ }
109
+ )
110
+ });
111
+
112
+ const registerResponseValidator = Object.freeze({
113
+ schema: Type.Object(
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
+ )
124
+ });
125
+
126
+ const loginResponseValidator = Object.freeze({
127
+ schema: Type.Object(
128
+ {
129
+ ok: Type.Boolean(),
130
+ username: Type.String({ minLength: 1, maxLength: 120 })
131
+ },
132
+ {
133
+ additionalProperties: false
134
+ }
135
+ )
136
+ });
137
+
138
+ const otpVerifyResponseValidator = Object.freeze({
139
+ schema: Type.Object(
140
+ {
141
+ ok: Type.Boolean(),
142
+ username: Type.String({ minLength: 1, maxLength: 120 }),
143
+ email: authEmailValidator.schema
144
+ },
145
+ {
146
+ additionalProperties: false
147
+ }
148
+ )
149
+ });
150
+
151
+ const oauthCompleteResponseValidator = Object.freeze({
152
+ schema: Type.Object(
153
+ {
154
+ ok: Type.Boolean(),
155
+ provider: oauthProviderValidator.schema,
156
+ username: Type.String({ minLength: 1, maxLength: 120 }),
157
+ email: authEmailValidator.schema
158
+ },
159
+ {
160
+ additionalProperties: false
161
+ }
162
+ )
163
+ });
164
+
165
+ const logoutResponseValidator = Object.freeze({
166
+ schema: Type.Object(
167
+ {
168
+ ok: Type.Boolean()
169
+ },
170
+ {
171
+ additionalProperties: false
172
+ }
173
+ )
174
+ });
175
+
176
+ const oauthProviderCatalogEntryValidator = Object.freeze({
177
+ schema: Type.Object(
178
+ {
179
+ id: oauthProviderValidator.schema,
180
+ label: Type.String({ minLength: 1, maxLength: 120 })
181
+ },
182
+ {
183
+ additionalProperties: false
184
+ }
185
+ )
186
+ });
187
+
188
+ const sessionResponseValidator = Object.freeze({
189
+ schema: Type.Object(
190
+ {
191
+ authenticated: Type.Boolean(),
192
+ username: Type.Optional(Type.String({ minLength: 1, maxLength: 120 })),
193
+ csrfToken: Type.String({ minLength: 1 }),
194
+ oauthProviders: Type.Array(oauthProviderCatalogEntryValidator.schema),
195
+ oauthDefaultProvider: Type.Union([oauthProviderValidator.schema, Type.Null()])
196
+ },
197
+ {
198
+ additionalProperties: false
199
+ }
200
+ )
201
+ });
202
+
203
+ const sessionUnavailableResponseValidator = Object.freeze({
204
+ schema: Type.Object(
205
+ {
206
+ error: Type.String({ minLength: 1 }),
207
+ csrfToken: Type.String({ minLength: 1 }),
208
+ oauthProviders: Type.Array(oauthProviderCatalogEntryValidator.schema),
209
+ oauthDefaultProvider: Type.Union([oauthProviderValidator.schema, Type.Null()])
210
+ },
211
+ {
212
+ additionalProperties: false
213
+ }
214
+ )
215
+ });
216
+
217
+ function createCommandMessages({
218
+ fields = {},
219
+ defaultMessage = "Invalid value."
220
+ } = {}) {
221
+ return Object.freeze({
222
+ apiValidation: "Validation failed.",
223
+ fields: Object.freeze({
224
+ ...(fields && typeof fields === "object" ? fields : {})
225
+ }),
226
+ keywords: Object.freeze({
227
+ additionalProperties: "Unexpected field."
228
+ }),
229
+ default: String(defaultMessage || "Invalid value.")
230
+ });
231
+ }
232
+
233
+ export {
234
+ authEmailValidator,
235
+ authPasswordValidator,
236
+ authLoginPasswordValidator,
237
+ authRecoveryTokenValidator,
238
+ authAccessTokenValidator,
239
+ authRefreshTokenValidator,
240
+ oauthProviderValidator,
241
+ authMethodIdValidator,
242
+ authMethodKindValidator,
243
+ oauthReturnToValidator,
244
+ okResponseValidator,
245
+ okMessageResponseValidator,
246
+ registerResponseValidator,
247
+ loginResponseValidator,
248
+ otpVerifyResponseValidator,
249
+ oauthCompleteResponseValidator,
250
+ logoutResponseValidator,
251
+ oauthProviderCatalogEntryValidator,
252
+ sessionResponseValidator,
253
+ sessionUnavailableResponseValidator,
254
+ createCommandMessages
255
+ };
@@ -0,0 +1,68 @@
1
+ import { Type } from "typebox";
2
+ import { normalizeObjectInput } from "../inputNormalization.js";
3
+ import {
4
+ authAccessTokenValidator,
5
+ authRecoveryTokenValidator,
6
+ authRefreshTokenValidator,
7
+ createCommandMessages,
8
+ oauthCompleteResponseValidator,
9
+ oauthProviderValidator
10
+ } from "./authCommandValidators.js";
11
+
12
+ const AUTH_LOGIN_OAUTH_COMPLETE_MESSAGES = createCommandMessages({
13
+ fields: {
14
+ provider: {
15
+ required: "OAuth provider is required.",
16
+ pattern: "OAuth provider id is invalid.",
17
+ default: "OAuth provider id is invalid."
18
+ },
19
+ code: {
20
+ default: "OAuth code is invalid."
21
+ },
22
+ accessToken: {
23
+ default: "Access token is invalid."
24
+ },
25
+ refreshToken: {
26
+ default: "Refresh token is invalid."
27
+ }
28
+ }
29
+ });
30
+
31
+ const authLoginOAuthCompleteBodyValidator = Object.freeze({
32
+ schema: Type.Object(
33
+ {
34
+ provider: oauthProviderValidator.schema,
35
+ code: Type.Optional(authRecoveryTokenValidator.schema),
36
+ accessToken: Type.Optional(authAccessTokenValidator.schema),
37
+ refreshToken: Type.Optional(authRefreshTokenValidator.schema),
38
+ error: Type.Optional(Type.String({ minLength: 1, maxLength: 128 })),
39
+ errorDescription: Type.Optional(Type.String({ minLength: 1, maxLength: 1024 })),
40
+ error_code: Type.Optional(Type.String({ minLength: 1, maxLength: 128 })),
41
+ error_description: Type.Optional(Type.String({ minLength: 1, maxLength: 1024 }))
42
+ },
43
+ {
44
+ additionalProperties: false
45
+ }
46
+ ),
47
+ normalize: normalizeObjectInput,
48
+ messages: AUTH_LOGIN_OAUTH_COMPLETE_MESSAGES
49
+ });
50
+
51
+ const authLoginOAuthCompleteCommand = Object.freeze({
52
+ command: "auth.login.oauth.complete",
53
+ operation: Object.freeze({
54
+ method: "POST",
55
+ bodyValidator: authLoginOAuthCompleteBodyValidator,
56
+ responseValidator: oauthCompleteResponseValidator,
57
+ messages: AUTH_LOGIN_OAUTH_COMPLETE_MESSAGES,
58
+ idempotent: false,
59
+ invalidates: Object.freeze(["auth.session.read"])
60
+ })
61
+ });
62
+
63
+ export {
64
+ authLoginOAuthCompleteBodyValidator,
65
+ oauthCompleteResponseValidator,
66
+ AUTH_LOGIN_OAUTH_COMPLETE_MESSAGES,
67
+ authLoginOAuthCompleteCommand
68
+ };
@@ -0,0 +1,72 @@
1
+ import { Type } from "typebox";
2
+ import { normalizeObjectInput } from "../inputNormalization.js";
3
+ import {
4
+ createCommandMessages,
5
+ oauthProviderValidator,
6
+ oauthReturnToValidator
7
+ } from "./authCommandValidators.js";
8
+
9
+ const AUTH_LOGIN_OAUTH_START_MESSAGES = createCommandMessages({
10
+ fields: {
11
+ provider: {
12
+ required: "OAuth provider is required.",
13
+ pattern: "OAuth provider id is invalid.",
14
+ default: "OAuth provider id is invalid."
15
+ },
16
+ returnTo: {
17
+ pattern: "Return target must be an absolute path or URL.",
18
+ default: "Return target must be an absolute path or URL."
19
+ }
20
+ }
21
+ });
22
+
23
+ const authLoginOAuthStartParamsValidator = Object.freeze({
24
+ schema: Type.Object(
25
+ {
26
+ provider: oauthProviderValidator.schema
27
+ },
28
+ {
29
+ additionalProperties: false
30
+ }
31
+ ),
32
+ normalize: normalizeObjectInput,
33
+ messages: AUTH_LOGIN_OAUTH_START_MESSAGES
34
+ });
35
+
36
+ const authLoginOAuthStartQueryValidator = Object.freeze({
37
+ schema: Type.Object(
38
+ {
39
+ returnTo: Type.Optional(oauthReturnToValidator.schema)
40
+ },
41
+ {
42
+ additionalProperties: false
43
+ }
44
+ ),
45
+ normalize: normalizeObjectInput,
46
+ messages: AUTH_LOGIN_OAUTH_START_MESSAGES
47
+ });
48
+
49
+ const authLoginOAuthStartResponseValidator = Object.freeze({
50
+ schema: Type.Unknown()
51
+ });
52
+
53
+ const authLoginOAuthStartCommand = Object.freeze({
54
+ command: "auth.login.oauth.start",
55
+ operation: Object.freeze({
56
+ method: "GET",
57
+ paramsValidator: authLoginOAuthStartParamsValidator,
58
+ queryValidator: authLoginOAuthStartQueryValidator,
59
+ responseValidator: authLoginOAuthStartResponseValidator,
60
+ messages: AUTH_LOGIN_OAUTH_START_MESSAGES,
61
+ idempotent: true,
62
+ invalidates: Object.freeze([])
63
+ })
64
+ });
65
+
66
+ export {
67
+ authLoginOAuthStartParamsValidator,
68
+ authLoginOAuthStartQueryValidator,
69
+ authLoginOAuthStartResponseValidator,
70
+ AUTH_LOGIN_OAUTH_START_MESSAGES,
71
+ authLoginOAuthStartCommand
72
+ };
@@ -0,0 +1,56 @@
1
+ import { Type } from "typebox";
2
+ import { normalizeObjectInput } from "../inputNormalization.js";
3
+ import {
4
+ authEmailValidator,
5
+ createCommandMessages,
6
+ oauthReturnToValidator,
7
+ okMessageResponseValidator
8
+ } from "./authCommandValidators.js";
9
+
10
+ const AUTH_LOGIN_OTP_REQUEST_MESSAGES = createCommandMessages({
11
+ fields: {
12
+ email: {
13
+ required: "Email is required.",
14
+ minLength: "Email is required.",
15
+ pattern: "Enter a valid email address.",
16
+ default: "Enter a valid email address."
17
+ },
18
+ returnTo: {
19
+ pattern: "Return target must be an absolute path or URL.",
20
+ default: "Return target must be an absolute path or URL."
21
+ }
22
+ }
23
+ });
24
+
25
+ const authLoginOtpRequestBodyValidator = Object.freeze({
26
+ schema: Type.Object(
27
+ {
28
+ email: authEmailValidator.schema,
29
+ returnTo: Type.Optional(oauthReturnToValidator.schema)
30
+ },
31
+ {
32
+ additionalProperties: false
33
+ }
34
+ ),
35
+ normalize: normalizeObjectInput,
36
+ messages: AUTH_LOGIN_OTP_REQUEST_MESSAGES
37
+ });
38
+
39
+ const authLoginOtpRequestCommand = Object.freeze({
40
+ command: "auth.login.otp.request",
41
+ operation: Object.freeze({
42
+ method: "POST",
43
+ bodyValidator: authLoginOtpRequestBodyValidator,
44
+ responseValidator: okMessageResponseValidator,
45
+ messages: AUTH_LOGIN_OTP_REQUEST_MESSAGES,
46
+ idempotent: false,
47
+ invalidates: Object.freeze([])
48
+ })
49
+ });
50
+
51
+ export {
52
+ authLoginOtpRequestBodyValidator,
53
+ okMessageResponseValidator,
54
+ AUTH_LOGIN_OTP_REQUEST_MESSAGES,
55
+ authLoginOtpRequestCommand
56
+ };
@@ -0,0 +1,64 @@
1
+ import { Type } from "typebox";
2
+ import { normalizeObjectInput } from "../inputNormalization.js";
3
+ import {
4
+ authEmailValidator,
5
+ authRecoveryTokenValidator,
6
+ createCommandMessages,
7
+ otpVerifyResponseValidator
8
+ } from "./authCommandValidators.js";
9
+
10
+ const AUTH_LOGIN_OTP_VERIFY_MESSAGES = createCommandMessages({
11
+ fields: {
12
+ email: {
13
+ pattern: "Enter a valid email address.",
14
+ default: "Enter a valid email address."
15
+ },
16
+ token: {
17
+ minLength: "One-time code is required.",
18
+ default: "One-time code is required."
19
+ },
20
+ tokenHash: {
21
+ default: "One-time token hash is invalid."
22
+ },
23
+ type: {
24
+ const: "Only email OTP verification is supported.",
25
+ default: "Only email OTP verification is supported."
26
+ }
27
+ }
28
+ });
29
+
30
+ const authLoginOtpVerifyBodyValidator = Object.freeze({
31
+ schema: Type.Object(
32
+ {
33
+ email: Type.Optional(authEmailValidator.schema),
34
+ token: Type.Optional(authRecoveryTokenValidator.schema),
35
+ tokenHash: Type.Optional(authRecoveryTokenValidator.schema),
36
+ type: Type.Optional(Type.Literal("email"))
37
+ },
38
+ {
39
+ additionalProperties: false,
40
+ minProperties: 1
41
+ }
42
+ ),
43
+ normalize: normalizeObjectInput,
44
+ messages: AUTH_LOGIN_OTP_VERIFY_MESSAGES
45
+ });
46
+
47
+ const authLoginOtpVerifyCommand = Object.freeze({
48
+ command: "auth.login.otp.verify",
49
+ operation: Object.freeze({
50
+ method: "POST",
51
+ bodyValidator: authLoginOtpVerifyBodyValidator,
52
+ responseValidator: otpVerifyResponseValidator,
53
+ messages: AUTH_LOGIN_OTP_VERIFY_MESSAGES,
54
+ idempotent: false,
55
+ invalidates: Object.freeze(["auth.session.read"])
56
+ })
57
+ });
58
+
59
+ export {
60
+ authLoginOtpVerifyBodyValidator,
61
+ otpVerifyResponseValidator,
62
+ AUTH_LOGIN_OTP_VERIFY_MESSAGES,
63
+ authLoginOtpVerifyCommand
64
+ };
@@ -0,0 +1,57 @@
1
+ import { Type } from "typebox";
2
+ import { normalizeObjectInput } from "../inputNormalization.js";
3
+ import {
4
+ authEmailValidator,
5
+ authLoginPasswordValidator,
6
+ createCommandMessages,
7
+ loginResponseValidator
8
+ } from "./authCommandValidators.js";
9
+
10
+ const AUTH_LOGIN_PASSWORD_MESSAGES = createCommandMessages({
11
+ fields: {
12
+ email: {
13
+ required: "Email is required.",
14
+ minLength: "Email is required.",
15
+ pattern: "Enter a valid email address.",
16
+ default: "Enter a valid email address."
17
+ },
18
+ password: {
19
+ required: "Password is required.",
20
+ minLength: "Password is required.",
21
+ default: "Password is required."
22
+ }
23
+ }
24
+ });
25
+
26
+ const authLoginPasswordBodyValidator = Object.freeze({
27
+ schema: Type.Object(
28
+ {
29
+ email: authEmailValidator.schema,
30
+ password: authLoginPasswordValidator.schema
31
+ },
32
+ {
33
+ additionalProperties: false
34
+ }
35
+ ),
36
+ normalize: normalizeObjectInput,
37
+ messages: AUTH_LOGIN_PASSWORD_MESSAGES
38
+ });
39
+
40
+ const authLoginPasswordCommand = Object.freeze({
41
+ command: "auth.login.password",
42
+ operation: Object.freeze({
43
+ method: "POST",
44
+ bodyValidator: authLoginPasswordBodyValidator,
45
+ responseValidator: loginResponseValidator,
46
+ messages: AUTH_LOGIN_PASSWORD_MESSAGES,
47
+ idempotent: false,
48
+ invalidates: Object.freeze(["auth.session.read"])
49
+ })
50
+ });
51
+
52
+ export {
53
+ authLoginPasswordBodyValidator,
54
+ loginResponseValidator,
55
+ AUTH_LOGIN_PASSWORD_MESSAGES,
56
+ authLoginPasswordCommand
57
+ };
@@ -0,0 +1,23 @@
1
+ import {
2
+ createCommandMessages,
3
+ logoutResponseValidator
4
+ } from "./authCommandValidators.js";
5
+
6
+ const AUTH_LOGOUT_MESSAGES = createCommandMessages();
7
+
8
+ const authLogoutCommand = Object.freeze({
9
+ command: "auth.logout",
10
+ operation: Object.freeze({
11
+ method: "POST",
12
+ responseValidator: logoutResponseValidator,
13
+ messages: AUTH_LOGOUT_MESSAGES,
14
+ idempotent: false,
15
+ invalidates: Object.freeze(["auth.session.read"])
16
+ })
17
+ });
18
+
19
+ export {
20
+ logoutResponseValidator,
21
+ AUTH_LOGOUT_MESSAGES,
22
+ authLogoutCommand
23
+ };
@@ -0,0 +1,67 @@
1
+ import { Type } from "typebox";
2
+ import { normalizeObjectInput } from "../inputNormalization.js";
3
+ import {
4
+ authAccessTokenValidator,
5
+ authRecoveryTokenValidator,
6
+ authRefreshTokenValidator,
7
+ createCommandMessages,
8
+ okResponseValidator
9
+ } from "./authCommandValidators.js";
10
+
11
+ const AUTH_PASSWORD_RECOVERY_COMPLETE_MESSAGES = createCommandMessages({
12
+ fields: {
13
+ code: {
14
+ default: "Recovery code is invalid."
15
+ },
16
+ tokenHash: {
17
+ default: "Recovery token hash is invalid."
18
+ },
19
+ accessToken: {
20
+ default: "Access token is invalid."
21
+ },
22
+ refreshToken: {
23
+ default: "Refresh token is invalid."
24
+ },
25
+ type: {
26
+ const: "Only recovery links are supported.",
27
+ default: "Only recovery links are supported."
28
+ }
29
+ }
30
+ });
31
+
32
+ const authPasswordRecoveryCompleteBodyValidator = Object.freeze({
33
+ schema: Type.Object(
34
+ {
35
+ code: Type.Optional(authRecoveryTokenValidator.schema),
36
+ tokenHash: Type.Optional(authRecoveryTokenValidator.schema),
37
+ accessToken: Type.Optional(authAccessTokenValidator.schema),
38
+ refreshToken: Type.Optional(authRefreshTokenValidator.schema),
39
+ type: Type.Optional(Type.Literal("recovery"))
40
+ },
41
+ {
42
+ additionalProperties: false,
43
+ minProperties: 1
44
+ }
45
+ ),
46
+ normalize: normalizeObjectInput,
47
+ messages: AUTH_PASSWORD_RECOVERY_COMPLETE_MESSAGES
48
+ });
49
+
50
+ const authPasswordRecoveryCompleteCommand = Object.freeze({
51
+ command: "auth.password.recovery.complete",
52
+ operation: Object.freeze({
53
+ method: "POST",
54
+ bodyValidator: authPasswordRecoveryCompleteBodyValidator,
55
+ responseValidator: okResponseValidator,
56
+ messages: AUTH_PASSWORD_RECOVERY_COMPLETE_MESSAGES,
57
+ idempotent: false,
58
+ invalidates: Object.freeze(["auth.session.read"])
59
+ })
60
+ });
61
+
62
+ export {
63
+ authPasswordRecoveryCompleteBodyValidator,
64
+ okResponseValidator,
65
+ AUTH_PASSWORD_RECOVERY_COMPLETE_MESSAGES,
66
+ authPasswordRecoveryCompleteCommand
67
+ };