@oxyhq/contracts 0.11.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.
@@ -1,27 +1,15 @@
1
1
  /**
2
- * Device-first bootstrap & token contracts (auth centralization, wave 1).
2
+ * First-party login result contract.
3
3
  *
4
- * SINGLE SOURCE OF TRUTH for the wire shape of the new device-first session
5
- * bootstrap: the top-level `#oxy_boot=…` fragment the API hands back from
6
- * `GET /auth/device/bootstrap`, the token bundle a boot code / web-session
7
- * fast-path exchanges into, the persisted-refresh rotation, the native
8
- * device-token issuance, the IdP chooser's device-resolve, and the first-party
9
- * password login result (2FA arm vs. session arm). The API validates its OUTPUT
10
- * against these schemas; every consumer (`@oxyhq/core`'s device-boot mixin, the
11
- * SDK cold boot, the IdP chooser) validates its INPUT against the same
12
- * definitions, so producer and consumers cannot drift.
4
+ * SINGLE SOURCE OF TRUTH for the first-party password login result (2FA arm vs.
5
+ * session arm). The API validates its OUTPUT against this schema; every consumer
6
+ * (`@oxyhq/core`'s auth mixin) validates its INPUT against the same definition,
7
+ * so producer and consumers cannot drift.
13
8
  *
14
- * Design anchors (from the auth-centralization plan):
15
- * - The bootstrap fragment carries NO tokens and NO deviceId — only a
16
- * `state` echo (CSRF), a `reason`, a short-lived single-use `code`, and an
17
- * opaque `deviceToken`. Tokens are obtained by exchanging the `code` at
18
- * `POST /auth/device/exchange` (origin-bound GETDEL burn).
19
- * - Refresh is ONE rotating, single-use family shared by web and native.
20
- * - `loginResult` mirrors what `POST /auth/login` returns today
21
- * (`buildSessionAuthResponse` in the API's `session.controller.ts`): either a
22
- * 2FA challenge (`{ twoFactorRequired: true, loginToken }`) or a session
23
- * payload. The session arm matches `SessionAuthResponse` EXACTLY, plus an
24
- * optional `refreshToken` the new server adds for the persisted-refresh lane.
9
+ * The device transport is `deviceId` + `deviceSecret` + `POST /session/device/token`
10
+ * (see `deviceSession.ts`). The legacy cookie/bootstrap/refresh-family lanes were
11
+ * removed in the zero-cookie cutover — nothing here carries a refresh token or a
12
+ * boot fragment.
25
13
  *
26
14
  * Nested-object response shapes are declared as explicit `interface`s with the
27
15
  * runtime schema annotated `z.ZodType<Interface>` — the same rationale as
@@ -34,164 +22,22 @@
34
22
  * `require()`).
35
23
  */
36
24
  import { z } from 'zod';
