@oxy.so/contracts 4.15.0 → 4.17.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/cjs/.tsbuildinfo +1 -1
- package/dist/cjs/accountEmail.js +12 -34
- package/dist/cjs/accountGraph.js +22 -320
- package/dist/cjs/agentKeys.js +11 -13
- package/dist/cjs/client/accountEmail.js +48 -0
- package/dist/cjs/client/accountGraph.js +323 -0
- package/dist/cjs/client/agentKeys.js +77 -0
- package/dist/cjs/client/check.js +466 -0
- package/dist/cjs/client/deviceBoot.js +22 -0
- package/dist/cjs/client/deviceDirectory.js +51 -0
- package/dist/cjs/client/deviceSession.js +63 -0
- package/dist/cjs/client/externalIdentity.js +19 -0
- package/dist/cjs/client/identity.js +45 -0
- package/dist/cjs/client/identityLink.js +55 -0
- package/dist/cjs/client/identityProof.js +109 -0
- package/dist/cjs/client/index.js +190 -0
- package/dist/cjs/client/organizations.js +114 -0
- package/dist/cjs/client/products.js +153 -0
- package/dist/cjs/client/recommendations.js +33 -0
- package/dist/cjs/client/reputation.js +41 -0
- package/dist/cjs/client/safety.js +15 -0
- package/dist/cjs/client/sessionStatus.js +23 -0
- package/dist/cjs/client/signIn.js +157 -0
- package/dist/cjs/client/userResponse.js +15 -0
- package/dist/cjs/client/username.js +173 -0
- package/dist/cjs/deviceSession.js +3 -16
- package/dist/cjs/identityLink.js +13 -34
- package/dist/cjs/identityProof.js +18 -106
- package/dist/cjs/index.js +15 -10
- package/dist/cjs/inference/money.js +10 -0
- package/dist/cjs/inference/version.js +1 -1
- package/dist/cjs/organizations.js +21 -41
- package/dist/cjs/products/billing.js +0 -1
- package/dist/cjs/products/checkout.js +1 -14
- package/dist/cjs/products/plans.js +2 -18
- package/dist/cjs/reputation.js +3 -34
- package/dist/cjs/signIn.js +57 -96
- package/dist/cjs/userResponse.js +1 -8
- package/dist/cjs/username.js +23 -158
- package/dist/esm/.tsbuildinfo +1 -1
- package/dist/esm/accountEmail.js +4 -32
- package/dist/esm/accountGraph.js +4 -309
- package/dist/esm/agentKeys.js +4 -10
- package/dist/esm/client/accountEmail.js +45 -0
- package/dist/esm/client/accountGraph.js +314 -0
- package/dist/esm/client/agentKeys.js +74 -0
- package/dist/esm/client/check.js +428 -0
- package/dist/esm/client/deviceBoot.js +19 -0
- package/dist/esm/client/deviceDirectory.js +48 -0
- package/dist/esm/client/deviceSession.js +60 -0
- package/dist/esm/client/externalIdentity.js +16 -0
- package/dist/esm/client/identity.js +42 -0
- package/dist/esm/client/identityLink.js +50 -0
- package/dist/esm/client/identityProof.js +104 -0
- package/dist/esm/client/index.js +37 -0
- package/dist/esm/client/organizations.js +111 -0
- package/dist/esm/client/products.js +150 -0
- package/dist/esm/client/recommendations.js +30 -0
- package/dist/esm/client/reputation.js +37 -0
- package/dist/esm/client/safety.js +12 -0
- package/dist/esm/client/sessionStatus.js +20 -0
- package/dist/esm/client/signIn.js +151 -0
- package/dist/esm/client/userResponse.js +12 -0
- package/dist/esm/client/username.js +167 -0
- package/dist/esm/deviceSession.js +1 -15
- package/dist/esm/identityLink.js +4 -27
- package/dist/esm/identityProof.js +4 -99
- package/dist/esm/index.js +2 -2
- package/dist/esm/inference/money.js +10 -0
- package/dist/esm/inference/version.js +1 -1
- package/dist/esm/organizations.js +4 -31
- package/dist/esm/products/billing.js +0 -1
- package/dist/esm/products/checkout.js +0 -13
- package/dist/esm/products/plans.js +1 -17
- package/dist/esm/reputation.js +1 -32
- package/dist/esm/signIn.js +29 -83
- package/dist/esm/userResponse.js +1 -8
- package/dist/esm/username.js +4 -148
- package/dist/types/.tsbuildinfo +1 -1
- package/dist/types/accountEmail.d.ts +2 -34
- package/dist/types/accountGraph.d.ts +12 -208
- package/dist/types/agency.d.ts +24 -24
- package/dist/types/agentKeys.d.ts +8 -6
- package/dist/types/client/accountEmail.d.ts +44 -0
- package/dist/types/client/accountGraph.d.ts +203 -0
- package/dist/types/client/agentKeys.d.ts +113 -0
- package/dist/types/client/check.d.ts +184 -0
- package/dist/types/client/deviceBoot.d.ts +6 -0
- package/dist/types/client/deviceDirectory.d.ts +134 -0
- package/dist/types/client/deviceSession.d.ts +91 -0
- package/dist/types/client/externalIdentity.d.ts +14 -0
- package/dist/types/client/identity.d.ts +8 -0
- package/dist/types/client/identityLink.d.ts +21 -0
- package/dist/types/client/identityProof.d.ts +73 -0
- package/dist/types/client/index.d.ts +37 -0
- package/dist/types/client/organizations.d.ts +167 -0
- package/dist/types/client/products.d.ts +145 -0
- package/dist/types/client/recommendations.d.ts +27 -0
- package/dist/types/client/reputation.d.ts +28 -0
- package/dist/types/client/safety.d.ts +13 -0
- package/dist/types/client/sessionStatus.d.ts +19 -0
- package/dist/types/client/signIn.d.ts +107 -0
- package/dist/types/client/userResponse.d.ts +7 -0
- package/dist/types/client/username.d.ts +126 -0
- package/dist/types/deviceDirectory.d.ts +28 -28
- package/dist/types/deviceSession.d.ts +1 -12
- package/dist/types/externalIdentity.d.ts +11 -44
- package/dist/types/identityLink.d.ts +3 -11
- package/dist/types/identityProof.d.ts +2 -65
- package/dist/types/index.d.ts +3 -3
- package/dist/types/inference/catalogue.d.ts +7 -7
- package/dist/types/inference/decisions.d.ts +41 -41
- package/dist/types/inference/economics.d.ts +5 -5
- package/dist/types/inference/embeddings.d.ts +16 -16
- package/dist/types/inference/errors.d.ts +8 -8
- package/dist/types/inference/inbox.d.ts +8 -8
- package/dist/types/inference/money.d.ts +17 -8
- package/dist/types/inference/priceVersion.d.ts +12 -12
- package/dist/types/inference/privateAutoExecution.d.ts +6 -6
- package/dist/types/inference/realtime.d.ts +54 -54
- package/dist/types/inference/request.d.ts +28 -28
- package/dist/types/inference/routingPolicy.d.ts +7 -7
- package/dist/types/inference/streamEvents.d.ts +26 -26
- package/dist/types/inference/usage.d.ts +32 -32
- package/dist/types/inference/version.d.ts +1 -1
- package/dist/types/oauth.d.ts +2 -2
- package/dist/types/organizations.d.ts +8 -10
- package/dist/types/products/billing.d.ts +3 -8
- package/dist/types/products/checkout.d.ts +0 -36
- package/dist/types/products/plans.d.ts +5 -102
- package/dist/types/reputation.d.ts +1 -11
- package/dist/types/sessionStatus.d.ts +2 -2
- package/dist/types/signIn.d.ts +74 -76
- package/dist/types/userResponse.d.ts +23 -159
- package/dist/types/username.d.ts +1 -96
- package/package.json +20 -1
package/dist/cjs/signIn.js
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
exports.normalizeEmailSignInCode = normalizeEmailSignInCode;
|
|
5
|
-
exports.isSecondFactorRequired = isSecondFactorRequired;
|
|
3
|
+
exports.totpBackupCodesResponseSchema = exports.totpReauthRequestSchema = exports.totpConfirmRequestSchema = exports.totpEnrollResponseSchema = exports.signInMethodsSchema = exports.passwordSetRequestSchema = exports.emailReauthProofSchema = exports.reauthProofSchema = exports.reauthEmailStartRequestSchema = exports.emailSignInChooseRequestSchema = exports.emailSignInChooseAccountSchema = exports.emailSignInAccountOptionSchema = exports.emailSignInPendingSchema = exports.secondFactorRequiredSchema = exports.signUpRequestSchema = exports.secondFactorSignInRequestSchema = exports.passwordSignInRequestSchema = exports.emailSignInLinkResponseSchema = exports.emailSignInLinkRequestSchema = exports.emailSignInCollectRequestSchema = exports.emailSignInConfirmRequestSchema = exports.emailSignInCodeSchema = exports.emailSignInStartResponseSchema = exports.emailSignInStartRequestSchema = exports.secondFactorCodeSchema = exports.newPasswordSchema = exports.passwordInputSchema = exports.signInIdentifierSchema = exports.SIGN_IN_ERROR_CODES = exports.REAUTH_ACTIONS = exports.isEmailSignInChooseAccount = exports.isSecondFactorRequired = exports.EMAIL_ACCOUNTS_MAX = exports.EMAIL_SIGNIN_CHOICE_TTL_MS = exports.normalizeEmailSignInCode = exports.EMAIL_SIGNIN_LONG_CODE_LENGTH = exports.EMAIL_SIGNIN_LONG_CODE_ALPHABET = exports.TOTP_BACKUP_CODE_COUNT = exports.TOTP_PERIOD_SECONDS = exports.TOTP_DIGITS = exports.PASSWORD_MAX_LENGTH = exports.PASSWORD_MIN_LENGTH = exports.SIGNIN_SECOND_FACTOR_MAX_ATTEMPTS = exports.SIGNIN_SECOND_FACTOR_TTL_MS = exports.EMAIL_SIGNIN_LINK_TTL_MS = void 0;
|
|
6
4
|
/**
|
|
7
5
|
* Signing in: an email code or link, an optional password,
|
|
8
6
|
* and an optional authenticator app (TOTP) as a second factor.
|
|
@@ -23,6 +21,11 @@ exports.isSecondFactorRequired = isSecondFactorRequired;
|
|
|
23
21
|
* one-use second-factor challenge instead of a session, and
|
|
24
22
|
* `POST /auth/signin/second-factor` takes the TOTP (or a backup code).
|
|
25
23
|
*
|
|
24
|
+
* An email may hold several accounts (up to `EMAIL_ACCOUNTS_MAX`). Signing in
|
|
25
|
+
* with the email, once the code or the link proves it, answers the accounts to
|
|
26
|
+
* choose from when there are several, and `POST /auth/signin/email/choose`
|
|
27
|
+
* names one. A username always names one account.
|
|
28
|
+
*
|
|
26
29
|
* `POST /auth/signup` creates an account from a username and an email confirmed
|
|
27
30
|
* with `POST /auth/email/verify/{start,confirm}` (purpose `signup`).
|
|
28
31
|
*
|
|
@@ -32,40 +35,27 @@ exports.isSecondFactorRequired = isSecondFactorRequired;
|
|
|
32
35
|
const zod_1 = require("zod");
|
|
33
36
|
const accountEmail_1 = require("./accountEmail");
|
|
34
37
|
const deviceSession_1 = require("./deviceSession");
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
exports.
|
|
41
|
-
|
|
42
|
-
exports.PASSWORD_MIN_LENGTH
|
|
43
|
-
|
|
44
|
-
exports.
|
|
45
|
-
|
|
46
|
-
exports.
|
|
47
|
-
|
|
48
|
-
exports.
|
|
49
|
-
|
|
50
|
-
exports.
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
* type a code while guessing one is infeasible.
|
|
57
|
-
*/
|
|
58
|
-
exports.EMAIL_SIGNIN_LONG_CODE_ALPHABET = '23456789ABCDEFGHJKMNPQRSTVWXYZ';
|
|
59
|
-
exports.EMAIL_SIGNIN_LONG_CODE_LENGTH = 10;
|
|
60
|
-
/**
|
|
61
|
-
* Normalise a typed sign-in code: 6 digits stay as they are; a long code is
|
|
62
|
-
* upper-cased with its dash and spaces removed. Anything else is returned
|
|
63
|
-
* trimmed (and will simply be wrong).
|
|
64
|
-
*/
|
|
65
|
-
function normalizeEmailSignInCode(code) {
|
|
66
|
-
const compact = code.trim().replace(/[\s-]/g, '').toUpperCase();
|
|
67
|
-
return compact;
|
|
68
|
-
}
|
|
38
|
+
// The Zod-free half of this contract lives in `./client/` (`@oxy.so/contracts/client`);
|
|
39
|
+
// it is re-exported here so the root entry is unchanged.
|
|
40
|
+
const signIn_1 = require("./client/signIn");
|
|
41
|
+
var signIn_2 = require("./client/signIn");
|
|
42
|
+
Object.defineProperty(exports, "EMAIL_SIGNIN_LINK_TTL_MS", { enumerable: true, get: function () { return signIn_2.EMAIL_SIGNIN_LINK_TTL_MS; } });
|
|
43
|
+
Object.defineProperty(exports, "SIGNIN_SECOND_FACTOR_TTL_MS", { enumerable: true, get: function () { return signIn_2.SIGNIN_SECOND_FACTOR_TTL_MS; } });
|
|
44
|
+
Object.defineProperty(exports, "SIGNIN_SECOND_FACTOR_MAX_ATTEMPTS", { enumerable: true, get: function () { return signIn_2.SIGNIN_SECOND_FACTOR_MAX_ATTEMPTS; } });
|
|
45
|
+
Object.defineProperty(exports, "PASSWORD_MIN_LENGTH", { enumerable: true, get: function () { return signIn_2.PASSWORD_MIN_LENGTH; } });
|
|
46
|
+
Object.defineProperty(exports, "PASSWORD_MAX_LENGTH", { enumerable: true, get: function () { return signIn_2.PASSWORD_MAX_LENGTH; } });
|
|
47
|
+
Object.defineProperty(exports, "TOTP_DIGITS", { enumerable: true, get: function () { return signIn_2.TOTP_DIGITS; } });
|
|
48
|
+
Object.defineProperty(exports, "TOTP_PERIOD_SECONDS", { enumerable: true, get: function () { return signIn_2.TOTP_PERIOD_SECONDS; } });
|
|
49
|
+
Object.defineProperty(exports, "TOTP_BACKUP_CODE_COUNT", { enumerable: true, get: function () { return signIn_2.TOTP_BACKUP_CODE_COUNT; } });
|
|
50
|
+
Object.defineProperty(exports, "EMAIL_SIGNIN_LONG_CODE_ALPHABET", { enumerable: true, get: function () { return signIn_2.EMAIL_SIGNIN_LONG_CODE_ALPHABET; } });
|
|
51
|
+
Object.defineProperty(exports, "EMAIL_SIGNIN_LONG_CODE_LENGTH", { enumerable: true, get: function () { return signIn_2.EMAIL_SIGNIN_LONG_CODE_LENGTH; } });
|
|
52
|
+
Object.defineProperty(exports, "normalizeEmailSignInCode", { enumerable: true, get: function () { return signIn_2.normalizeEmailSignInCode; } });
|
|
53
|
+
Object.defineProperty(exports, "EMAIL_SIGNIN_CHOICE_TTL_MS", { enumerable: true, get: function () { return signIn_2.EMAIL_SIGNIN_CHOICE_TTL_MS; } });
|
|
54
|
+
Object.defineProperty(exports, "EMAIL_ACCOUNTS_MAX", { enumerable: true, get: function () { return signIn_2.EMAIL_ACCOUNTS_MAX; } });
|
|
55
|
+
Object.defineProperty(exports, "isSecondFactorRequired", { enumerable: true, get: function () { return signIn_2.isSecondFactorRequired; } });
|
|
56
|
+
Object.defineProperty(exports, "isEmailSignInChooseAccount", { enumerable: true, get: function () { return signIn_2.isEmailSignInChooseAccount; } });
|
|
57
|
+
Object.defineProperty(exports, "REAUTH_ACTIONS", { enumerable: true, get: function () { return signIn_2.REAUTH_ACTIONS; } });
|
|
58
|
+
Object.defineProperty(exports, "SIGN_IN_ERROR_CODES", { enumerable: true, get: function () { return signIn_2.SIGN_IN_ERROR_CODES; } });
|
|
69
59
|
const sixDigits = zod_1.z
|
|
70
60
|
.string()
|
|
71
61
|
.trim()
|
|
@@ -78,17 +68,17 @@ const opaqueTokenSchema = accountEmail_1.emailTicketSchema;
|
|
|
78
68
|
/** A username or an email. */
|
|
79
69
|
exports.signInIdentifierSchema = zod_1.z.string().trim().min(1).max(254);
|
|
80
70
|
/** A password as typed. Its policy applies only when one is set. */
|
|
81
|
-
exports.passwordInputSchema = zod_1.z.string().min(1).max(
|
|
71
|
+
exports.passwordInputSchema = zod_1.z.string().min(1).max(signIn_1.PASSWORD_MAX_LENGTH);
|
|
82
72
|
/** A new password. */
|
|
83
73
|
exports.newPasswordSchema = zod_1.z
|
|
84
74
|
.string()
|
|
85
|
-
.min(
|
|
86
|
-
.max(
|
|
75
|
+
.min(signIn_1.PASSWORD_MIN_LENGTH, `password must be at least ${signIn_1.PASSWORD_MIN_LENGTH} characters`)
|
|
76
|
+
.max(signIn_1.PASSWORD_MAX_LENGTH, `password must be at most ${signIn_1.PASSWORD_MAX_LENGTH} characters`);
|
|
87
77
|
/**
|
|
88
78
|
* An authenticator code (6 digits) or a backup code (10 characters, with or
|
|
89
79
|
* without its dash). Normalised server-side.
|
|
90
80
|
*/
|
|
91
|
-
exports.secondFactorCodeSchema = zod_1.z.string().trim().min(
|
|
81
|
+
exports.secondFactorCodeSchema = zod_1.z.string().trim().min(signIn_1.TOTP_DIGITS).max(16);
|
|
92
82
|
/** The device-session fields every body that ends in a session may carry. */
|
|
93
83
|
const sessionEnvelope = {
|
|
94
84
|
deviceName: zod_1.z.string().trim().min(1).max(120).optional(),
|
|
@@ -121,11 +111,11 @@ exports.emailSignInCodeSchema = zod_1.z
|
|
|
121
111
|
.string()
|
|
122
112
|
.trim()
|
|
123
113
|
.refine((value) => {
|
|
124
|
-
const code = normalizeEmailSignInCode(value);
|
|
114
|
+
const code = (0, signIn_1.normalizeEmailSignInCode)(value);
|
|
125
115
|
return (new RegExp(`^\\d{${accountEmail_1.EMAIL_CODE_LENGTH}}$`).test(code) ||
|
|
126
|
-
new RegExp(`^[${
|
|
116
|
+
new RegExp(`^[${signIn_1.EMAIL_SIGNIN_LONG_CODE_ALPHABET}]{${signIn_1.EMAIL_SIGNIN_LONG_CODE_LENGTH}}$`).test(code));
|
|
127
117
|
}, {
|
|
128
|
-
message: `code must be ${accountEmail_1.EMAIL_CODE_LENGTH} digits or the ${
|
|
118
|
+
message: `code must be ${accountEmail_1.EMAIL_CODE_LENGTH} digits or the ${signIn_1.EMAIL_SIGNIN_LONG_CODE_LENGTH}-character code from the email`,
|
|
129
119
|
});
|
|
130
120
|
/** `POST /auth/signin/email/confirm` — the code from the email. */
|
|
131
121
|
exports.emailSignInConfirmRequestSchema = zod_1.z
|
|
@@ -193,23 +183,28 @@ exports.emailSignInPendingSchema = zod_1.z.object({
|
|
|
193
183
|
status: zod_1.z.literal('pending'),
|
|
194
184
|
expiresAt: zod_1.z.number().int().positive(),
|
|
195
185
|
});
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
exports.
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
186
|
+
exports.emailSignInAccountOptionSchema = zod_1.z.object({
|
|
187
|
+
id: zod_1.z.string().min(1).max(64),
|
|
188
|
+
username: zod_1.z.string().min(1).optional(),
|
|
189
|
+
displayName: zod_1.z.string().min(1).optional(),
|
|
190
|
+
avatar: zod_1.z.string().min(1).optional(),
|
|
191
|
+
});
|
|
192
|
+
exports.emailSignInChooseAccountSchema = zod_1.z.object({
|
|
193
|
+
chooseAccount: zod_1.z.literal(true),
|
|
194
|
+
accounts: zod_1.z.array(exports.emailSignInAccountOptionSchema).min(2).max(signIn_1.EMAIL_ACCOUNTS_MAX),
|
|
195
|
+
expiresAt: zod_1.z.number().int().positive(),
|
|
196
|
+
});
|
|
197
|
+
/** `POST /auth/signin/email/choose` — the account, from those {@link EmailSignInChooseAccount} listed. */
|
|
198
|
+
exports.emailSignInChooseRequestSchema = zod_1.z
|
|
199
|
+
.object({
|
|
200
|
+
requestId: zod_1.z.string().trim().min(1).max(64),
|
|
201
|
+
requestSecret: opaqueTokenSchema,
|
|
202
|
+
userId: zod_1.z.string().trim().min(1).max(64),
|
|
203
|
+
...sessionEnvelope,
|
|
204
|
+
})
|
|
205
|
+
.strict();
|
|
211
206
|
/** `POST /users/me/reauth/email` */
|
|
212
|
-
exports.reauthEmailStartRequestSchema = zod_1.z.object({ action: zod_1.z.enum(
|
|
207
|
+
exports.reauthEmailStartRequestSchema = zod_1.z.object({ action: zod_1.z.enum(signIn_1.REAUTH_ACTIONS) }).strict();
|
|
213
208
|
/**
|
|
214
209
|
* A fresh proof that the person, not only their session, is asking: the
|
|
215
210
|
* current password, or a code just sent to the account's email
|
|
@@ -270,7 +265,7 @@ exports.totpConfirmRequestSchema = zod_1.z
|
|
|
270
265
|
code: zod_1.z
|
|
271
266
|
.string()
|
|
272
267
|
.trim()
|
|
273
|
-
.regex(new RegExp(`^\\d{${
|
|
268
|
+
.regex(new RegExp(`^\\d{${signIn_1.TOTP_DIGITS}}$`)),
|
|
274
269
|
reauth: exports.reauthProofSchema,
|
|
275
270
|
})
|
|
276
271
|
.strict();
|
|
@@ -279,39 +274,5 @@ exports.totpReauthRequestSchema = zod_1.z.object({ reauth: exports.reauthProofSc
|
|
|
279
274
|
exports.totpBackupCodesResponseSchema = zod_1.z.object({
|
|
280
275
|
backupCodes: zod_1.z
|
|
281
276
|
.array(zod_1.z.string().regex(/^[a-z2-9]{5}-[a-z2-9]{5}$/))
|
|
282
|
-
.length(
|
|
277
|
+
.length(signIn_1.TOTP_BACKUP_CODE_COUNT),
|
|
283
278
|
});
|
|
284
|
-
/**
|
|
285
|
-
* Stable error codes (`error.code` in the API error body). Clients map these
|
|
286
|
-
* through their localization, never the English message.
|
|
287
|
-
*/
|
|
288
|
-
exports.SIGN_IN_ERROR_CODES = {
|
|
289
|
-
/** Wrong identifier or password — never says which. */
|
|
290
|
-
invalidCredentials: 'SIGNIN_INVALID_CREDENTIALS',
|
|
291
|
-
/** The request is unknown, expired, spent, or its secret is wrong. */
|
|
292
|
-
requestInvalid: 'SIGNIN_REQUEST_INVALID',
|
|
293
|
-
/** The link is unknown, expired or already used. */
|
|
294
|
-
linkInvalid: 'SIGNIN_LINK_INVALID',
|
|
295
|
-
/** The link was opened in another browser: type the code in the app instead. */
|
|
296
|
-
linkOtherDevice: 'SIGNIN_LINK_OTHER_DEVICE',
|
|
297
|
-
/** The second-factor challenge or its code is wrong, expired or spent. */
|
|
298
|
-
secondFactorInvalid: 'SECOND_FACTOR_INVALID',
|
|
299
|
-
/** Too many failures for this account: wait and try again. */
|
|
300
|
-
locked: 'SIGNIN_LOCKED',
|
|
301
|
-
/** The step needs a fresh proof (`reauth`). */
|
|
302
|
-
reauthRequired: 'REAUTH_REQUIRED',
|
|
303
|
-
/** The fresh proof was wrong. */
|
|
304
|
-
reauthInvalid: 'REAUTH_INVALID',
|
|
305
|
-
/** The account has an authenticator: the proof must carry its code. */
|
|
306
|
-
totpRequired: 'TOTP_REQUIRED',
|
|
307
|
-
/** Enrolling or confirming an authenticator that is already on. */
|
|
308
|
-
totpAlreadyEnabled: 'TOTP_ALREADY_ENABLED',
|
|
309
|
-
/** Disabling, confirming or regenerating codes with no authenticator (or no pending one). */
|
|
310
|
-
totpNotEnabled: 'TOTP_NOT_ENABLED',
|
|
311
|
-
/** The code the authenticator showed at enrolment is wrong. */
|
|
312
|
-
totpCodeInvalid: 'TOTP_CODE_INVALID',
|
|
313
|
-
/** Only official Oxy apps and auth.oxy.so may sign people in here. */
|
|
314
|
-
originNotAllowed: 'SIGNIN_ORIGIN_NOT_ALLOWED',
|
|
315
|
-
/** The username is taken. */
|
|
316
|
-
usernameTaken: 'USERNAME_TAKEN',
|
|
317
|
-
};
|
package/dist/cjs/userResponse.js
CHANGED
|
@@ -246,10 +246,6 @@ exports.userResponseSchema = zod_1.z
|
|
|
246
246
|
* so it is present on the current-user DTO (`GET /users/me`,
|
|
247
247
|
* `GET /session/user/:sessionId`) and absent until the user sets it.
|
|
248
248
|
*/
|
|
249
|
-
userPreferences: zod_1.z
|
|
250
|
-
.object({ displayCurrency: zod_1.z.enum(['USD', 'EUR', 'FAIR']).optional() })
|
|
251
|
-
.catchall(zod_1.z.unknown())
|
|
252
|
-
.optional(),
|
|
253
249
|
themePreference: exports.themePreferenceSchema.optional(),
|
|
254
250
|
personalization: zod_1.z
|
|
255
251
|
.object({
|
|
@@ -310,10 +306,7 @@ exports.userProfileUpdateSchema = zod_1.z
|
|
|
310
306
|
languages: zod_1.z.array(zod_1.z.string()).optional(),
|
|
311
307
|
accountExpiresAfterInactivityDays: zod_1.z.number().nullable().optional(),
|
|
312
308
|
notificationPreferences: zod_1.z.record(zod_1.z.unknown()).optional(),
|
|
313
|
-
userPreferences: zod_1.z
|
|
314
|
-
.object({ displayCurrency: zod_1.z.enum(['USD', 'EUR', 'FAIR']).optional() })
|
|
315
|
-
.catchall(zod_1.z.unknown())
|
|
316
|
-
.optional(),
|
|
309
|
+
userPreferences: zod_1.z.record(zod_1.z.unknown()).optional(),
|
|
317
310
|
privacySettings: zod_1.z.record(zod_1.z.unknown()).optional(),
|
|
318
311
|
/**
|
|
319
312
|
* Portable theme preference. Written through the same `PUT /users/me`
|
package/dist/cjs/username.js
CHANGED
|
@@ -100,106 +100,25 @@
|
|
|
100
100
|
* knows what is taken, and it must not pretend to.
|
|
101
101
|
*/
|
|
102
102
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
103
|
-
exports.botUsernameSchema = exports.BOT_USERNAME_INVALID_MESSAGE = exports.BOT_USERNAME_SUFFIX = exports.
|
|
103
|
+
exports.botUsernameSchema = exports.usernameSchema = exports.applyBotUsernameSuffix = exports.BOT_USERNAME_INVALID_MESSAGE = exports.BOT_USERNAME_SUFFIX = exports.stripDisallowedUsernameCharacters = exports.USERNAME_PATTERN_SOURCE = exports.NUMERIC_USERNAME_MESSAGE = exports.RESERVED_USERNAME_MESSAGE = exports.RESERVED_USERNAMES = exports.USERNAME_INVALID_MESSAGE = exports.USERNAME_MAX_LENGTH = exports.USERNAME_MIN_LENGTH = void 0;
|
|
104
104
|
exports.isValidUsername = isValidUsername;
|
|
105
|
-
exports.stripDisallowedUsernameCharacters = stripDisallowedUsernameCharacters;
|
|
106
105
|
exports.usernameSchemaForAccountKind = usernameSchemaForAccountKind;
|
|
107
|
-
exports.applyBotUsernameSuffix = applyBotUsernameSuffix;
|
|
108
106
|
const zod_1 = require("zod");
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
exports
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
*
|
|
125
|
-
* `oxy`, `mention`, `homiio`, `clarity`, `faircoin`, `astro` and `mercaria`
|
|
126
|
-
* are deliberately NOT here: each already has an `organization`/`project`
|
|
127
|
-
* row, so the unique index already refuses a second one, and `oxy` is the
|
|
128
|
-
* name `USERNAME_MIN_LENGTH` is pinned against in
|
|
129
|
-
* `__tests__/username.test.ts` — listing it would make
|
|
130
|
-
* `usernameSchema.safeParse('oxy')` fail and falsify that comment. A brand
|
|
131
|
-
* with no account of its own yet (measured 2026-09-18: Alia, Allo, TNP,
|
|
132
|
-
* Kaana, Bloom) has no row to protect it, so it is listed until one exists.
|
|
133
|
-
*/
|
|
134
|
-
exports.RESERVED_USERNAMES = new Set([
|
|
135
|
-
// Oxy product lines with no account row of their own yet.
|
|
136
|
-
'alia',
|
|
137
|
-
'allo',
|
|
138
|
-
'tnp',
|
|
139
|
-
'kaana',
|
|
140
|
-
'bloom',
|
|
141
|
-
// System / role words a signup impersonating staff or Oxy itself would reach for.
|
|
142
|
-
'admin',
|
|
143
|
-
'administrator',
|
|
144
|
-
'root',
|
|
145
|
-
'superadmin',
|
|
146
|
-
'super',
|
|
147
|
-
'superuser',
|
|
148
|
-
'support',
|
|
149
|
-
'staff',
|
|
150
|
-
'moderator',
|
|
151
|
-
'mod',
|
|
152
|
-
'security',
|
|
153
|
-
'system',
|
|
154
|
-
'official',
|
|
155
|
-
'help',
|
|
156
|
-
'noreply',
|
|
157
|
-
'anonymous',
|
|
158
|
-
'everyone',
|
|
159
|
-
'owner',
|
|
160
|
-
]);
|
|
161
|
-
/** The 400 / inline-validation copy for a handle on {@link RESERVED_USERNAMES}. */
|
|
162
|
-
exports.RESERVED_USERNAME_MESSAGE = 'This username is reserved and cannot be registered';
|
|
163
|
-
/**
|
|
164
|
-
* {@link RESERVED_USERNAMES}, minus `alia`, checked against each `-`/`_`
|
|
165
|
-
* separated SEGMENT of a candidate rather than the whole string — so
|
|
166
|
-
* `official-oxy`, `super-admin` and `team-kaana` are refused the same as the
|
|
167
|
-
* bare words, without banning every word that merely CONTAINS one as a
|
|
168
|
-
* substring (`superman`, `modern`, `grassroot`, `homeowner` all stay legal:
|
|
169
|
-
* none of them separates the reserved word from the rest with `-` or `_`).
|
|
170
|
-
*
|
|
171
|
-
* `alia` is excluded because `alia-` is the live internal-cost-centre
|
|
172
|
-
* namespace: `alia-production-chat` is a minted account and
|
|
173
|
-
* `alia-research` / `alia-voice` / `alia-evaluations` are pinned as legal
|
|
174
|
-
* slugs in `__tests__/username.test.ts` and `internalCostCenterSpecs.test.ts`.
|
|
175
|
-
* Segment-matching `alia` would refuse all four. The bare word `alia` is
|
|
176
|
-
* still refused — {@link RESERVED_USERNAMES} above catches it exactly.
|
|
177
|
-
*/
|
|
178
|
-
const RESERVED_USERNAME_SEGMENTS = new Set([...exports.RESERVED_USERNAMES].filter((word) => word !== 'alia'));
|
|
179
|
-
/** The 400 / inline-validation copy for a handle that is only digits. */
|
|
180
|
-
exports.NUMERIC_USERNAME_MESSAGE = 'Username cannot be only numbers';
|
|
181
|
-
/**
|
|
182
|
-
* Alphanumeric runs joined by single separators, as a SOURCE string.
|
|
183
|
-
*
|
|
184
|
-
* A string rather than a literal because the OpenAPI docblocks that publish this
|
|
185
|
-
* rule (`POST /auth/register`, `PUT /users/:userId`) must quote it verbatim, and
|
|
186
|
-
* `usernamePolicySingleSource.test.ts` compares them against THIS constant. A
|
|
187
|
-
* published `pattern:` that drifts from the enforced rule is a lie told to every
|
|
188
|
-
* client that generates from the spec, and it is exactly the kind of copy nobody
|
|
189
|
-
* notices going stale.
|
|
190
|
-
*
|
|
191
|
-
* Deliberately NOT re-exported from the package barrel: it exists for the
|
|
192
|
-
* schema below and for that one gate. Anything validating a username uses
|
|
193
|
-
* {@link usernameSchema}, so there is no second way to ask the question.
|
|
194
|
-
*
|
|
195
|
-
* Written as an unambiguous alternation rather than a lookahead: every character
|
|
196
|
-
* belongs to exactly one branch, so matching is linear and there is no
|
|
197
|
-
* backtracking to bound. It also carries no `\p{…}` property escape, which
|
|
198
|
-
* mobile Hermes throws on at runtime — this module is reachable from every React
|
|
199
|
-
* Native consumer.
|
|
200
|
-
*/
|
|
201
|
-
exports.USERNAME_PATTERN_SOURCE = '^[A-Za-z0-9]+(?:[-_][A-Za-z0-9]+)*$';
|
|
202
|
-
const USERNAME_PATTERN = new RegExp(exports.USERNAME_PATTERN_SOURCE);
|
|
107
|
+
// The Zod-free half of this contract lives in `./client/` (`@oxy.so/contracts/client`);
|
|
108
|
+
// it is re-exported here so the root entry is unchanged.
|
|
109
|
+
const username_1 = require("./client/username");
|
|
110
|
+
var username_2 = require("./client/username");
|
|
111
|
+
Object.defineProperty(exports, "USERNAME_MIN_LENGTH", { enumerable: true, get: function () { return username_2.USERNAME_MIN_LENGTH; } });
|
|
112
|
+
Object.defineProperty(exports, "USERNAME_MAX_LENGTH", { enumerable: true, get: function () { return username_2.USERNAME_MAX_LENGTH; } });
|
|
113
|
+
Object.defineProperty(exports, "USERNAME_INVALID_MESSAGE", { enumerable: true, get: function () { return username_2.USERNAME_INVALID_MESSAGE; } });
|
|
114
|
+
Object.defineProperty(exports, "RESERVED_USERNAMES", { enumerable: true, get: function () { return username_2.RESERVED_USERNAMES; } });
|
|
115
|
+
Object.defineProperty(exports, "RESERVED_USERNAME_MESSAGE", { enumerable: true, get: function () { return username_2.RESERVED_USERNAME_MESSAGE; } });
|
|
116
|
+
Object.defineProperty(exports, "NUMERIC_USERNAME_MESSAGE", { enumerable: true, get: function () { return username_2.NUMERIC_USERNAME_MESSAGE; } });
|
|
117
|
+
Object.defineProperty(exports, "USERNAME_PATTERN_SOURCE", { enumerable: true, get: function () { return username_2.USERNAME_PATTERN_SOURCE; } });
|
|
118
|
+
Object.defineProperty(exports, "stripDisallowedUsernameCharacters", { enumerable: true, get: function () { return username_2.stripDisallowedUsernameCharacters; } });
|
|
119
|
+
Object.defineProperty(exports, "BOT_USERNAME_SUFFIX", { enumerable: true, get: function () { return username_2.BOT_USERNAME_SUFFIX; } });
|
|
120
|
+
Object.defineProperty(exports, "BOT_USERNAME_INVALID_MESSAGE", { enumerable: true, get: function () { return username_2.BOT_USERNAME_INVALID_MESSAGE; } });
|
|
121
|
+
Object.defineProperty(exports, "applyBotUsernameSuffix", { enumerable: true, get: function () { return username_2.applyBotUsernameSuffix; } });
|
|
203
122
|
/**
|
|
204
123
|
* The one username policy, as a schema.
|
|
205
124
|
*
|
|
@@ -212,14 +131,14 @@ const USERNAME_PATTERN = new RegExp(exports.USERNAME_PATTERN_SOURCE);
|
|
|
212
131
|
exports.usernameSchema = zod_1.z
|
|
213
132
|
.string()
|
|
214
133
|
.trim()
|
|
215
|
-
.min(
|
|
216
|
-
.max(
|
|
217
|
-
.regex(USERNAME_PATTERN,
|
|
218
|
-
.refine((username) => !/^[0-9]+$/.test(username),
|
|
219
|
-
.refine((username) => !
|
|
134
|
+
.min(username_1.USERNAME_MIN_LENGTH, username_1.USERNAME_INVALID_MESSAGE)
|
|
135
|
+
.max(username_1.USERNAME_MAX_LENGTH, username_1.USERNAME_INVALID_MESSAGE)
|
|
136
|
+
.regex(username_1.USERNAME_PATTERN, username_1.USERNAME_INVALID_MESSAGE)
|
|
137
|
+
.refine((username) => !/^[0-9]+$/.test(username), username_1.NUMERIC_USERNAME_MESSAGE)
|
|
138
|
+
.refine((username) => !username_1.RESERVED_USERNAMES.has(username.toLowerCase()), username_1.RESERVED_USERNAME_MESSAGE)
|
|
220
139
|
.refine((username) => !username
|
|
221
140
|
.split(/[-_]/)
|
|
222
|
-
.some((segment) => RESERVED_USERNAME_SEGMENTS.has(segment.toLowerCase())),
|
|
141
|
+
.some((segment) => username_1.RESERVED_USERNAME_SEGMENTS.has(segment.toLowerCase())), username_1.RESERVED_USERNAME_MESSAGE);
|
|
223
142
|
/**
|
|
224
143
|
* Whether a candidate handle is storable — the boolean form, for input surfaces
|
|
225
144
|
* that show a message as somebody types rather than throwing.
|
|
@@ -230,36 +149,6 @@ exports.usernameSchema = zod_1.z
|
|
|
230
149
|
function isValidUsername(candidate) {
|
|
231
150
|
return exports.usernameSchema.safeParse(candidate).success;
|
|
232
151
|
}
|
|
233
|
-
/**
|
|
234
|
-
* Drop the characters the policy forbids, for an input field that filters
|
|
235
|
-
* keystrokes.
|
|
236
|
-
*
|
|
237
|
-
* This is a TYPING aid and nothing else — the result still has to pass
|
|
238
|
-
* {@link usernameSchema}, which is what decides. It does not lower-case (case is
|
|
239
|
-
* preserved, see the header) and it cannot repair a name: a value that is too
|
|
240
|
-
* short, edge-separated or doubly-separated comes back unchanged and fails
|
|
241
|
-
* validation with a message, which is the outcome the coercing rules this
|
|
242
|
-
* replaces used to hide.
|
|
243
|
-
*/
|
|
244
|
-
function stripDisallowedUsernameCharacters(input) {
|
|
245
|
-
return input.replace(/[^A-Za-z0-9_-]/g, '');
|
|
246
|
-
}
|
|
247
|
-
/**
|
|
248
|
-
* The label a bot's handle ends in — the ONE exception the policy carries.
|
|
249
|
-
*
|
|
250
|
-
* Lower-case here because it is what a generator appends; the comparison that
|
|
251
|
-
* enforces it folds case, so `MyBot` satisfies it just as `mybot` does.
|
|
252
|
-
*
|
|
253
|
-
* Deliberately NOT re-exported from the package barrel, for the same reason
|
|
254
|
-
* {@link USERNAME_PATTERN_SOURCE} is not: it exists for the schema and the
|
|
255
|
-
* generator aid below. A consumer that wants to SAY the rule uses
|
|
256
|
-
* {@link BOT_USERNAME_INVALID_MESSAGE}, which already quotes it, and one that
|
|
257
|
-
* wants to APPLY it uses {@link applyBotUsernameSuffix} — so there is no second
|
|
258
|
-
* way to spell the check.
|
|
259
|
-
*/
|
|
260
|
-
exports.BOT_USERNAME_SUFFIX = 'bot';
|
|
261
|
-
/** The 400 / inline-validation copy for a bot handle that carries no label. */
|
|
262
|
-
exports.BOT_USERNAME_INVALID_MESSAGE = `A bot account's username must end in "${exports.BOT_USERNAME_SUFFIX}"`;
|
|
263
152
|
/**
|
|
264
153
|
* The username policy for an account of kind `bot`: everything above, plus a
|
|
265
154
|
* handle that ends in {@link BOT_USERNAME_SUFFIX}.
|
|
@@ -317,7 +206,7 @@ exports.BOT_USERNAME_INVALID_MESSAGE = `A bot account's username must end in "${
|
|
|
317
206
|
* `community-maestro`, `community-pulse`, `garden-helper`, `luna`, `verity`).
|
|
318
207
|
* They go on loading and resolving; only a NEW handle is held to this.
|
|
319
208
|
*/
|
|
320
|
-
exports.botUsernameSchema = exports.usernameSchema.refine((username) => username.toLowerCase().endsWith(
|
|
209
|
+
exports.botUsernameSchema = exports.usernameSchema.refine((username) => username.toLowerCase().endsWith(username_1.BOT_USERNAME_SUFFIX), username_1.BOT_USERNAME_INVALID_MESSAGE);
|
|
321
210
|
/**
|
|
322
211
|
* The policy that governs a handle, given the kind of account that will hold it.
|
|
323
212
|
*
|
|
@@ -334,27 +223,3 @@ exports.botUsernameSchema = exports.usernameSchema.refine((username) => username
|
|
|
334
223
|
function usernameSchemaForAccountKind(kind) {
|
|
335
224
|
return kind === 'bot' ? exports.botUsernameSchema : exports.usernameSchema;
|
|
336
225
|
}
|
|
337
|
-
/**
|
|
338
|
-
* Label a proposed bot handle, so a generator PROPOSES something the server will
|
|
339
|
-
* accept.
|
|
340
|
-
*
|
|
341
|
-
* Alia builds an agent's handle from its display name; without this it would
|
|
342
|
-
* propose `garden-helper` for a bot and be 400ed on submit, which is the same
|
|
343
|
-
* "suggest, then refuse" defect the minimum length already caused once.
|
|
344
|
-
*
|
|
345
|
-
* It appends and never inserts: a separator is the caller's choice, so
|
|
346
|
-
* `garden-helper` becomes `garden-helperbot` while a caller who typed
|
|
347
|
-
* `garden-helper-` gets `garden-helper-bot`. It truncates to leave room rather
|
|
348
|
-
* than overflowing {@link USERNAME_MAX_LENGTH}.
|
|
349
|
-
*
|
|
350
|
-
* Like {@link stripDisallowedUsernameCharacters} it is an aid, not a decision: it
|
|
351
|
-
* cannot repair a handle the base policy refuses, and the result still has to
|
|
352
|
-
* pass {@link botUsernameSchema}.
|
|
353
|
-
*/
|
|
354
|
-
function applyBotUsernameSuffix(candidate) {
|
|
355
|
-
const trimmed = candidate.trim();
|
|
356
|
-
if (trimmed.toLowerCase().endsWith(exports.BOT_USERNAME_SUFFIX)) {
|
|
357
|
-
return trimmed;
|
|
358
|
-
}
|
|
359
|
-
return trimmed.slice(0, exports.USERNAME_MAX_LENGTH - exports.BOT_USERNAME_SUFFIX.length) + exports.BOT_USERNAME_SUFFIX;
|
|
360
|
-
}
|