@jskit-ai/auth-core 0.1.53 → 0.1.55

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.
@@ -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.53",
4
+ "version": "0.1.55",
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.54",
72
+ "@jskit-ai/kernel": "0.1.56",
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.53",
3
+ "version": "0.1.55",
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.54",
49
+ "@jskit-ai/kernel": "0.1.56",
50
50
  "@fastify/cookie": "^11.0.2",
51
51
  "@fastify/csrf-protection": "^7.1.0",
52
52
  "@fastify/rate-limit": "^10.3.0",
53
- "typebox": "^1.0.81"
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
- composeAuthPolicyContextResolvers,
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
- ...(typeof resolveContext === "function" ? { resolveContext } : {})
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 { Type } from "typebox";
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 oauthProviderValidator = Object.freeze({
17
- schema: Type.String({
18
- minLength: 2,
19
- maxLength: 32,
20
- pattern: OAUTH_PROVIDER_ID_PATTERN
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 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
- })
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 authMethodKindValidator = Object.freeze({
33
- schema: Type.Union(AUTH_METHOD_KINDS.map((kind) => Type.Literal(kind)))
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 oauthReturnToValidator = Object.freeze({
39
- schema: Type.String({
40
- minLength: 1,
41
- maxLength: 1024,
42
- pattern: OAUTH_RETURN_TO_PATTERN
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 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
- })
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 authPasswordValidator = Object.freeze({
55
- schema: Type.String({
56
- minLength: AUTH_PASSWORD_MIN_LENGTH,
57
- maxLength: AUTH_PASSWORD_MAX_LENGTH
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 authLoginPasswordValidator = Object.freeze({
62
- schema: Type.String({
63
- minLength: 1,
64
- maxLength: AUTH_LOGIN_PASSWORD_MAX_LENGTH
65
- })
59
+ const authLoginPasswordFieldDefinition = deepFreeze({
60
+ type: "string",
61
+ minLength: 1,
62
+ maxLength: AUTH_LOGIN_PASSWORD_MAX_LENGTH
66
63
  });
67
64
 
68
- const authRecoveryTokenValidator = Object.freeze({
69
- schema: Type.String({
70
- minLength: 1,
71
- maxLength: AUTH_RECOVERY_TOKEN_MAX_LENGTH
72
- })
65
+ const authRecoveryTokenFieldDefinition = deepFreeze({
66
+ type: "string",
67
+ minLength: 1,
68
+ maxLength: AUTH_RECOVERY_TOKEN_MAX_LENGTH
73
69
  });
74
70
 
75
- const authAccessTokenValidator = Object.freeze({
76
- schema: Type.String({
77
- minLength: 1,
78
- maxLength: AUTH_ACCESS_TOKEN_MAX_LENGTH
79
- })
71
+ const authAccessTokenFieldDefinition = deepFreeze({
72
+ type: "string",
73
+ minLength: 1,
74
+ maxLength: AUTH_ACCESS_TOKEN_MAX_LENGTH
80
75
  });
81
76
 
82
- const authRefreshTokenValidator = Object.freeze({
83
- schema: Type.String({
84
- minLength: 1,
85
- maxLength: AUTH_REFRESH_TOKEN_MAX_LENGTH
86
- })
77
+ const authRefreshTokenFieldDefinition = deepFreeze({
78
+ type: "string",
79
+ minLength: 1,
80
+ maxLength: AUTH_REFRESH_TOKEN_MAX_LENGTH
87
81
  });
88
82
 
89
- const okResponseValidator = Object.freeze({
90
- schema: Type.Object(
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 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
- )
88
+ const authMethodIdValidator = deepFreeze({
89
+ type: "string",
90
+ ...authMethodIdFieldDefinition
110
91
  });
111
92
 
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
- )
93
+ const authMethodKindValidator = deepFreeze({
94
+ type: "string",
95
+ enum: AUTH_METHOD_KINDS
124
96
  });
125
97
 
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
- )
98
+ const oauthReturnToValidator = deepFreeze({
99
+ type: "string",
100
+ ...oauthReturnToFieldDefinition
136
101
  });
137
102
 
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
- )
103
+ const authEmailValidator = deepFreeze({
104
+ type: "string",
105
+ ...authEmailFieldDefinition
149
106
  });
150
107
 
151
- const oauthCompleteResponseValidator = Object.freeze({
152
- schema: Type.Object(
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 devLoginAsResponseValidator = Object.freeze({
166
- schema: Type.Object(
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 logoutResponseValidator = Object.freeze({
180
- schema: Type.Object(
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 oauthProviderCatalogEntryValidator = Object.freeze({
191
- schema: Type.Object(
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 sessionUnavailableResponseValidator = Object.freeze({
220
- schema: Type.Object(
221
- {
222
- error: Type.String({ minLength: 1 }),
223
- csrfToken: Type.String({ minLength: 1 }),
224
- oauthProviders: Type.Array(oauthProviderCatalogEntryValidator.schema),
225
- oauthDefaultProvider: Type.Union([oauthProviderValidator.schema, Type.Null()])
226
- },
227
- {
228
- additionalProperties: false
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 Object.freeze({
267
+ return deepFreeze({
238
268
  apiValidation: "Validation failed.",
239
- fields: Object.freeze({
269
+ fields: {
240
270
  ...(fields && typeof fields === "object" ? fields : {})
241
- }),
242
- keywords: Object.freeze({
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
- okResponseValidator,
261
- okMessageResponseValidator,
262
- registerResponseValidator,
263
- loginResponseValidator,
264
- otpVerifyResponseValidator,
265
- oauthCompleteResponseValidator,
266
- devLoginAsResponseValidator,
267
- logoutResponseValidator,
268
- oauthProviderCatalogEntryValidator,
269
- sessionResponseValidator,
270
- sessionUnavailableResponseValidator,
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 { Type } from "typebox";
1
+ import { createSchema } from "json-rest-schema";
2
2
  import { recordIdInputSchema } from "@jskit-ai/kernel/shared/validators";
3
- import { normalizeObjectInput } from "../inputNormalization.js";
3
+ import { deepFreeze } from "@jskit-ai/kernel/shared/support/deepFreeze";
4
4
  import {
5
5
  authEmailValidator,
6
6
  createCommandMessages,
7
- devLoginAsResponseValidator
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 = Object.freeze({
25
- schema: Type.Object(
26
- {
27
- userId: Type.Optional(recordIdInputSchema),
28
- email: Type.Optional(authEmailValidator.schema)
24
+ const authDevLoginAsBodyValidator = deepFreeze({
25
+ schema: createSchema({
26
+ userId: {
27
+ ...recordIdInputSchema,
28
+ required: false
29
29
  },
30
- {
31
- additionalProperties: false,
32
- anyOf: [{ required: ["userId"] }, { required: ["email"] }]
30
+ email: {
31
+ ...authEmailValidator,
32
+ required: false
33
33
  }
34
- ),
35
- normalize: normalizeObjectInput,
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 = Object.freeze({
45
+ const authDevLoginAsCommand = deepFreeze({
46
46
  command: "auth.dev.loginAs",
47
- operation: Object.freeze({
47
+ operation: {
48
48
  method: "POST",
49
- bodyValidator: authDevLoginAsBodyValidator,
50
- responseValidator: devLoginAsResponseValidator,
49
+ body: authDevLoginAsBodyValidator,
50
+ response: devLoginAsOutputValidator,
51
51
  messages: AUTH_DEV_LOGIN_AS_MESSAGES,
52
52
  idempotent: false,
53
- invalidates: Object.freeze(["auth.session.read"])
54
- })
53
+ invalidates: ["auth.session.read"]
54
+ }
55
55
  });
56
56
 
57
57
  export { AUTH_DEV_LOGIN_AS_MESSAGES, authDevLoginAsBodyValidator, authDevLoginAsCommand };