@oxy.so/contracts 2.2.0 → 3.0.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 +21 -25
- package/dist/cjs/deviceBoot.js +2 -2
- package/dist/cjs/deviceSession.js +73 -16
- package/dist/cjs/identity.js +1 -3
- package/dist/cjs/identityLink.js +22 -19
- package/dist/cjs/identityProof.js +2 -2
- package/dist/cjs/index.js +59 -28
- package/dist/cjs/reputation.js +10 -55
- package/dist/cjs/signIn.js +304 -0
- package/dist/esm/.tsbuildinfo +1 -1
- package/dist/esm/accountEmail.js +21 -25
- package/dist/esm/deviceBoot.js +2 -2
- package/dist/esm/deviceSession.js +72 -15
- package/dist/esm/identity.js +1 -3
- package/dist/esm/identityLink.js +21 -18
- package/dist/esm/identityProof.js +2 -2
- package/dist/esm/index.js +11 -11
- package/dist/esm/reputation.js +9 -54
- package/dist/esm/signIn.js +299 -0
- package/dist/types/.tsbuildinfo +1 -1
- package/dist/types/accountEmail.d.ts +20 -28
- package/dist/types/accountGraph.d.ts +4 -4
- package/dist/types/deviceBoot.d.ts +2 -2
- package/dist/types/deviceSession.d.ts +127 -15
- package/dist/types/externalIdentity.d.ts +4 -4
- package/dist/types/identity.d.ts +4 -8
- package/dist/types/identityLink.d.ts +54 -118
- package/dist/types/identityProof.d.ts +3 -3
- package/dist/types/index.d.ts +8 -8
- package/dist/types/inference/entitlement.d.ts +2 -2
- package/dist/types/oauth.d.ts +16 -16
- package/dist/types/reputation.d.ts +32 -127
- package/dist/types/signIn.d.ts +717 -0
- package/dist/types/userResponse.d.ts +2 -2
- package/package.json +1 -1
- package/dist/cjs/webauthn.js +0 -114
- package/dist/esm/webauthn.js +0 -111
- package/dist/types/webauthn.d.ts +0 -173
package/dist/esm/accountEmail.js
CHANGED
|
@@ -1,22 +1,26 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Email codes and tickets (ADR 0030).
|
|
3
3
|
*
|
|
4
|
-
* A web account is a username
|
|
5
|
-
*
|
|
6
|
-
* ticket the next step spends:
|
|
4
|
+
* A web account is a username and an email; a password and an authenticator
|
|
5
|
+
* app are optional and added later. The email is proven by a 6-digit code sent
|
|
6
|
+
* to it, and the proof is a short-lived one-use ticket the next step spends:
|
|
7
7
|
*
|
|
8
|
-
* - `signup`: the ticket lets `POST /
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* account's recovery email, and the ticket lets them register a new passkey
|
|
12
|
-
* for that account.
|
|
8
|
+
* - `signup`: the ticket lets `POST /auth/signup` create the account with that
|
|
9
|
+
* email. `start` answers the same whether or not the address already has an
|
|
10
|
+
* account, so it never tells anyone which emails have an Oxy account.
|
|
13
11
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* Commons key has no recovery email: it recovers in Commons.
|
|
12
|
+
* Signing in by email (`signin`) and re-verifying before a sensitive change
|
|
13
|
+
* (`reauth`) use the same code, through their own routes (`signIn.ts`).
|
|
17
14
|
*/
|
|
18
15
|
import { z } from 'zod';
|
|
19
|
-
|
|
16
|
+
/**
|
|
17
|
+
* - `signup`: above.
|
|
18
|
+
* - `signin`: the code (and link) of an email sign-in (`POST /auth/signin/email/start`).
|
|
19
|
+
* - `reauth`: a signed-in person proving it is them before a sensitive step
|
|
20
|
+
* (`POST /users/me/reauth/email`): a password, an authenticator, deleting the
|
|
21
|
+
* account, linking Commons.
|
|
22
|
+
*/
|
|
23
|
+
export const EMAIL_VERIFICATION_PURPOSES = ['signup', 'signin', 'reauth'];
|
|
20
24
|
/** Digits in a code. */
|
|
21
25
|
export const EMAIL_CODE_LENGTH = 6;
|
|
22
26
|
/** How long a code can be confirmed. */
|
|
@@ -33,16 +37,9 @@ export const emailTicketSchema = z
|
|
|
33
37
|
.trim()
|
|
34
38
|
.regex(/^[A-Za-z0-9_-]{43}$/, 'ticket must be 32 bytes of base64url');
|
|
35
39
|
/** `POST /auth/email/verify/start` */
|
|
36
|
-
export const emailVerificationStartRequestSchema = z
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
.object({
|
|
40
|
-
purpose: z.literal('recovery'),
|
|
41
|
-
/** The account's username, or its recovery email. */
|
|
42
|
-
identifier: z.string().trim().min(1).max(254),
|
|
43
|
-
})
|
|
44
|
-
.strict(),
|
|
45
|
-
]);
|
|
40
|
+
export const emailVerificationStartRequestSchema = z
|
|
41
|
+
.object({ purpose: z.literal('signup'), email: emailAddressSchema })
|
|
42
|
+
.strict();
|
|
46
43
|
export const emailVerificationStartResponseSchema = z.object({
|
|
47
44
|
verificationId: z.string().min(1).max(64),
|
|
48
45
|
expiresAt: z.number().int().positive(),
|
|
@@ -60,7 +57,6 @@ export const emailVerificationConfirmRequestSchema = z
|
|
|
60
57
|
export const emailVerificationConfirmResponseSchema = z.object({
|
|
61
58
|
ticket: emailTicketSchema,
|
|
62
59
|
expiresAt: z.number().int().positive(),
|
|
63
|
-
username: z.string().nullable(),
|
|
64
60
|
});
|
|
65
61
|
/**
|
|
66
62
|
* Stable error codes (`error.code` in the API error body). Clients map these
|
|
@@ -73,7 +69,7 @@ export const EMAIL_VERIFICATION_ERROR_CODES = {
|
|
|
73
69
|
tooManyAttempts: 'EMAIL_CODE_TOO_MANY_ATTEMPTS',
|
|
74
70
|
/** The ticket is unknown, expired, spent, or for another email or purpose. */
|
|
75
71
|
ticketInvalid: 'EMAIL_TICKET_INVALID',
|
|
76
|
-
/** A sign-up without a confirmed
|
|
72
|
+
/** A sign-up without a confirmed email. */
|
|
77
73
|
ticketRequired: 'EMAIL_TICKET_REQUIRED',
|
|
78
74
|
/** This server cannot send mail. */
|
|
79
75
|
unavailable: 'EMAIL_UNAVAILABLE',
|
package/dist/esm/deviceBoot.js
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* SINGLE SOURCE OF TRUTH for the first-party login result (the session arm). The
|
|
5
5
|
* API validates its OUTPUT against this schema; every consumer (`@oxy.so/core`'s
|
|
6
6
|
* auth mixin) validates its INPUT against the same definition, so producer and
|
|
7
|
-
* consumers cannot drift.
|
|
8
|
-
*
|
|
7
|
+
* consumers cannot drift. This is the session arm every sign-in
|
|
8
|
+
* ends in (email code or link, password, authenticator, Commons handoff).
|
|
9
9
|
*
|
|
10
10
|
* The device transport is `deviceId` + `deviceSecret` + `POST /session/device/token`
|
|
11
11
|
* (see `deviceSession.ts`). The legacy cookie/bootstrap/refresh-family lanes were
|
|
@@ -26,9 +26,10 @@ export const deviceSessionSyncSchema = z.object({
|
|
|
26
26
|
/**
|
|
27
27
|
* Request body for `POST /session/device/token` — the client presents the
|
|
28
28
|
* `deviceId` it stored first-party plus the opaque `deviceSecret`. NO bearer:
|
|
29
|
-
* possession of the secret IS the proof of device ownership. The server
|
|
30
|
-
* `sha256(deviceSecret)`
|
|
31
|
-
*
|
|
29
|
+
* possession of the secret IS the proof of device ownership. The server looks
|
|
30
|
+
* `sha256(deviceSecret)` up among the device's holder credentials (one per app
|
|
31
|
+
* or origin that joined the shared DeviceSession) and mints a short access
|
|
32
|
+
* token for the device's active account.
|
|
32
33
|
*
|
|
33
34
|
* `accountId` pins the mint to ONE account of that device instead of whichever
|
|
34
35
|
* account is currently active. It exists for identity-bound clients (Commons),
|
|
@@ -48,8 +49,8 @@ export const deviceTokenMintRequestSchema = z.object({
|
|
|
48
49
|
* short access token for the active account, its expiry, the device secret the
|
|
49
50
|
* client must persist (`nextDeviceSecret` — on mint this echoes the presented
|
|
50
51
|
* secret unchanged so concurrent refreshes from multiple origins do not race),
|
|
51
|
-
* and the projected device-session state.
|
|
52
|
-
*
|
|
52
|
+
* and the projected device-session state. Nothing rotates: each sign-in issues
|
|
53
|
+
* a NEW holder credential and leaves the others valid.
|
|
53
54
|
*/
|
|
54
55
|
export const deviceTokenMintResponseSchema = z.object({
|
|
55
56
|
accessToken: z.string(),
|
|
@@ -107,12 +108,11 @@ export const sessionAccountsChangedEventSchema = z.object({
|
|
|
107
108
|
* derived server-side from it) and consumed afterwards only by native
|
|
108
109
|
* background code, which has no JS runtime to mint a token for itself.
|
|
109
110
|
*
|
|
110
|
-
* Deliberately a SEPARATE credential from the
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
* anything JS reads.
|
|
111
|
+
* Deliberately a SEPARATE credential from the holder `deviceSecret`: that one
|
|
112
|
+
* is device-wide and mints for whichever account is active, while this one is
|
|
113
|
+
* bound to ONE account and expires, so a widget worker never holds a
|
|
114
|
+
* credential that reaches every account on the device. Background code is its
|
|
115
|
+
* sole writer and never touches anything JS reads.
|
|
116
116
|
*
|
|
117
117
|
* The raw `secret` is returned exactly once, at provision time — never stored
|
|
118
118
|
* retrievably, never logged, never re-read. A caller that loses it provisions
|
|
@@ -135,10 +135,10 @@ export const deviceBackgroundCredentialResponseSchema = z.object({
|
|
|
135
135
|
* native background code with NO bearer and NO cookies: possession of the
|
|
136
136
|
* background `secret` IS the proof, as it is for the device-secret mint.
|
|
137
137
|
*
|
|
138
|
-
*
|
|
139
|
-
* `next…` field
|
|
140
|
-
*
|
|
141
|
-
*
|
|
138
|
+
* Like that mint this one NEVER rotates the presented secret, and it carries
|
|
139
|
+
* no `next…` field at all, so background code interrupted anywhere between
|
|
140
|
+
* request and response leaves the credential intact and usable on its next
|
|
141
|
+
* run.
|
|
142
142
|
*/
|
|
143
143
|
export const deviceBackgroundTokenRequestSchema = z.object({
|
|
144
144
|
deviceId: z.string().min(1),
|
|
@@ -159,3 +159,60 @@ export const deviceBackgroundTokenResponseSchema = z.object({
|
|
|
159
159
|
expiresAt: z.string(),
|
|
160
160
|
accountId: z.string().min(1),
|
|
161
161
|
});
|
|
162
|
+
/* -------------------------------------------------------------------------- */
|
|
163
|
+
/* The browser bridge — joining the browser's DeviceSession (ADR 0029 D2) */
|
|
164
|
+
/* -------------------------------------------------------------------------- */
|
|
165
|
+
/**
|
|
166
|
+
* Proof that the caller holds a device: the `deviceId` it stored first-party and
|
|
167
|
+
* one of that device's holder secrets. Sent with `POST /session/device/join-code`
|
|
168
|
+
* and, optionally, with a sign-in (`POST /auth/session/claim`, the email,
|
|
169
|
+
* password and second-factor sign-ins, `POST /auth/signup`), where
|
|
170
|
+
* a valid proof puts the new session on THAT device so every app holding it sees
|
|
171
|
+
* the account. An invalid proof on a sign-in is ignored, never an error.
|
|
172
|
+
*/
|
|
173
|
+
export const deviceProofSchema = z.object({
|
|
174
|
+
deviceId: z.string().min(1).max(128),
|
|
175
|
+
deviceSecret: z.string().min(1).max(256),
|
|
176
|
+
});
|
|
177
|
+
/**
|
|
178
|
+
* `POST /session/device/register` — auth.oxy.so only. No body. A new, empty
|
|
179
|
+
* DeviceSession with a server-chosen `deviceId` and ONE holder credential for
|
|
180
|
+
* auth.oxy.so. The raw secret is returned exactly once.
|
|
181
|
+
*/
|
|
182
|
+
export const deviceRegisterResponseSchema = z.object({
|
|
183
|
+
deviceId: z.string().min(1),
|
|
184
|
+
deviceSecret: z.string().min(1),
|
|
185
|
+
});
|
|
186
|
+
/** PKCE S256 challenge: base64url of a SHA-256 digest (43 characters). */
|
|
187
|
+
const pkceS256ChallengeSchema = z.string().regex(/^[A-Za-z0-9_-]{43}$/);
|
|
188
|
+
/**
|
|
189
|
+
* `POST /session/device/join-code` — auth.oxy.so only (the bridge window). Proves
|
|
190
|
+
* auth.oxy.so's device and asks for a one-use code an official app redeems to
|
|
191
|
+
* join it. The code is bound to the application (`clientId`), its exact
|
|
192
|
+
* registered `redirectUri` and the app's PKCE challenge, and lives about a
|
|
193
|
+
* minute.
|
|
194
|
+
*/
|
|
195
|
+
export const deviceJoinCodeRequestSchema = deviceProofSchema.extend({
|
|
196
|
+
clientId: z.string().min(1).max(256),
|
|
197
|
+
redirectUri: z.string().url().max(2048),
|
|
198
|
+
codeChallenge: pkceS256ChallengeSchema,
|
|
199
|
+
codeChallengeMethod: z.literal('S256'),
|
|
200
|
+
});
|
|
201
|
+
export const deviceJoinCodeResponseSchema = z.object({
|
|
202
|
+
code: z.string().min(1),
|
|
203
|
+
/** Seconds until the code expires. */
|
|
204
|
+
expiresIn: z.number().int().positive(),
|
|
205
|
+
});
|
|
206
|
+
/**
|
|
207
|
+
* `POST /session/device/join` — called by the app's own origin with the code the
|
|
208
|
+
* bridge window posted to it and the PKCE verifier only the app holds. Returns a
|
|
209
|
+
* NEW holder credential for the browser's device; the app then mints through the
|
|
210
|
+
* ordinary `POST /session/device/token`.
|
|
211
|
+
*/
|
|
212
|
+
export const deviceJoinRequestSchema = z.object({
|
|
213
|
+
code: z.string().min(1).max(256),
|
|
214
|
+
codeVerifier: z.string().min(43).max(128).regex(/^[A-Za-z0-9._~-]+$/),
|
|
215
|
+
clientId: z.string().min(1).max(256),
|
|
216
|
+
redirectUri: z.string().url().max(2048),
|
|
217
|
+
});
|
|
218
|
+
export const deviceJoinResponseSchema = deviceRegisterResponseSchema;
|
package/dist/esm/identity.js
CHANGED
|
@@ -207,11 +207,9 @@ export const domainVerificationInstructionsSchema = z.object({
|
|
|
207
207
|
}),
|
|
208
208
|
});
|
|
209
209
|
export const authMethodEntrySchema = z.object({
|
|
210
|
-
type: z.
|
|
210
|
+
type: z.literal('identity'),
|
|
211
211
|
linkedAt: z.union([z.string(), z.date()]),
|
|
212
212
|
verificationMethodId: z.string().optional(),
|
|
213
|
-
credentialId: z.string().optional(),
|
|
214
|
-
name: z.string().optional(),
|
|
215
213
|
});
|
|
216
214
|
export const authMethodsResponseSchema = z.object({
|
|
217
215
|
did: z.string(),
|
package/dist/esm/identityLink.js
CHANGED
|
@@ -1,28 +1,31 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Linking Commons to a
|
|
2
|
+
* Linking Commons to an account without a key (ADR 0029 D3) — the two-device
|
|
3
|
+
* relay.
|
|
3
4
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* The authority is the same as `POST /auth/link` (ADR 0024 D8): a root
|
|
7
|
-
* (`link_identity`) by the key Commons holds
|
|
8
|
-
* the account's
|
|
9
|
-
*
|
|
5
|
+
* An account without a key links a Commons root once, and becomes
|
|
6
|
+
* self-custodied: its email is deleted and its phrase in Commons is how it gets
|
|
7
|
+
* back in. The authority is the same as `POST /auth/link` (ADR 0024 D8): a root
|
|
8
|
+
* proof (`link_identity`) by the key Commons holds over a one-use challenge,
|
|
9
|
+
* and the account's own confirmation — a code just sent to its email (plus its
|
|
10
|
+
* authenticator code when it has one). Only the transport is new, because the
|
|
11
|
+
* two factors live on two devices:
|
|
10
12
|
*
|
|
11
|
-
* 1.
|
|
12
|
-
* shown as a QR
|
|
13
|
+
* 1. The signed-in account (the "Link Commons" panel of `@oxy.so/services`)
|
|
14
|
+
* opens a link request → `{ linkId, challenge }`, shown as a QR
|
|
15
|
+
* (`oxycommons://link?id=…&c=…`).
|
|
13
16
|
* 2. Commons scans it, reads the request (the account's id and username),
|
|
14
17
|
* signs the root proof over the challenge and posts it with its key.
|
|
15
18
|
* 3. Both screens show the same 6-digit code, derived from the link id and
|
|
16
19
|
* that key (`deriveIdentityLinkCode` in `@oxy.so/core`); the person checks
|
|
17
20
|
* they match, so a photographed QR cannot slip another key in.
|
|
18
|
-
* 4.
|
|
19
|
-
*
|
|
21
|
+
* 4. The panel completes with the email code: the account gains the root,
|
|
22
|
+
* loses the email, and Commons signs in with it.
|
|
20
23
|
*
|
|
21
24
|
* The server stores only the challenge's hash; the challenge travels in the QR.
|
|
22
25
|
*/
|
|
23
26
|
import { z } from 'zod';
|
|
24
27
|
import { identityProofSchema } from './identityProof.js';
|
|
25
|
-
import {
|
|
28
|
+
import { emailReauthProofSchema } from './signIn.js';
|
|
26
29
|
export const IDENTITY_LINK_STATUSES = ['pending', 'signed', 'completed', 'cancelled'];
|
|
27
30
|
/** The scheme and host Commons routes a link QR to. */
|
|
28
31
|
export const IDENTITY_LINK_QR_PREFIX = 'oxycommons://link';
|
|
@@ -76,9 +79,9 @@ export const identityLinkProofRequestSchema = z
|
|
|
76
79
|
proof: identityProofSchema,
|
|
77
80
|
})
|
|
78
81
|
.strict();
|
|
79
|
-
/**
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
export const identityLinkCompleteRequestSchema = z.object({
|
|
82
|
+
/**
|
|
83
|
+
* `POST /identity/link/:linkId/complete` — the account's own confirmation: a
|
|
84
|
+
* code just sent to its email for this link (`reauth`, plus its authenticator
|
|
85
|
+
* code when it has one).
|
|
86
|
+
*/
|
|
87
|
+
export const identityLinkCompleteRequestSchema = z.object({ reauth: emailReauthProofSchema }).strict();
|
|
@@ -28,8 +28,8 @@ export const IDENTITY_PROOF_CHALLENGE_TTL_MS = 5 * 60 * 1000;
|
|
|
28
28
|
*/
|
|
29
29
|
export const IDENTITY_PROOF_ACTIONS = {
|
|
30
30
|
/**
|
|
31
|
-
* Link Commons' root to
|
|
32
|
-
* The account becomes self-custodied and its
|
|
31
|
+
* Link Commons' root to an account that has none (`POST /auth/link`).
|
|
32
|
+
* The account becomes self-custodied and its email is deleted
|
|
33
33
|
* (ADR 0029 D3).
|
|
34
34
|
*/
|
|
35
35
|
link: 'link_identity',
|
package/dist/esm/index.js
CHANGED
|
@@ -47,13 +47,13 @@ export {
|
|
|
47
47
|
// Closed value sets — shared by the API's mongoose enums, the API's request
|
|
48
48
|
// validation, and the SDK's unions, so a new category/tier/status cannot be
|
|
49
49
|
// added on one side only.
|
|
50
|
-
REPUTATION_CATEGORIES, REPUTATION_TRANSACTION_STATUSES, TRUST_TIERS, REPUTATION_TARGET_ENTITY_TYPES,
|
|
50
|
+
REPUTATION_CATEGORIES, REPUTATION_TRANSACTION_STATUSES, TRUST_TIERS, REPUTATION_TARGET_ENTITY_TYPES, REPUTATION_INFLUENCE_CONTEXTS,
|
|
51
51
|
// Schemas — closed value sets
|
|
52
|
-
reputationCategorySchema, reputationTransactionStatusSchema, trustTierSchema, reputationTargetEntityTypeSchema,
|
|
52
|
+
reputationCategorySchema, reputationTransactionStatusSchema, trustTierSchema, reputationTargetEntityTypeSchema, reputationInfluenceContextSchema,
|
|
53
53
|
// Schemas — responses
|
|
54
|
-
reputationTransactionSchema, reputationBalanceBreakdownSchema, reputationInfluenceSchema, reputationReliabilitySchema, reputationBalanceSummarySchema, reputationBalanceSchema,
|
|
54
|
+
reputationTransactionSchema, reputationBalanceBreakdownSchema, reputationInfluenceSchema, reputationReliabilitySchema, reputationBalanceSummarySchema, reputationBalanceSchema, reputationRuleSchema, reputationRulesResponseSchema, reputationLeaderboardUserSchema, reputationLeaderboardEntrySchema, reputationInfluenceResultSchema,
|
|
55
55
|
// Schemas — request bodies
|
|
56
|
-
awardReputationSchema,
|
|
56
|
+
awardReputationSchema,
|
|
57
57
|
// Narrows the two balance views apart at runtime.
|
|
58
58
|
isFullReputationBalance, } from './reputation.js';
|
|
59
59
|
export {
|
|
@@ -67,7 +67,7 @@ moderationFindingSchema, moderationDecisionEventSubjectSchema, moderationPolicyV
|
|
|
67
67
|
registerIdentityBindingSchema, identityBindingSchema,
|
|
68
68
|
// Schemas — the derived V2 axes
|
|
69
69
|
reputationPersonhoodSchema, reputationContributionSchema, reputationConductSchema, reputationReportingSchema, reputationReviewingSchema, reputationContextualInfluenceSchema, applicationModerationTrustSchema, } from './moderationReputation.js';
|
|
70
|
-
export { sessionAccountSchema, deviceSessionStateSchema, activeTokenSchema, deviceSessionSyncSchema, deviceTokenMintRequestSchema, deviceTokenMintResponseSchema, deviceBackgroundCredentialResponseSchema, deviceBackgroundTokenRequestSchema, deviceBackgroundTokenResponseSchema, SESSION_ACCOUNTS_CHANGED_EVENT, sessionAccountsChangedReasonSchema, sessionAccountsChangedEventSchema, } from './deviceSession.js';
|
|
70
|
+
export { sessionAccountSchema, deviceSessionStateSchema, activeTokenSchema, deviceSessionSyncSchema, deviceTokenMintRequestSchema, deviceTokenMintResponseSchema, deviceBackgroundCredentialResponseSchema, deviceBackgroundTokenRequestSchema, deviceBackgroundTokenResponseSchema, deviceProofSchema, deviceRegisterResponseSchema, deviceJoinCodeRequestSchema, deviceJoinCodeResponseSchema, deviceJoinRequestSchema, deviceJoinResponseSchema, SESSION_ACCOUNTS_CHANGED_EVENT, sessionAccountsChangedReasonSchema, sessionAccountsChangedEventSchema, } from './deviceSession.js';
|
|
71
71
|
export { deviceContextRelationshipSchema, deviceDirectoryProfileSchema, deviceAccountContextSchema, devicePrincipalSchema, deviceDirectorySchema, deviceActivateRequestSchema, deviceActivateResponseSchema, deviceDirectorySyncSchema, } from './deviceDirectory.js';
|
|
72
72
|
export { oauthConsentDecisionSchema, oauthAuthorizeCodeResponseSchema, mcpOAuthClientApplicationSchema, mcpOAuthWriteActionSchema, mcpOAuthConsentContextSchema, mcpOAuthClientInfoResponseSchema, mcpOAuthConsentResponseSchema, } from './oauth.js';
|
|
73
73
|
export {
|
|
@@ -94,14 +94,14 @@ updateSchema, createUpdateResponseSchema, rollbackToEmbeddedEntrySchema, channel
|
|
|
94
94
|
// Rollback / promote / rollout
|
|
95
95
|
rollbackRequestSchema, rollbackToEmbeddedRequestSchema, promoteRequestSchema, updateRolloutPatchSchema, } from './updates.js';
|
|
96
96
|
export {
|
|
97
|
-
//
|
|
98
|
-
webauthnRegisterOptionsRequestSchema, webauthnLoginOptionsRequestSchema, webauthnRegisterVerifyRequestSchema, webauthnLoginVerifyRequestSchema, webauthnCredentialIdSchema, webauthnAssertionResponseSchema, } from './webauthn.js';
|
|
99
|
-
export {
|
|
100
|
-
// Recovery email of a passkey account (ADR 0029 D3)
|
|
97
|
+
// Email codes and tickets for sign-up and re-verification
|
|
101
98
|
EMAIL_VERIFICATION_PURPOSES, EMAIL_CODE_LENGTH, EMAIL_CODE_TTL_MS, EMAIL_CODE_MAX_ATTEMPTS, EMAIL_TICKET_TTL_MS, EMAIL_VERIFICATION_ERROR_CODES, emailAddressSchema, emailTicketSchema, emailVerificationStartRequestSchema, emailVerificationStartResponseSchema, emailVerificationConfirmRequestSchema, emailVerificationConfirmResponseSchema, } from './accountEmail.js';
|
|
102
99
|
export {
|
|
103
|
-
//
|
|
104
|
-
|
|
100
|
+
// Email code/link, password and authenticator sign-in
|
|
101
|
+
EMAIL_SIGNIN_LINK_TTL_MS, SIGNIN_SECOND_FACTOR_TTL_MS, SIGNIN_SECOND_FACTOR_MAX_ATTEMPTS, PASSWORD_MIN_LENGTH, PASSWORD_MAX_LENGTH, TOTP_DIGITS, TOTP_PERIOD_SECONDS, TOTP_BACKUP_CODE_COUNT, SIGN_IN_ERROR_CODES, signInIdentifierSchema, passwordInputSchema, newPasswordSchema, secondFactorCodeSchema, emailSignInStartRequestSchema, emailSignInStartResponseSchema, emailSignInConfirmRequestSchema, emailSignInCodeSchema, normalizeEmailSignInCode, EMAIL_SIGNIN_LONG_CODE_ALPHABET, EMAIL_SIGNIN_LONG_CODE_LENGTH, emailSignInCollectRequestSchema, emailSignInLinkRequestSchema, emailSignInLinkResponseSchema, emailSignInPendingSchema, passwordSignInRequestSchema, secondFactorSignInRequestSchema, secondFactorRequiredSchema, signUpRequestSchema, isSecondFactorRequired, reauthProofSchema, emailReauthProofSchema, REAUTH_ACTIONS, reauthEmailStartRequestSchema, passwordSetRequestSchema, signInMethodsSchema, totpEnrollResponseSchema, totpConfirmRequestSchema, totpReauthRequestSchema, totpBackupCodesResponseSchema, } from './signIn.js';
|
|
102
|
+
export {
|
|
103
|
+
// Linking Commons to an account without a key (ADR 0029 D3)
|
|
104
|
+
IDENTITY_LINK_STATUSES, IDENTITY_LINK_QR_PREFIX, identityLinkIdSchema, buildIdentityLinkQrPayload, parseIdentityLinkQrPayload, identityLinkCreateResponseSchema, identityLinkStateSchema, identityLinkProofRequestSchema, identityLinkCompleteRequestSchema, } from './identityLink.js';
|
|
105
105
|
export {
|
|
106
106
|
// Schemas — transparency log (checkpoints + inclusion proofs)
|
|
107
107
|
transparencyCheckpointSignatureSchema, transparencyAnchorSchema, transparencyCheckpointSchema, transparencyInclusionProofSchema, transparencyCheckpointListSchema, } from './transparency.js';
|
package/dist/esm/reputation.js
CHANGED
|
@@ -3,9 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* SINGLE SOURCE OF TRUTH for the reputation ledger's wire shapes: the closed
|
|
5
5
|
* value sets (`REPUTATION_CATEGORIES`, `TRUST_TIERS`, …), the response entities
|
|
6
|
-
* (`ReputationTransaction`, the two balance views, `
|
|
7
|
-
*
|
|
8
|
-
* endpoints accept. The API validates its OUTPUT against these schemas and its
|
|
6
|
+
* (`ReputationTransaction`, the two balance views, `ReputationRule`, the
|
|
7
|
+
* leaderboard entry) and the award body. The API validates its OUTPUT against these schemas and its
|
|
9
8
|
* INPUT with the same request schemas the SDK's input types are derived from;
|
|
10
9
|
* `@oxy.so/core`'s reputation mixin imports every type from here rather than
|
|
11
10
|
* declaring its own.
|
|
@@ -71,15 +70,13 @@ export const reputationCategorySchema = z.enum(REPUTATION_CATEGORIES);
|
|
|
71
70
|
* Transaction lifecycle status.
|
|
72
71
|
*
|
|
73
72
|
* - `active` — counts toward the balance.
|
|
74
|
-
* - `
|
|
75
|
-
* -
|
|
76
|
-
*
|
|
73
|
+
* - `reversed` — superseded by a compensating reversal transaction (written
|
|
74
|
+
* only by policy-driven code, never by a person); the pair nets
|
|
75
|
+
* to zero.
|
|
77
76
|
*/
|
|
78
77
|
export const REPUTATION_TRANSACTION_STATUSES = [
|
|
79
78
|
'active',
|
|
80
|
-
'disputed',
|
|
81
79
|
'reversed',
|
|
82
|
-
'voided',
|
|
83
80
|
];
|
|
84
81
|
export const reputationTransactionStatusSchema = z.enum(REPUTATION_TRANSACTION_STATUSES);
|
|
85
82
|
/**
|
|
@@ -104,15 +101,6 @@ export const REPUTATION_TARGET_ENTITY_TYPES = [
|
|
|
104
101
|
'other',
|
|
105
102
|
];
|
|
106
103
|
export const reputationTargetEntityTypeSchema = z.enum(REPUTATION_TARGET_ENTITY_TYPES);
|
|
107
|
-
/** Dispute lifecycle status. */
|
|
108
|
-
export const REPUTATION_DISPUTE_STATUSES = [
|
|
109
|
-
'open',
|
|
110
|
-
'accepted',
|
|
111
|
-
'rejected',
|
|
112
|
-
'needs_review',
|
|
113
|
-
];
|
|
114
|
-
export const reputationDisputeStatusSchema = z.enum(REPUTATION_DISPUTE_STATUSES);
|
|
115
|
-
/** Influence context selecting which capped weight axis to read. */
|
|
116
104
|
export const REPUTATION_INFLUENCE_CONTEXTS = [
|
|
117
105
|
'default',
|
|
118
106
|
'report',
|
|
@@ -217,26 +205,16 @@ const FULL_BALANCE_FIELDS = [
|
|
|
217
205
|
export function isFullReputationBalance(balance) {
|
|
218
206
|
return FULL_BALANCE_FIELDS.every((field) => field in balance);
|
|
219
207
|
}
|
|
220
|
-
export const reputationDisputeSchema = z.object({
|
|
221
|
-
id: z.string(),
|
|
222
|
-
transactionId: z.string(),
|
|
223
|
-
userId: z.string(),
|
|
224
|
-
reason: z.string(),
|
|
225
|
-
status: reputationDisputeStatusSchema,
|
|
226
|
-
evidence: z.array(z.string()).optional(),
|
|
227
|
-
resolvedAt: z.string().optional(),
|
|
228
|
-
resolvedByUserId: z.string().optional(),
|
|
229
|
-
createdAt: z.string(),
|
|
230
|
-
updatedAt: z.string(),
|
|
231
|
-
});
|
|
232
208
|
export const reputationRuleSchema = z.object({
|
|
233
|
-
id: z.string(),
|
|
234
209
|
actionType: z.string(),
|
|
235
210
|
points: z.number(),
|
|
236
211
|
category: reputationCategorySchema,
|
|
237
212
|
description: z.string(),
|
|
238
213
|
cooldownInMinutes: z.number(),
|
|
239
|
-
|
|
214
|
+
});
|
|
215
|
+
export const reputationRulesResponseSchema = z.object({
|
|
216
|
+
version: z.number().int(),
|
|
217
|
+
rules: z.array(reputationRuleSchema),
|
|
240
218
|
});
|
|
241
219
|
export const reputationLeaderboardUserSchema = z.object({
|
|
242
220
|
id: z.string(),
|
|
@@ -256,10 +234,6 @@ export const reputationInfluenceResultSchema = z.object({
|
|
|
256
234
|
weight: z.number(),
|
|
257
235
|
influence: reputationInfluenceSchema,
|
|
258
236
|
});
|
|
259
|
-
export const reverseReputationTransactionResultSchema = z.object({
|
|
260
|
-
original: reputationTransactionSchema,
|
|
261
|
-
reversal: reputationTransactionSchema,
|
|
262
|
-
});
|
|
263
237
|
export const awardReputationSchema = z.object({
|
|
264
238
|
userId: z.string().trim().min(1),
|
|
265
239
|
actionType: z.string().trim().min(1),
|
|
@@ -272,22 +246,3 @@ export const awardReputationSchema = z.object({
|
|
|
272
246
|
reason: z.string().trim().max(500).optional(),
|
|
273
247
|
metadata: z.record(z.unknown()).optional(),
|
|
274
248
|
});
|
|
275
|
-
export const createReputationDisputeSchema = z.object({
|
|
276
|
-
transactionId: z.string().trim().min(1),
|
|
277
|
-
reason: z.string().trim().min(1).max(1000),
|
|
278
|
-
evidence: z.array(z.string().trim().min(1)).max(20).optional(),
|
|
279
|
-
});
|
|
280
|
-
export const resolveReputationDisputeSchema = z.object({
|
|
281
|
-
status: z.enum(['accepted', 'rejected']),
|
|
282
|
-
});
|
|
283
|
-
export const upsertReputationRuleSchema = z.object({
|
|
284
|
-
actionType: z.string().trim().min(1),
|
|
285
|
-
points: z.number(),
|
|
286
|
-
category: reputationCategorySchema,
|
|
287
|
-
description: z.string().trim().min(1).max(500),
|
|
288
|
-
cooldownInMinutes: z.number().int().min(0).default(0),
|
|
289
|
-
isEnabled: z.boolean().default(true),
|
|
290
|
-
});
|
|
291
|
-
export const reverseReputationTransactionSchema = z.object({
|
|
292
|
-
reason: z.string().trim().max(500).optional(),
|
|
293
|
-
});
|