37
- import { type UserResponse } from './userResponse';
38
- /**
39
- * Why the bootstrap hop resolved the way it did.
40
- * - `session` — the device cookie resolved an active session; a `code` is
41
- * present to exchange for tokens.
42
- * - `no_session` — the device is known but has no active session; no `code`.
43
- * - `new_device` — first contact; the cookie was just planted, no session yet.
44
- */
45
- export declare const deviceBootReasonSchema: z.ZodEnum<["session", "no_session", "new_device"]>;
46
- export type DeviceBootReason = z.infer<typeof deviceBootReasonSchema>;
47
- export declare const deviceBootFragmentSchema: z.ZodDiscriminatedUnion<"reason", [z.ZodObject<{
48
- reason: z.ZodLiteral<"session">;
49
- code: z.ZodString;
50
- v: z.ZodLiteral<1>;
51
- state: z.ZodString;
52
- deviceToken: z.ZodString;
53
- }, "strip", z.ZodTypeAny, {
54
- code: string;
55
- reason: "session";
56
- v: 1;
57
- state: string;
58
- deviceToken: string;
59
- }, {
60
- code: string;
61
- reason: "session";
62
- v: 1;
63
- state: string;
64
- deviceToken: string;
65
- }>, z.ZodObject<{
66
- reason: z.ZodLiteral<"no_session">;
67
- v: z.ZodLiteral<1>;
68
- state: z.ZodString;
69
- deviceToken: z.ZodString;
70
- }, "strip", z.ZodTypeAny, {
71
- reason: "no_session";
72
- v: 1;
73
- state: string;
74
- deviceToken: string;
75
- }, {
76
- reason: "no_session";
77
- v: 1;
78
- state: string;
79
- deviceToken: string;
80
- }>, z.ZodObject<{
81
- reason: z.ZodLiteral<"new_device">;
82
- v: z.ZodLiteral<1>;
83
- state: z.ZodString;
84
- deviceToken: z.ZodString;
85
- }, "strip", z.ZodTypeAny, {
86
- reason: "new_device";
87
- v: 1;
88
- state: string;
89
- deviceToken: string;
90
- }, {
91
- reason: "new_device";
92
- v: 1;
93
- state: string;
94
- deviceToken: string;
95
- }>]>;
96
- export type DeviceBootFragment = z.infer<typeof deviceBootFragmentSchema>;
97
- /** Request body for `POST /auth/device/exchange` — the single-use boot code. */
98
- export declare const deviceExchangeRequestSchema: z.ZodObject<{
99
- code: z.ZodString;
100
- }, "strip", z.ZodTypeAny, {
101
- code: string;
102
- }, {
103
- code: string;
104
- }>;
105
- export type DeviceExchangeRequest = z.infer<typeof deviceExchangeRequestSchema>;
106
- /**
107
- * The token bundle returned by `POST /auth/device/exchange` and
108
- * `POST /auth/device/web-session` — the freshly-minted access token, its
109
- * rotating refresh-family head, the owning `sessionId`, and the full canonical
110
- * user object. `expiresAt` is an ISO string.
111
- */
112
- export interface AuthTokenBundle {
113
- sessionId: string;
114
- accessToken: string;
115
- refreshToken: string;
116
- expiresAt: string;
117
- user: UserResponse;
118
- }
119
- export declare const authTokenBundleSchema: z.ZodType<AuthTokenBundle>;
120
- /**
121
- * The `*.oxy.so` same-site fast path returns a `reason`-discriminated result:
122
- * a full session (the device cookie resolved an active session) OR a
123
- * signed-out arm (the device is known / was just planted). BOTH arms carry the
124
- * rotated opaque `deviceToken` to persist — the deviceToken is device-level
125
- * attribution, not session-level, so it is refreshed even when signed out.
126
- *
127
- * IMPORTANT: the success arm nests the token bundle under `session` — it is
128
- * NOT a bare {@link AuthTokenBundle}. That distinction is load-bearing for the
129
- * consumer (`@oxyhq/core`'s cold boot uses `result.session` and persists the
130
- * `deviceToken` from the SAME envelope).
131
- */
132
- /**
133
- * Success arm: an active session resolved from the same-site device cookie.
134
- */
135
- export interface WebSessionSession {
136
- reason: 'session';
137
- session: AuthTokenBundle;
138
- deviceToken: string;
25
+ /** One anomalous signal the server flagged on a sign-in (new device, location, …). */
26
+ export interface SecurityAlertAnomaly {
27
+ type: string;
28
+ reason: string;
29
+ details?: string;
139
30
  }
140
31
  /**
141
- * Signed-out arm: the device is known (or freshly planted) but has no active
142
- * session. Carries only the rotated `deviceToken`.
32
+ * The "New sign-in detected" payload the API attaches to a successful
33
+ * `POST /auth/login` when anomaly detection fires (`session.controller.ts`).
34
+ * The IdP renders `message` and gates the flow on user acknowledgement before
35
+ * continuing to the OAuth authorize step.
143
36
  */
144
- export interface WebSessionNoSession {
145
- reason: 'no_session' | 'new_device';
146
- deviceToken: string;
37
+ export interface SecurityAlert {
38
+ message: string;
39
+ anomalies: SecurityAlertAnomaly[];
147
40
  }
148
- /** The `reason`-discriminated outcome of `POST /auth/device/web-session`. */
149
- export type WebSessionResult = WebSessionSession | WebSessionNoSession;
150
- export declare const webSessionResultSchema: z.ZodType<WebSessionResult>;
151
- /** Request body for `POST /auth/refresh-token` — the current refresh token. */
152
- export declare const tokenRefreshRequestSchema: z.ZodObject<{
153
- refreshToken: z.ZodString;
154
- }, "strip", z.ZodTypeAny, {
155
- refreshToken: string;
156
- }, {
157
- refreshToken: string;
158
- }>;
159
- export type TokenRefreshRequest = z.infer<typeof tokenRefreshRequestSchema>;
160
- /**
161
- * Wire shape of `POST /auth/refresh-token`: the rotated (single-use) family —
162
- * a new access token, the next refresh token, the new access-token expiry, and
163
- * the owning session id. `expiresAt` is an ISO string.
164
- */
165
- export declare const tokenRefreshResponseSchema: z.ZodObject<{
166
- accessToken: z.ZodString;
167
- refreshToken: z.ZodString;
168
- expiresAt: z.ZodString;
169
- sessionId: z.ZodString;
170
- }, "strip", z.ZodTypeAny, {
171
- expiresAt: string;
172
- sessionId: string;
173
- accessToken: string;
174
- refreshToken: string;
175
- }, {
176
- expiresAt: string;
177
- sessionId: string;
178
- accessToken: string;
179
- refreshToken: string;
180
- }>;
181
- export type TokenRefreshResponse = z.infer<typeof tokenRefreshResponseSchema>;
182
- /**
183
- * Wire shape of `POST /auth/device/token` — issues (or rotates) the opaque
184
- * device token for the native channel. The deviceId is taken from the bearer
185
- * JWT claims server-side; only the token comes back.
186
- */
187
- export declare const deviceTokenIssueResponseSchema: z.ZodObject<{
188
- deviceToken: z.ZodString;
189
- }, "strip", z.ZodTypeAny, {
190
- deviceToken: string;
191
- }, {
192
- deviceToken: string;
193
- }>;
194
- export type DeviceTokenIssueResponse = z.infer<typeof deviceTokenIssueResponseSchema>;
195
41
  /**
196
42
  * `POST /auth/login` when the account has 2FA enabled: a short-lived login
197
43
  * token to be presented at the 2FA challenge, and no session yet.
@@ -202,8 +48,7 @@ export interface LoginTwoFactorRequired {
202
48
  }
203
49
  /**
204
50
  * `POST /auth/login` when authentication completed in one step. Matches the
205
- * API's `SessionAuthResponse` EXACTLY (`buildSessionAuthResponse`), plus the
206
- * optional `refreshToken` the persisted-refresh lane adds. `user` is the
51
+ * API's `SessionAuthResponse` EXACTLY (`buildSessionAuthResponse`). `user` is the
207
52
  * truncated session-user shape the login endpoint emits (NOT the full
208
53
  * `userResponseSchema`).
209
54
  */
@@ -212,7 +57,20 @@ export interface LoginSessionResult {
212
57
  deviceId: string;
213
58
  expiresAt: string;
214
59
  accessToken?: string;
215
- refreshToken?: string;
60
+ /**
61
+ * The device secret (zero-cookie transport). Emitted on every successful
62
+ * sign-in; the client persists it first-party alongside `deviceId` and later
63
+ * mints access tokens via `POST /session/device/token`. Optional only because
64
+ * a best-effort mint can fail — it is the sole restore credential.
65
+ */
66
+ deviceSecret?: string;
67
+ /**
68
+ * Present only when the server's anomaly detection flagged this sign-in.
69
+ * The IdP shows a "New sign-in detected" acknowledgement before proceeding.
70
+ * The session is already established regardless — this is an interstitial,
71
+ * not a gate on the credential check.
72
+ */
73
+ securityAlert?: SecurityAlert;
216
74
  user: {
217
75
  id: string;
218
76
  username?: string;
@@ -222,33 +80,3 @@ export interface LoginSessionResult {
222
80
  /** The discriminated outcome of `POST /auth/login`. */
223
81
  export type LoginResult = LoginTwoFactorRequired | LoginSessionResult;
224
82
  export declare const loginResultSchema: z.ZodType<LoginResult>;
225
- /**
226
- * Request body for `POST /auth/device/resolve` (X-Oxy-Internal, called by the
227
- * IdP chooser) — the device key the chooser read from the first-party
228
- * `oxy_device` cookie.
229
- */
230
- export declare const deviceResolveRequestSchema: z.ZodObject<{
231
- deviceKey: z.ZodString;
232
- }, "strip", z.ZodTypeAny, {
233
- deviceKey: string;
234
- }, {
235
- deviceKey: string;
236
- }>;
237
- export type DeviceResolveRequest = z.infer<typeof deviceResolveRequestSchema>;
238
- /** One account resolved for the IdP chooser from a device's session set. */
239
- export interface DeviceResolveAccount {
240
- user: UserResponse;
241
- sessionId: string;
242
- accessToken: string;
243
- expiresAt: string;
244
- }
245
- /**
246
- * Wire shape of `POST /auth/device/resolve` — the device's active account id
247
- * (or `null` when signed out of all) plus every account signed in on the
248
- * device. Replaces the IdP's legacy cookie-based chooser feed.
249
- */
250
- export interface DeviceResolveResponse {
251
- activeAccountId: string | null;
252
- accounts: DeviceResolveAccount[];
253
- }
254
- export declare const deviceResolveResponseSchema: z.ZodType<DeviceResolveResponse>;
@@ -39,24 +39,24 @@ export declare const deviceSessionStateSchema: z.ZodObject<{
39
39
  }, "strip", z.ZodTypeAny, {
40
40
  updatedAt: number;
41
41
  deviceId: string;
42
- activeAccountId: string | null;
43
42
  accounts: {
44
43
  sessionId: string;
45
44
  accountId: string;
46
45
  authuser: number;
47
46
  operatedByUserId?: string | undefined;
48
47
  }[];
48
+ activeAccountId: string | null;
49
49
  revision: number;
50
50
  }, {
51
51
  updatedAt: number;
52
52
  deviceId: string;
53
- activeAccountId: string | null;
54
53
  accounts: {
55
54
  sessionId: string;
56
55
  accountId: string;
57
56
  authuser: number;
58
57
  operatedByUserId?: string | undefined;
59
58
  }[];
59
+ activeAccountId: string | null;
60
60
  revision: number;
61
61
  }>;
62
62
  export declare const activeTokenSchema: z.ZodObject<{
@@ -94,24 +94,24 @@ export declare const deviceSessionSyncSchema: z.ZodObject<{
94
94
  }, "strip", z.ZodTypeAny, {
95
95
  updatedAt: number;
96
96
  deviceId: string;
97
- activeAccountId: string | null;
98
97
  accounts: {
99
98
  sessionId: string;
100
99
  accountId: string;
101
100
  authuser: number;
102
101
  operatedByUserId?: string | undefined;
103
102
  }[];
103
+ activeAccountId: string | null;
104
104
  revision: number;
105
105
  }, {
106
106
  updatedAt: number;
107
107
  deviceId: string;
108
- activeAccountId: string | null;
109
108
  accounts: {
110
109
  sessionId: string;
111
110
  accountId: string;
112
111
  authuser: number;
113
112
  operatedByUserId?: string | undefined;
114
113
  }[];
114
+ activeAccountId: string | null;
115
115
  revision: number;
116
116
  }>;
117
117
  activeToken: z.ZodNullable<z.ZodObject<{
@@ -128,13 +128,13 @@ export declare const deviceSessionSyncSchema: z.ZodObject<{
128
128
  state: {
129
129
  updatedAt: number;
130
130
  deviceId: string;
131
- activeAccountId: string | null;
132
131
  accounts: {
133
132
  sessionId: string;
134
133
  accountId: string;
135
134
  authuser: number;
136
135
  operatedByUserId?: string | undefined;
137
136
  }[];
137
+ activeAccountId: string | null;
138
138
  revision: number;
139
139
  };
140
140
  activeToken: {
@@ -145,13 +145,13 @@ export declare const deviceSessionSyncSchema: z.ZodObject<{
145
145
  state: {
146
146
  updatedAt: number;
147
147
  deviceId: string;
148
- activeAccountId: string | null;
149
148
  accounts: {
150
149
  sessionId: string;
151
150
  accountId: string;
152
151
  authuser: number;
153
152
  operatedByUserId?: string | undefined;
154
153
  }[];
154
+ activeAccountId: string | null;
155
155
  revision: number;
156
156
  };
157
157
  activeToken: {
@@ -163,3 +163,110 @@ export type SessionAccount = z.infer<typeof sessionAccountSchema>;
163
163
  export type DeviceSessionState = z.infer<typeof deviceSessionStateSchema>;
164
164
  export type ActiveToken = z.infer<typeof activeTokenSchema>;
165
165
  export type DeviceSessionSync = z.infer<typeof deviceSessionSyncSchema>;
166
+ /**
167
+ * Request body for `POST /session/device/token` — the client presents the
168
+ * `deviceId` it stored first-party plus the opaque `deviceSecret`. NO bearer:
169
+ * possession of the secret IS the proof of device ownership. The server matches
170
+ * `sha256(deviceSecret)` against the device's stored `secretHash` (constant-time)
171
+ * and mints a short access token for the device's active account.
172
+ */
173
+ export declare const deviceTokenMintRequestSchema: z.ZodObject<{
174
+ deviceId: z.ZodString;
175
+ deviceSecret: z.ZodString;
176
+ }, "strip", z.ZodTypeAny, {
177
+ deviceId: string;
178
+ deviceSecret: string;
179
+ }, {
180
+ deviceId: string;
181
+ deviceSecret: string;
182
+ }>;
183
+ /**
184
+ * Wire shape of a successful `POST /session/device/token`: the freshly-minted
185
+ * short access token for the active account, its expiry, the NEXT rotating
186
+ * device secret the client must persist (rotation-in-use — the presented secret
187
+ * stays valid for a short grace so multi-tab races don't lock out), and the
188
+ * projected device-session state.
189
+ */
190
+ export declare const deviceTokenMintResponseSchema: z.ZodObject<{
191
+ accessToken: z.ZodString;
192
+ expiresAt: z.ZodString;
193
+ nextDeviceSecret: z.ZodString;
194
+ state: z.ZodObject<{
195
+ deviceId: z.ZodString;
196
+ accounts: z.ZodArray<z.ZodObject<{
197
+ accountId: z.ZodString;
198
+ sessionId: z.ZodString;
199
+ authuser: z.ZodNumber;
200
+ operatedByUserId: z.ZodOptional<z.ZodString>;
201
+ }, "strip", z.ZodTypeAny, {
202
+ sessionId: string;
203
+ accountId: string;
204
+ authuser: number;
205
+ operatedByUserId?: string | undefined;
206
+ }, {
207
+ sessionId: string;
208
+ accountId: string;
209
+ authuser: number;
210
+ operatedByUserId?: string | undefined;
211
+ }>, "many">;
212
+ activeAccountId: z.ZodNullable<z.ZodString>;
213
+ revision: z.ZodNumber;
214
+ updatedAt: z.ZodNumber;
215
+ }, "strip", z.ZodTypeAny, {
216
+ updatedAt: number;
217
+ deviceId: string;
218
+ accounts: {
219
+ sessionId: string;
220
+ accountId: string;
221
+ authuser: number;
222
+ operatedByUserId?: string | undefined;
223
+ }[];
224
+ activeAccountId: string | null;
225
+ revision: number;
226
+ }, {
227
+ updatedAt: number;
228
+ deviceId: string;
229
+ accounts: {
230
+ sessionId: string;
231
+ accountId: string;
232
+ authuser: number;
233
+ operatedByUserId?: string | undefined;
234
+ }[];
235
+ activeAccountId: string | null;
236
+ revision: number;
237
+ }>;
238
+ }, "strip", z.ZodTypeAny, {
239
+ expiresAt: string;
240
+ accessToken: string;
241
+ state: {
242
+ updatedAt: number;
243
+ deviceId: string;
244
+ accounts: {
245
+ sessionId: string;
246
+ accountId: string;
247
+ authuser: number;
248
+ operatedByUserId?: string | undefined;
249
+ }[];
250
+ activeAccountId: string | null;
251
+ revision: number;
252
+ };
253
+ nextDeviceSecret: string;
254
+ }, {
255
+ expiresAt: string;
256
+ accessToken: string;
257
+ state: {
258
+ updatedAt: number;
259
+ deviceId: string;
260
+ accounts: {
261
+ sessionId: string;
262
+ accountId: string;
263
+ authuser: number;
264
+ operatedByUserId?: string | undefined;
265
+ }[];
266
+ activeAccountId: string | null;
267
+ revision: number;
268
+ };
269
+ nextDeviceSecret: string;
270
+ }>;
271
+ export type DeviceTokenMintRequest = z.infer<typeof deviceTokenMintRequestSchema>;
272
+ export type DeviceTokenMintResponse = z.infer<typeof deviceTokenMintResponseSchema>;
@@ -27,7 +27,7 @@ export { publicCardSchema, signedPublicCardSchema, realLifeAttestationRecordSche
27
27
  export type { CardTrustTier, PersonhoodStatus, PublicCard, SignedPublicCard, RealLifeAttestationRecord, RealLifeAttestationResult, ValidationVerdict, ValidationRequestStatus, ValidationVerdictRecord, ValidationOpenRequest, ValidationOpenResult, ValidationRequestSummary, ValidationVoteResult, PersonhoodVouchRecord, PersonhoodBreakdown, PersonhoodStatusResult, VouchResult, CredentialStatus, CredentialRecord, VerifiableCredentialResponse, CredentialIssueResult, CredentialListResult, CredentialVerifyResult, } from './civic';
28
28
  export { linkPreviewSchema, linkPreviewBatchRequestSchema, linkPreviewBatchResponseSchema, linkPreviewResponseSchema, } from './links';
29
29
  export type { LinkPreviewStatus, LinkPreview, LinkPreviewBatchRequest, LinkPreviewBatchResponse, } from './links';
30
- export { sessionAccountSchema, deviceSessionStateSchema, activeTokenSchema, deviceSessionSyncSchema, } from './deviceSession';
31
- export type { SessionAccount, DeviceSessionState, ActiveToken, DeviceSessionSync, } from './deviceSession';
32
- export { deviceBootReasonSchema, deviceBootFragmentSchema, deviceExchangeRequestSchema, authTokenBundleSchema, webSessionResultSchema, tokenRefreshRequestSchema, tokenRefreshResponseSchema, deviceTokenIssueResponseSchema, loginResultSchema, deviceResolveRequestSchema, deviceResolveResponseSchema, } from './deviceBoot';
33
- export type { DeviceBootReason, DeviceBootFragment, DeviceExchangeRequest, AuthTokenBundle, WebSessionResult, WebSessionSession, WebSessionNoSession, TokenRefreshRequest, TokenRefreshResponse, DeviceTokenIssueResponse, LoginTwoFactorRequired, LoginSessionResult, LoginResult, DeviceResolveRequest, DeviceResolveAccount, DeviceResolveResponse, } from './deviceBoot';
30
+ export { sessionAccountSchema, deviceSessionStateSchema, activeTokenSchema, deviceSessionSyncSchema, deviceTokenMintRequestSchema, deviceTokenMintResponseSchema, } from './deviceSession';
31
+ export type { SessionAccount, DeviceSessionState, ActiveToken, DeviceSessionSync, DeviceTokenMintRequest, DeviceTokenMintResponse, } from './deviceSession';
32
+ export { loginResultSchema, } from './deviceBoot';
33
+ export type { LoginTwoFactorRequired, LoginSessionResult, LoginResult, SecurityAlert, SecurityAlertAnomaly, } from './deviceBoot';
@@ -16,8 +16,7 @@
16
16
  *
17
17
  * Faithful to the producers:
18
18
  * - `packages/api/src/utils/userTransform.ts` `formatUserResponse` — the
19
- * canonical serialization used by the device-first bootstrap/exchange
20
- * endpoints (`deviceAuth.ts`), login/signup, device sessions, etc.
19
+ * canonical serialization used by login/signup, device sessions, etc.
21
20
  * Emits `id` (NOT `_id`), forwards `username` verbatim (may be absent), and
22
21
  * emits `name` as the structured `{ first, last, full, displayName }`
23
22
  * subdocument.
@@ -417,12 +416,12 @@ export declare const currentUserResponseSchema: z.ZodObject<{
417
416
  verifiedDomains?: import("./identity").VerifiedDomain[] | undefined;
418
417
  verified?: boolean | undefined;
419
418
  username?: string | undefined;
419
+ avatar?: string | null | undefined;
420
420
  _id?: string | undefined;
421
421
  email?: string | undefined;
422
422
  phone?: string | undefined;
423
423
  address?: string | undefined;
424
424
  birthday?: string | undefined;
425
- avatar?: string | null | undefined;
426
425
  color?: string | null | undefined;
427
426
  language?: string | undefined;
428
427
  } & {
@@ -437,12 +436,12 @@ export declare const currentUserResponseSchema: z.ZodObject<{
437
436
  verifiedDomains?: import("./identity").VerifiedDomain[] | undefined;
438
437
  verified?: boolean | undefined;
439
438
  username?: string | undefined;
439
+ avatar?: string | null | undefined;
440
440
  _id?: string | undefined;
441
441
  email?: string | undefined;
442
442
  phone?: string | undefined;
443
443
  address?: string | undefined;
444
444
  birthday?: string | undefined;
445
- avatar?: string | null | undefined;
446
445
  color?: string | null | undefined;
447
446
  language?: string | undefined;
448
447
  } & {
@@ -549,7 +548,6 @@ export declare const deviceLinkedSessionSchema: z.ZodObject<{
549
548
  }, z.ZodTypeAny, "passthrough">>>>;
550
549
  }, "strip", z.ZodTypeAny, {
551
550
  sessionId: string;
552
- isCurrent?: boolean | undefined;
553
551
  user?: z.objectOutputType<{
554
552
  /** MongoDB ObjectId as a string. Present on `formatUserResponse` output. */
555
553
  id: z.ZodOptional<z.ZodString>;
@@ -580,9 +578,9 @@ export declare const deviceLinkedSessionSchema: z.ZodObject<{
580
578
  */
581
579
  verifiedDomains: z.ZodOptional<z.ZodArray<z.ZodType<import("./identity").VerifiedDomain, z.ZodTypeDef, import("./identity").VerifiedDomain>, "many">>;
582
580
  }, z.ZodTypeAny, "passthrough"> | null | undefined;
581
+ isCurrent?: boolean | undefined;
583
582
  }, {
584
583
  sessionId: string;
585
- isCurrent?: boolean | undefined;
586
584
  user?: z.objectInputType<{
587
585
  /** MongoDB ObjectId as a string. Present on `formatUserResponse` output. */
588
586
  id: z.ZodOptional<z.ZodString>;
@@ -613,6 +611,7 @@ export declare const deviceLinkedSessionSchema: z.ZodObject<{
613
611
  */
614
612
  verifiedDomains: z.ZodOptional<z.ZodArray<z.ZodType<import("./identity").VerifiedDomain, z.ZodTypeDef, import("./identity").VerifiedDomain>, "many">>;
615
613
  }, z.ZodTypeAny, "passthrough"> | null | undefined;
614
+ isCurrent?: boolean | undefined;
616
615
  }>;
617
616
  export type DeviceLinkedSessionResponse = z.infer<typeof deviceLinkedSessionSchema>;
618
617
  /** Wire shape of `GET /session/device/sessions/:sessionId` (an array). */
@@ -709,7 +708,6 @@ export declare const deviceLinkedSessionsResponseSchema: z.ZodArray<z.ZodObject<
709
708
  }, z.ZodTypeAny, "passthrough">>>>;
710
709
  }, "strip", z.ZodTypeAny, {
711
710
  sessionId: string;
712
- isCurrent?: boolean | undefined;
713
711
  user?: z.objectOutputType<{
714
712
  /** MongoDB ObjectId as a string. Present on `formatUserResponse` output. */
715
713
  id: z.ZodOptional<z.ZodString>;
@@ -740,9 +738,9 @@ export declare const deviceLinkedSessionsResponseSchema: z.ZodArray<z.ZodObject<
740
738
  */
741
739
  verifiedDomains: z.ZodOptional<z.ZodArray<z.ZodType<import("./identity").VerifiedDomain, z.ZodTypeDef, import("./identity").VerifiedDomain>, "many">>;
742
740
  }, z.ZodTypeAny, "passthrough"> | null | undefined;
741
+ isCurrent?: boolean | undefined;
743
742
  }, {
744
743
  sessionId: string;
745
- isCurrent?: boolean | undefined;
746
744
  user?: z.objectInputType<{
747
745
  /** MongoDB ObjectId as a string. Present on `formatUserResponse` output. */
748
746
  id: z.ZodOptional<z.ZodString>;
@@ -773,6 +771,7 @@ export declare const deviceLinkedSessionsResponseSchema: z.ZodArray<z.ZodObject<
773
771
  */
774
772
  verifiedDomains: z.ZodOptional<z.ZodArray<z.ZodType<import("./identity").VerifiedDomain, z.ZodTypeDef, import("./identity").VerifiedDomain>, "many">>;
775
773
  }, z.ZodTypeAny, "passthrough"> | null | undefined;
774
+ isCurrent?: boolean | undefined;
776
775
  }>, "many">;
777
776
  export type DeviceLinkedSessionsResponseContract = z.infer<typeof deviceLinkedSessionsResponseSchema>;
778
777
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oxyhq/contracts",
3
- "version": "0.11.0",
3
+ "version": "0.13.0",
4
4
  "description": "OxyHQ API contracts — single source of truth for request/response Zod schemas and inferred types, shared by the backend and the client SDKs",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",