@oxyhq/contracts 0.12.0 → 0.13.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/deviceBoot.js +19 -156
- package/dist/cjs/index.js +1 -11
- package/dist/cjs/userResponse.js +1 -2
- package/dist/esm/.tsbuildinfo +1 -1
- package/dist/esm/deviceBoot.js +18 -155
- package/dist/esm/index.js +1 -1
- package/dist/esm/userResponse.js +1 -2
- package/dist/types/.tsbuildinfo +1 -1
- package/dist/types/deviceBoot.d.ts +33 -220
- package/dist/types/deviceSession.d.ts +14 -14
- package/dist/types/index.d.ts +2 -2
- package/dist/types/userResponse.d.ts +7 -8
- package/package.json +1 -1
package/dist/cjs/deviceBoot.js
CHANGED
|
@@ -1,28 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* First-party login result contract.
|
|
4
4
|
*
|
|
5
|
-
* SINGLE SOURCE OF TRUTH for the
|
|
6
|
-
*
|
|
7
|
-
* `
|
|
8
|
-
*
|
|
9
|
-
* device-token issuance, the IdP chooser's device-resolve, and the first-party
|
|
10
|
-
* password login result (2FA arm vs. session arm). The API validates its OUTPUT
|
|
11
|
-
* against these schemas; every consumer (`@oxyhq/core`'s device-boot mixin, the
|
|
12
|
-
* SDK cold boot, the IdP chooser) validates its INPUT against the same
|
|
13
|
-
* definitions, so producer and consumers cannot drift.
|
|
5
|
+
* SINGLE SOURCE OF TRUTH for the first-party password login result (2FA arm vs.
|
|
6
|
+
* session arm). The API validates its OUTPUT against this schema; every consumer
|
|
7
|
+
* (`@oxyhq/core`'s auth mixin) validates its INPUT against the same definition,
|
|
8
|
+
* so producer and consumers cannot drift.
|
|
14
9
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* `POST /auth/device/exchange` (origin-bound GETDEL burn).
|
|
20
|
-
* - Refresh is ONE rotating, single-use family shared by web and native.
|
|
21
|
-
* - `loginResult` mirrors what `POST /auth/login` returns today
|
|
22
|
-
* (`buildSessionAuthResponse` in the API's `session.controller.ts`): either a
|
|
23
|
-
* 2FA challenge (`{ twoFactorRequired: true, loginToken }`) or a session
|
|
24
|
-
* payload. The session arm matches `SessionAuthResponse` EXACTLY, plus an
|
|
25
|
-
* optional `refreshToken` the new server adds for the persisted-refresh lane.
|
|
10
|
+
* The device transport is `deviceId` + `deviceSecret` + `POST /session/device/token`
|
|
11
|
+
* (see `deviceSession.ts`). The legacy cookie/bootstrap/refresh-family lanes were
|
|
12
|
+
* removed in the zero-cookie cutover — nothing here carries a refresh token or a
|
|
13
|
+
* boot fragment.
|
|
26
14
|
*
|
|
27
15
|
* Nested-object response shapes are declared as explicit `interface`s with the
|
|
28
16
|
* runtime schema annotated `z.ZodType<Interface>` — the same rationale as
|
|
@@ -35,131 +23,27 @@
|
|
|
35
23
|
* `require()`).
|
|
36
24
|
*/
|
|
37
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
|
-
exports.
|
|
26
|
+
exports.loginResultSchema = void 0;
|
|
39
27
|
const zod_1 = require("zod");
|
|
40
|
-
const userResponse_1 = require("./userResponse");
|
|
41
|
-
/* -------------------------------------------------------------------------- */
|
|
42
|
-
/* Bootstrap fragment */
|
|
43
|
-
/* -------------------------------------------------------------------------- */
|
|
44
|
-
/**
|
|
45
|
-
* Why the bootstrap hop resolved the way it did.
|
|
46
|
-
* - `session` — the device cookie resolved an active session; a `code` is
|
|
47
|
-
* present to exchange for tokens.
|
|
48
|
-
* - `no_session` — the device is known but has no active session; no `code`.
|
|
49
|
-
* - `new_device` — first contact; the cookie was just planted, no session yet.
|
|
50
|
-
*/
|
|
51
|
-
exports.deviceBootReasonSchema = zod_1.z.enum(['session', 'no_session', 'new_device']);
|
|
52
|
-
/**
|
|
53
|
-
* The `#oxy_boot=<json>` fragment `GET /auth/device/bootstrap` appends to the
|
|
54
|
-
* `return_to` URL. Carries the CSRF `state` echo, the resolution `reason`, the
|
|
55
|
-
* opaque `deviceToken`, and — ONLY on the `session` arm — the single-use
|
|
56
|
-
* exchange `code`. NEVER carries tokens or a deviceId.
|
|
57
|
-
*
|
|
58
|
-
* Discriminated on `reason` so the code↔reason coupling is enforced by the
|
|
59
|
-
* schema, not by the consumer: the `session` arm REQUIRES `code`, and the
|
|
60
|
-
* `no_session` / `new_device` arms omit it (a stray `code` on those arms is
|
|
61
|
-
* stripped). A `session` fragment WITHOUT a code therefore fails to parse and
|
|
62
|
-
* is treated as "no usable fragment" rather than half-processed.
|
|
63
|
-
*/
|
|
64
|
-
const deviceBootFragmentBase = {
|
|
65
|
-
v: zod_1.z.literal(1),
|
|
66
|
-
state: zod_1.z.string().min(1).max(256),
|
|
67
|
-
deviceToken: zod_1.z.string().min(20).max(512),
|
|
68
|
-
};
|
|
69
|
-
exports.deviceBootFragmentSchema = zod_1.z.discriminatedUnion('reason', [
|
|
70
|
-
zod_1.z.object({
|
|
71
|
-
...deviceBootFragmentBase,
|
|
72
|
-
reason: zod_1.z.literal('session'),
|
|
73
|
-
code: zod_1.z.string().min(20).max(128),
|
|
74
|
-
}),
|
|
75
|
-
zod_1.z.object({
|
|
76
|
-
...deviceBootFragmentBase,
|
|
77
|
-
reason: zod_1.z.literal('no_session'),
|
|
78
|
-
}),
|
|
79
|
-
zod_1.z.object({
|
|
80
|
-
...deviceBootFragmentBase,
|
|
81
|
-
reason: zod_1.z.literal('new_device'),
|
|
82
|
-
}),
|
|
83
|
-
]);
|
|
84
|
-
/* -------------------------------------------------------------------------- */
|
|
85
|
-
/* Boot-code exchange */
|
|
86
|
-
/* -------------------------------------------------------------------------- */
|
|
87
|
-
/** Request body for `POST /auth/device/exchange` — the single-use boot code. */
|
|
88
|
-
exports.deviceExchangeRequestSchema = zod_1.z.object({
|
|
89
|
-
code: zod_1.z.string().min(20).max(128),
|
|
90
|
-
});
|
|
91
|
-
exports.authTokenBundleSchema = zod_1.z.object({
|
|
92
|
-
sessionId: zod_1.z.string(),
|
|
93
|
-
accessToken: zod_1.z.string(),
|
|
94
|
-
refreshToken: zod_1.z.string(),
|
|
95
|
-
expiresAt: zod_1.z.string(),
|
|
96
|
-
user: userResponse_1.userResponseSchema,
|
|
97
|
-
deviceSecret: zod_1.z.string().optional(),
|
|
98
|
-
});
|
|
99
|
-
// Internal (unexported) arm schemas — PLAIN `z.object` literals (no
|
|
100
|
-
// `z.ZodType<>` annotation) so `z.discriminatedUnion` can introspect the
|
|
101
|
-
// `reason` discriminator. The node10 `.d.ts`-degradation safety comes from the
|
|
102
|
-
// EXPORTED symbols instead: the public types are explicit interfaces
|
|
103
|
-
// (`WebSessionSession` / `WebSessionNoSession` / `WebSessionResult`) and the
|
|
104
|
-
// exported schema is annotated `z.ZodType<WebSessionResult>` below, so the
|
|
105
|
-
// emitted declaration states the shape literally rather than a degradable
|
|
106
|
-
// `z.infer<>` of the nested `session` object.
|
|
107
|
-
const webSessionSessionSchema = zod_1.z.object({
|
|
108
|
-
reason: zod_1.z.literal('session'),
|
|
109
|
-
session: exports.authTokenBundleSchema,
|
|
110
|
-
deviceToken: zod_1.z.string().min(1),
|
|
111
|
-
});
|
|
112
|
-
const webSessionNoSessionSchema = zod_1.z.object({
|
|
113
|
-
reason: zod_1.z.enum(['no_session', 'new_device']),
|
|
114
|
-
deviceToken: zod_1.z.string().min(1),
|
|
115
|
-
});
|
|
116
|
-
// Discriminated on `reason` — a true `discriminatedUnion` (not `z.union`): it
|
|
117
|
-
// dispatches on the discriminator instead of sequentially probing each arm,
|
|
118
|
-
// giving precise per-arm errors.
|
|
119
|
-
exports.webSessionResultSchema = zod_1.z.discriminatedUnion('reason', [
|
|
120
|
-
webSessionSessionSchema,
|
|
121
|
-
webSessionNoSessionSchema,
|
|
122
|
-
]);
|
|
123
|
-
/* -------------------------------------------------------------------------- */
|
|
124
|
-
/* Refresh-token rotation (web + native, one implementation) */
|
|
125
|
-
/* -------------------------------------------------------------------------- */
|
|
126
|
-
/** Request body for `POST /auth/refresh-token` — the current refresh token. */
|
|
127
|
-
exports.tokenRefreshRequestSchema = zod_1.z.object({
|
|
128
|
-
refreshToken: zod_1.z.string().min(20),
|
|
129
|
-
});
|
|
130
|
-
/**
|
|
131
|
-
* Wire shape of `POST /auth/refresh-token`: the rotated (single-use) family —
|
|
132
|
-
* a new access token, the next refresh token, the new access-token expiry, and
|
|
133
|
-
* the owning session id. `expiresAt` is an ISO string.
|
|
134
|
-
*/
|
|
135
|
-
exports.tokenRefreshResponseSchema = zod_1.z.object({
|
|
136
|
-
accessToken: zod_1.z.string(),
|
|
137
|
-
refreshToken: zod_1.z.string(),
|
|
138
|
-
expiresAt: zod_1.z.string(),
|
|
139
|
-
sessionId: zod_1.z.string(),
|
|
140
|
-
});
|
|
141
|
-
/* -------------------------------------------------------------------------- */
|
|
142
|
-
/* Native device-token issuance */
|
|
143
|
-
/* -------------------------------------------------------------------------- */
|
|
144
|
-
/**
|
|
145
|
-
* Wire shape of `POST /auth/device/token` — issues (or rotates) the opaque
|
|
146
|
-
* device token for the native channel. The deviceId is taken from the bearer
|
|
147
|
-
* JWT claims server-side; only the token comes back.
|
|
148
|
-
*/
|
|
149
|
-
exports.deviceTokenIssueResponseSchema = zod_1.z.object({
|
|
150
|
-
deviceToken: zod_1.z.string(),
|
|
151
|
-
});
|
|
152
28
|
const loginTwoFactorRequiredSchema = zod_1.z.object({
|
|
153
29
|
twoFactorRequired: zod_1.z.literal(true),
|
|
154
30
|
loginToken: zod_1.z.string(),
|
|
155
31
|
});
|
|
32
|
+
const securityAlertSchema = zod_1.z.object({
|
|
33
|
+
message: zod_1.z.string(),
|
|
34
|
+
anomalies: zod_1.z.array(zod_1.z.object({
|
|
35
|
+
type: zod_1.z.string(),
|
|
36
|
+
reason: zod_1.z.string(),
|
|
37
|
+
details: zod_1.z.string().optional(),
|
|
38
|
+
})),
|
|
39
|
+
});
|
|
156
40
|
const loginSessionResultSchema = zod_1.z.object({
|
|
157
41
|
sessionId: zod_1.z.string(),
|
|
158
42
|
deviceId: zod_1.z.string(),
|
|
159
43
|
expiresAt: zod_1.z.string(),
|
|
160
44
|
accessToken: zod_1.z.string().optional(),
|
|
161
|
-
refreshToken: zod_1.z.string().optional(),
|
|
162
45
|
deviceSecret: zod_1.z.string().optional(),
|
|
46
|
+
securityAlert: securityAlertSchema.optional(),
|
|
163
47
|
user: zod_1.z.object({
|
|
164
48
|
id: zod_1.z.string(),
|
|
165
49
|
username: zod_1.z.string().optional(),
|
|
@@ -170,24 +54,3 @@ exports.loginResultSchema = zod_1.z.union([
|
|
|
170
54
|
loginTwoFactorRequiredSchema,
|
|
171
55
|
loginSessionResultSchema,
|
|
172
56
|
]);
|
|
173
|
-
/* -------------------------------------------------------------------------- */
|
|
174
|
-
/* IdP chooser device-resolve */
|
|
175
|
-
/* -------------------------------------------------------------------------- */
|
|
176
|
-
/**
|
|
177
|
-
* Request body for `POST /auth/device/resolve` (X-Oxy-Internal, called by the
|
|
178
|
-
* IdP chooser) — the device key the chooser read from the first-party
|
|
179
|
-
* `oxy_device` cookie.
|
|
180
|
-
*/
|
|
181
|
-
exports.deviceResolveRequestSchema = zod_1.z.object({
|
|
182
|
-
deviceKey: zod_1.z.string().min(20),
|
|
183
|
-
});
|
|
184
|
-
const deviceResolveAccountSchema = zod_1.z.object({
|
|
185
|
-
user: userResponse_1.userResponseSchema,
|
|
186
|
-
sessionId: zod_1.z.string(),
|
|
187
|
-
accessToken: zod_1.z.string(),
|
|
188
|
-
expiresAt: zod_1.z.string(),
|
|
189
|
-
});
|
|
190
|
-
exports.deviceResolveResponseSchema = zod_1.z.object({
|
|
191
|
-
activeAccountId: zod_1.z.string().nullable(),
|
|
192
|
-
accounts: zod_1.z.array(deviceResolveAccountSchema),
|
|
193
|
-
});
|
package/dist/cjs/index.js
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
*/
|
|
13
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
14
|
exports.personhoodBreakdownSchema = exports.personhoodVouchRecordSchema = exports.validationVoteResultSchema = exports.validationRequestSummarySchema = exports.validationOpenResultSchema = exports.validationOpenRequestSchema = exports.validationVerdictRecordSchema = exports.realLifeAttestationResultSchema = exports.realLifeAttestationRecordSchema = exports.signedPublicCardSchema = exports.publicCardSchema = exports.logPageResponseSchema = exports.chainHeadResponseSchema = exports.oxySignedRecordTypeSchema = exports.exportBundleSchema = exports.exportAttestationSchema = exports.authMethodsResponseSchema = exports.authMethodEntrySchema = exports.domainVerificationInstructionsSchema = exports.domainVerificationRequestSchema = exports.verifiedDomainSchema = exports.signedRecordEnvelopeSchema = exports.didDocumentSchema = exports.didServiceSchema = exports.verificationMethodSchema = exports.appAffinityEventsIngestSchema = exports.appAffinityEventSchema = exports.appAffinityEventTypeSchema = exports.appUserSignalIngestSchema = exports.appInterestInputSchema = exports.appEndorsementInputSchema = exports.recommendationResponseSchema = exports.recommendationItemSchema = exports.recommendationCountSchema = exports.recommendationRequestSchema = exports.recommendationSignalWeightsSchema = exports.recommendationBoostSchema = exports.recommendationExcludeTypeSchema = exports.fedcmTokenPayloadSchema = exports.sessionStatusSchema = exports.publicApplicationSchema = exports.applicationTypeSchema = exports.safeParseContract = exports.resolveUserId = exports.deviceLinkedSessionsResponseSchema = exports.deviceLinkedSessionSchema = exports.currentUserResponseSchema = exports.userProfileUpdateSchema = exports.userResponseSchema = exports.userNameSchema = void 0;
|
|
15
|
-
exports.
|
|
15
|
+
exports.loginResultSchema = exports.deviceTokenMintResponseSchema = exports.deviceTokenMintRequestSchema = exports.deviceSessionSyncSchema = exports.activeTokenSchema = exports.deviceSessionStateSchema = exports.sessionAccountSchema = exports.linkPreviewResponseSchema = exports.linkPreviewBatchResponseSchema = exports.linkPreviewBatchRequestSchema = exports.linkPreviewSchema = exports.credentialVerifyResultSchema = exports.credentialListResultSchema = exports.credentialIssueResultSchema = exports.verifiableCredentialResponseSchema = exports.credentialRecordSchema = exports.vouchResultSchema = exports.personhoodStatusResultSchema = void 0;
|
|
16
16
|
var userResponse_1 = require("./userResponse");
|
|
17
17
|
// Schemas
|
|
18
18
|
Object.defineProperty(exports, "userNameSchema", { enumerable: true, get: function () { return userResponse_1.userNameSchema; } });
|
|
@@ -103,14 +103,4 @@ Object.defineProperty(exports, "deviceTokenMintRequestSchema", { enumerable: tru
|
|
|
103
103
|
Object.defineProperty(exports, "deviceTokenMintResponseSchema", { enumerable: true, get: function () { return deviceSession_1.deviceTokenMintResponseSchema; } });
|
|
104
104
|
var deviceBoot_1 = require("./deviceBoot");
|
|
105
105
|
// Schemas
|
|
106
|
-
Object.defineProperty(exports, "deviceBootReasonSchema", { enumerable: true, get: function () { return deviceBoot_1.deviceBootReasonSchema; } });
|
|
107
|
-
Object.defineProperty(exports, "deviceBootFragmentSchema", { enumerable: true, get: function () { return deviceBoot_1.deviceBootFragmentSchema; } });
|
|
108
|
-
Object.defineProperty(exports, "deviceExchangeRequestSchema", { enumerable: true, get: function () { return deviceBoot_1.deviceExchangeRequestSchema; } });
|
|
109
|
-
Object.defineProperty(exports, "authTokenBundleSchema", { enumerable: true, get: function () { return deviceBoot_1.authTokenBundleSchema; } });
|
|
110
|
-
Object.defineProperty(exports, "webSessionResultSchema", { enumerable: true, get: function () { return deviceBoot_1.webSessionResultSchema; } });
|
|
111
|
-
Object.defineProperty(exports, "tokenRefreshRequestSchema", { enumerable: true, get: function () { return deviceBoot_1.tokenRefreshRequestSchema; } });
|
|
112
|
-
Object.defineProperty(exports, "tokenRefreshResponseSchema", { enumerable: true, get: function () { return deviceBoot_1.tokenRefreshResponseSchema; } });
|
|
113
|
-
Object.defineProperty(exports, "deviceTokenIssueResponseSchema", { enumerable: true, get: function () { return deviceBoot_1.deviceTokenIssueResponseSchema; } });
|
|
114
106
|
Object.defineProperty(exports, "loginResultSchema", { enumerable: true, get: function () { return deviceBoot_1.loginResultSchema; } });
|
|
115
|
-
Object.defineProperty(exports, "deviceResolveRequestSchema", { enumerable: true, get: function () { return deviceBoot_1.deviceResolveRequestSchema; } });
|
|
116
|
-
Object.defineProperty(exports, "deviceResolveResponseSchema", { enumerable: true, get: function () { return deviceBoot_1.deviceResolveResponseSchema; } });
|
package/dist/cjs/userResponse.js
CHANGED
|
@@ -17,8 +17,7 @@
|
|
|
17
17
|
*
|
|
18
18
|
* Faithful to the producers:
|
|
19
19
|
* - `packages/api/src/utils/userTransform.ts` `formatUserResponse` — the
|
|
20
|
-
* canonical serialization used by
|
|
21
|
-
* endpoints (`deviceAuth.ts`), login/signup, device sessions, etc.
|
|
20
|
+
* canonical serialization used by login/signup, device sessions, etc.
|
|
22
21
|
* Emits `id` (NOT `_id`), forwards `username` verbatim (may be absent), and
|
|
23
22
|
* emits `name` as the structured `{ first, last, full, displayName }`
|
|
24
23
|
* subdocument.
|