@oxy.so/contracts 1.4.0 → 2.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/index.js +9 -22
- package/dist/cjs/linkedAccounts.js +93 -0
- package/dist/cjs/notifications.js +81 -0
- package/dist/esm/.tsbuildinfo +1 -1
- package/dist/esm/index.js +2 -1
- package/dist/esm/linkedAccounts.js +90 -0
- package/dist/esm/notifications.js +78 -0
- package/dist/types/.tsbuildinfo +1 -1
- package/dist/types/deviceDirectory.d.ts +46 -46
- package/dist/types/deviceSession.d.ts +2 -2
- package/dist/types/externalIdentity.d.ts +4 -4
- package/dist/types/index.d.ts +2 -2
- package/dist/types/inference/aliaModelRelease.d.ts +4 -4
- package/dist/types/inference/modelDocumentation.d.ts +8 -8
- package/dist/types/inference/providerConnection.d.ts +4 -4
- package/dist/types/linkedAccounts.d.ts +341 -0
- package/dist/types/notifications.d.ts +93 -0
- package/dist/types/oauth.d.ts +16 -16
- package/dist/types/sessionStatus.d.ts +6 -6
- package/dist/types/userResponse.d.ts +4 -4
- package/package.json +1 -1
- package/dist/cjs/browserHub.js +0 -215
- package/dist/esm/browserHub.js +0 -212
- package/dist/types/browserHub.d.ts +0 -856
package/dist/types/oauth.d.ts
CHANGED
|
@@ -106,10 +106,10 @@ export declare const mcpOAuthClientApplicationSchema: z.ZodObject<{
|
|
|
106
106
|
type: "system" | "internal" | "first_party" | "third_party";
|
|
107
107
|
name: string;
|
|
108
108
|
id: string;
|
|
109
|
-
clientId: string;
|
|
110
109
|
isOfficial: boolean;
|
|
111
110
|
isInternal: boolean;
|
|
112
111
|
scopes: string[];
|
|
112
|
+
clientId: string;
|
|
113
113
|
description?: string | undefined;
|
|
114
114
|
icon?: string | undefined;
|
|
115
115
|
websiteUrl?: string | undefined;
|
|
@@ -120,10 +120,10 @@ export declare const mcpOAuthClientApplicationSchema: z.ZodObject<{
|
|
|
120
120
|
type: "system" | "internal" | "first_party" | "third_party";
|
|
121
121
|
name: string;
|
|
122
122
|
id: string;
|
|
123
|
-
clientId: string;
|
|
124
123
|
isOfficial: boolean;
|
|
125
124
|
isInternal: boolean;
|
|
126
125
|
scopes: string[];
|
|
126
|
+
clientId: string;
|
|
127
127
|
description?: string | undefined;
|
|
128
128
|
icon?: string | undefined;
|
|
129
129
|
websiteUrl?: string | undefined;
|
|
@@ -215,10 +215,10 @@ export declare const mcpOAuthConsentContextSchema: z.ZodObject<{
|
|
|
215
215
|
type: "system" | "internal" | "first_party" | "third_party";
|
|
216
216
|
name: string;
|
|
217
217
|
id: string;
|
|
218
|
-
clientId: string;
|
|
219
218
|
isOfficial: boolean;
|
|
220
219
|
isInternal: boolean;
|
|
221
220
|
scopes: string[];
|
|
221
|
+
clientId: string;
|
|
222
222
|
description?: string | undefined;
|
|
223
223
|
icon?: string | undefined;
|
|
224
224
|
websiteUrl?: string | undefined;
|
|
@@ -229,10 +229,10 @@ export declare const mcpOAuthConsentContextSchema: z.ZodObject<{
|
|
|
229
229
|
type: "system" | "internal" | "first_party" | "third_party";
|
|
230
230
|
name: string;
|
|
231
231
|
id: string;
|
|
232
|
-
clientId: string;
|
|
233
232
|
isOfficial: boolean;
|
|
234
233
|
isInternal: boolean;
|
|
235
234
|
scopes: string[];
|
|
235
|
+
clientId: string;
|
|
236
236
|
description?: string | undefined;
|
|
237
237
|
icon?: string | undefined;
|
|
238
238
|
websiteUrl?: string | undefined;
|
|
@@ -423,10 +423,10 @@ export declare const mcpOAuthConsentContextSchema: z.ZodObject<{
|
|
|
423
423
|
type: "system" | "internal" | "first_party" | "third_party";
|
|
424
424
|
name: string;
|
|
425
425
|
id: string;
|
|
426
|
-
clientId: string;
|
|
427
426
|
isOfficial: boolean;
|
|
428
427
|
isInternal: boolean;
|
|
429
428
|
scopes: string[];
|
|
429
|
+
clientId: string;
|
|
430
430
|
description?: string | undefined;
|
|
431
431
|
icon?: string | undefined;
|
|
432
432
|
websiteUrl?: string | undefined;
|
|
@@ -471,10 +471,10 @@ export declare const mcpOAuthConsentContextSchema: z.ZodObject<{
|
|
|
471
471
|
type: "system" | "internal" | "first_party" | "third_party";
|
|
472
472
|
name: string;
|
|
473
473
|
id: string;
|
|
474
|
-
clientId: string;
|
|
475
474
|
isOfficial: boolean;
|
|
476
475
|
isInternal: boolean;
|
|
477
476
|
scopes: string[];
|
|
477
|
+
clientId: string;
|
|
478
478
|
description?: string | undefined;
|
|
479
479
|
icon?: string | undefined;
|
|
480
480
|
websiteUrl?: string | undefined;
|
|
@@ -510,10 +510,10 @@ export declare const mcpOAuthClientInfoResponseSchema: z.ZodObject<{
|
|
|
510
510
|
type: "system" | "internal" | "first_party" | "third_party";
|
|
511
511
|
name: string;
|
|
512
512
|
id: string;
|
|
513
|
-
clientId: string;
|
|
514
513
|
isOfficial: boolean;
|
|
515
514
|
isInternal: boolean;
|
|
516
515
|
scopes: string[];
|
|
516
|
+
clientId: string;
|
|
517
517
|
description?: string | undefined;
|
|
518
518
|
icon?: string | undefined;
|
|
519
519
|
websiteUrl?: string | undefined;
|
|
@@ -524,10 +524,10 @@ export declare const mcpOAuthClientInfoResponseSchema: z.ZodObject<{
|
|
|
524
524
|
type: "system" | "internal" | "first_party" | "third_party";
|
|
525
525
|
name: string;
|
|
526
526
|
id: string;
|
|
527
|
-
clientId: string;
|
|
528
527
|
isOfficial: boolean;
|
|
529
528
|
isInternal: boolean;
|
|
530
529
|
scopes: string[];
|
|
530
|
+
clientId: string;
|
|
531
531
|
description?: string | undefined;
|
|
532
532
|
icon?: string | undefined;
|
|
533
533
|
websiteUrl?: string | undefined;
|
|
@@ -540,10 +540,10 @@ export declare const mcpOAuthClientInfoResponseSchema: z.ZodObject<{
|
|
|
540
540
|
type: "system" | "internal" | "first_party" | "third_party";
|
|
541
541
|
name: string;
|
|
542
542
|
id: string;
|
|
543
|
-
clientId: string;
|
|
544
543
|
isOfficial: boolean;
|
|
545
544
|
isInternal: boolean;
|
|
546
545
|
scopes: string[];
|
|
546
|
+
clientId: string;
|
|
547
547
|
description?: string | undefined;
|
|
548
548
|
icon?: string | undefined;
|
|
549
549
|
websiteUrl?: string | undefined;
|
|
@@ -556,10 +556,10 @@ export declare const mcpOAuthClientInfoResponseSchema: z.ZodObject<{
|
|
|
556
556
|
type: "system" | "internal" | "first_party" | "third_party";
|
|
557
557
|
name: string;
|
|
558
558
|
id: string;
|
|
559
|
-
clientId: string;
|
|
560
559
|
isOfficial: boolean;
|
|
561
560
|
isInternal: boolean;
|
|
562
561
|
scopes: string[];
|
|
562
|
+
clientId: string;
|
|
563
563
|
description?: string | undefined;
|
|
564
564
|
icon?: string | undefined;
|
|
565
565
|
websiteUrl?: string | undefined;
|
|
@@ -590,10 +590,10 @@ export declare const mcpOAuthConsentResponseSchema: z.ZodObject<{
|
|
|
590
590
|
type: "system" | "internal" | "first_party" | "third_party";
|
|
591
591
|
name: string;
|
|
592
592
|
id: string;
|
|
593
|
-
clientId: string;
|
|
594
593
|
isOfficial: boolean;
|
|
595
594
|
isInternal: boolean;
|
|
596
595
|
scopes: string[];
|
|
596
|
+
clientId: string;
|
|
597
597
|
description?: string | undefined;
|
|
598
598
|
icon?: string | undefined;
|
|
599
599
|
websiteUrl?: string | undefined;
|
|
@@ -604,10 +604,10 @@ export declare const mcpOAuthConsentResponseSchema: z.ZodObject<{
|
|
|
604
604
|
type: "system" | "internal" | "first_party" | "third_party";
|
|
605
605
|
name: string;
|
|
606
606
|
id: string;
|
|
607
|
-
clientId: string;
|
|
608
607
|
isOfficial: boolean;
|
|
609
608
|
isInternal: boolean;
|
|
610
609
|
scopes: string[];
|
|
610
|
+
clientId: string;
|
|
611
611
|
description?: string | undefined;
|
|
612
612
|
icon?: string | undefined;
|
|
613
613
|
websiteUrl?: string | undefined;
|
|
@@ -798,10 +798,10 @@ export declare const mcpOAuthConsentResponseSchema: z.ZodObject<{
|
|
|
798
798
|
type: "system" | "internal" | "first_party" | "third_party";
|
|
799
799
|
name: string;
|
|
800
800
|
id: string;
|
|
801
|
-
clientId: string;
|
|
802
801
|
isOfficial: boolean;
|
|
803
802
|
isInternal: boolean;
|
|
804
803
|
scopes: string[];
|
|
804
|
+
clientId: string;
|
|
805
805
|
description?: string | undefined;
|
|
806
806
|
icon?: string | undefined;
|
|
807
807
|
websiteUrl?: string | undefined;
|
|
@@ -846,10 +846,10 @@ export declare const mcpOAuthConsentResponseSchema: z.ZodObject<{
|
|
|
846
846
|
type: "system" | "internal" | "first_party" | "third_party";
|
|
847
847
|
name: string;
|
|
848
848
|
id: string;
|
|
849
|
-
clientId: string;
|
|
850
849
|
isOfficial: boolean;
|
|
851
850
|
isInternal: boolean;
|
|
852
851
|
scopes: string[];
|
|
852
|
+
clientId: string;
|
|
853
853
|
description?: string | undefined;
|
|
854
854
|
icon?: string | undefined;
|
|
855
855
|
websiteUrl?: string | undefined;
|
|
@@ -896,10 +896,10 @@ export declare const mcpOAuthConsentResponseSchema: z.ZodObject<{
|
|
|
896
896
|
type: "system" | "internal" | "first_party" | "third_party";
|
|
897
897
|
name: string;
|
|
898
898
|
id: string;
|
|
899
|
-
clientId: string;
|
|
900
899
|
isOfficial: boolean;
|
|
901
900
|
isInternal: boolean;
|
|
902
901
|
scopes: string[];
|
|
902
|
+
clientId: string;
|
|
903
903
|
description?: string | undefined;
|
|
904
904
|
icon?: string | undefined;
|
|
905
905
|
websiteUrl?: string | undefined;
|
|
@@ -947,10 +947,10 @@ export declare const mcpOAuthConsentResponseSchema: z.ZodObject<{
|
|
|
947
947
|
type: "system" | "internal" | "first_party" | "third_party";
|
|
948
948
|
name: string;
|
|
949
949
|
id: string;
|
|
950
|
-
clientId: string;
|
|
951
950
|
isOfficial: boolean;
|
|
952
951
|
isInternal: boolean;
|
|
953
952
|
scopes: string[];
|
|
953
|
+
clientId: string;
|
|
954
954
|
description?: string | undefined;
|
|
955
955
|
icon?: string | undefined;
|
|
956
956
|
websiteUrl?: string | undefined;
|
|
@@ -180,11 +180,11 @@ export declare const sessionStatusSchema: z.ZodObject<{
|
|
|
180
180
|
}, "strip", z.ZodTypeAny, {
|
|
181
181
|
status: string;
|
|
182
182
|
expiresAt?: string | undefined;
|
|
183
|
-
sessionId?: string | null | undefined;
|
|
184
|
-
userId?: string | null | undefined;
|
|
185
183
|
publicKey?: string | null | undefined;
|
|
186
|
-
|
|
184
|
+
userId?: string | null | undefined;
|
|
185
|
+
sessionId?: string | null | undefined;
|
|
187
186
|
authorized?: boolean | undefined;
|
|
187
|
+
sessionToken?: string | undefined;
|
|
188
188
|
application?: {
|
|
189
189
|
type: "system" | "internal" | "first_party" | "third_party";
|
|
190
190
|
name: string;
|
|
@@ -205,11 +205,11 @@ export declare const sessionStatusSchema: z.ZodObject<{
|
|
|
205
205
|
}, {
|
|
206
206
|
status: string;
|
|
207
207
|
expiresAt?: string | undefined;
|
|
208
|
-
sessionId?: string | null | undefined;
|
|
209
|
-
userId?: string | null | undefined;
|
|
210
208
|
publicKey?: string | null | undefined;
|
|
211
|
-
|
|
209
|
+
userId?: string | null | undefined;
|
|
210
|
+
sessionId?: string | null | undefined;
|
|
212
211
|
authorized?: boolean | undefined;
|
|
212
|
+
sessionToken?: string | undefined;
|
|
213
213
|
application?: {
|
|
214
214
|
type: "system" | "internal" | "first_party" | "third_party";
|
|
215
215
|
name: string;
|
|
@@ -1335,7 +1335,6 @@ export declare const deviceLinkedSessionSchema: z.ZodObject<{
|
|
|
1335
1335
|
}, z.ZodTypeAny, "passthrough">>>>;
|
|
1336
1336
|
}, "strip", z.ZodTypeAny, {
|
|
1337
1337
|
sessionId: string;
|
|
1338
|
-
isCurrent?: boolean | undefined;
|
|
1339
1338
|
user?: z.objectOutputType<{
|
|
1340
1339
|
/** MongoDB ObjectId as a string. Present on `formatUserResponse` output. */
|
|
1341
1340
|
id: z.ZodOptional<z.ZodString>;
|
|
@@ -1438,9 +1437,9 @@ export declare const deviceLinkedSessionSchema: z.ZodObject<{
|
|
|
1438
1437
|
*/
|
|
1439
1438
|
themePreference: z.ZodOptional<z.ZodType<ThemePreference, z.ZodTypeDef, ThemePreference>>;
|
|
1440
1439
|
}, z.ZodTypeAny, "passthrough"> | null | undefined;
|
|
1440
|
+
isCurrent?: boolean | undefined;
|
|
1441
1441
|
}, {
|
|
1442
1442
|
sessionId: string;
|
|
1443
|
-
isCurrent?: boolean | undefined;
|
|
1444
1443
|
user?: z.objectInputType<{
|
|
1445
1444
|
/** MongoDB ObjectId as a string. Present on `formatUserResponse` output. */
|
|
1446
1445
|
id: z.ZodOptional<z.ZodString>;
|
|
@@ -1543,6 +1542,7 @@ export declare const deviceLinkedSessionSchema: z.ZodObject<{
|
|
|
1543
1542
|
*/
|
|
1544
1543
|
themePreference: z.ZodOptional<z.ZodType<ThemePreference, z.ZodTypeDef, ThemePreference>>;
|
|
1545
1544
|
}, z.ZodTypeAny, "passthrough"> | null | undefined;
|
|
1545
|
+
isCurrent?: boolean | undefined;
|
|
1546
1546
|
}>;
|
|
1547
1547
|
export type DeviceLinkedSessionResponse = z.infer<typeof deviceLinkedSessionSchema>;
|
|
1548
1548
|
/** Wire shape of `GET /session/device/sessions/:sessionId` (an array). */
|
|
@@ -1855,7 +1855,6 @@ export declare const deviceLinkedSessionsResponseSchema: z.ZodArray<z.ZodObject<
|
|
|
1855
1855
|
}, z.ZodTypeAny, "passthrough">>>>;
|
|
1856
1856
|
}, "strip", z.ZodTypeAny, {
|
|
1857
1857
|
sessionId: string;
|
|
1858
|
-
isCurrent?: boolean | undefined;
|
|
1859
1858
|
user?: z.objectOutputType<{
|
|
1860
1859
|
/** MongoDB ObjectId as a string. Present on `formatUserResponse` output. */
|
|
1861
1860
|
id: z.ZodOptional<z.ZodString>;
|
|
@@ -1958,9 +1957,9 @@ export declare const deviceLinkedSessionsResponseSchema: z.ZodArray<z.ZodObject<
|
|
|
1958
1957
|
*/
|
|
1959
1958
|
themePreference: z.ZodOptional<z.ZodType<ThemePreference, z.ZodTypeDef, ThemePreference>>;
|
|
1960
1959
|
}, z.ZodTypeAny, "passthrough"> | null | undefined;
|
|
1960
|
+
isCurrent?: boolean | undefined;
|
|
1961
1961
|
}, {
|
|
1962
1962
|
sessionId: string;
|
|
1963
|
-
isCurrent?: boolean | undefined;
|
|
1964
1963
|
user?: z.objectInputType<{
|
|
1965
1964
|
/** MongoDB ObjectId as a string. Present on `formatUserResponse` output. */
|
|
1966
1965
|
id: z.ZodOptional<z.ZodString>;
|
|
@@ -2063,6 +2062,7 @@ export declare const deviceLinkedSessionsResponseSchema: z.ZodArray<z.ZodObject<
|
|
|
2063
2062
|
*/
|
|
2064
2063
|
themePreference: z.ZodOptional<z.ZodType<ThemePreference, z.ZodTypeDef, ThemePreference>>;
|
|
2065
2064
|
}, z.ZodTypeAny, "passthrough"> | null | undefined;
|
|
2065
|
+
isCurrent?: boolean | undefined;
|
|
2066
2066
|
}>, "many">;
|
|
2067
2067
|
export type DeviceLinkedSessionsResponseContract = z.infer<typeof deviceLinkedSessionsResponseSchema>;
|
|
2068
2068
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oxy.so/contracts",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.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",
|
package/dist/cjs/browserHub.js
DELETED
|
@@ -1,215 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.hubAuthorizeResultSchema = exports.hubAuthorizeRequestSchema = exports.hubActivateRequestSchema = exports.hubClaimRequestSchema = exports.hubSessionSchema = exports.browserHubRevokeResponseSchema = exports.browserHubErrorSchema = exports.browserHubResolveResponseSchema = exports.browserHubHandleResponseSchema = exports.browserHubHandleRequestSchema = exports.browserHubHandleSchema = exports.BROWSER_HUB_HANDLE_TTL_MS = exports.BROWSER_HUB_COOKIE_ATTRIBUTES = exports.BROWSER_HUB_COOKIE_NAME = void 0;
|
|
4
|
-
const zod_1 = require("zod");
|
|
5
|
-
const deviceDirectory_1 = require("./deviceDirectory");
|
|
6
|
-
/**
|
|
7
|
-
* The browser DeviceSession hub at `auth.oxy.so` (issue #937, Phase 5, ADR 0003).
|
|
8
|
-
*
|
|
9
|
-
* Two wire surfaces live in this file and they are deliberately different
|
|
10
|
-
* shapes, because they answer to different callers:
|
|
11
|
-
*
|
|
12
|
-
* - The `browserHub*` schemas below the first divider are the API's
|
|
13
|
-
* (`api.oxy.so/session/browser-hub/*`), spoken ONLY by the IdP's own
|
|
14
|
-
* server/edge layer. They carry the raw handle and a bearer, so nothing that
|
|
15
|
-
* speaks them may run in a browser.
|
|
16
|
-
* - The `hub*` schemas below the second divider are the EDGE's
|
|
17
|
-
* (`auth.oxy.so/hub/*`), spoken by the IdP SPA. They carry neither: the
|
|
18
|
-
* handle stays in an `HttpOnly` cookie the script cannot read, and the
|
|
19
|
-
* device-wide bearer stays at the edge.
|
|
20
|
-
*
|
|
21
|
-
* That split is the whole point of the phase. A single schema covering both
|
|
22
|
-
* would let a refactor move a credential across the boundary without any type
|
|
23
|
-
* changing shape.
|
|
24
|
-
*
|
|
25
|
-
* ## What is NOT reopened here
|
|
26
|
-
*
|
|
27
|
-
* Relying-party origins remain zero-cookie: they keep `{deviceId,
|
|
28
|
-
* deviceSecret}` + `POST /session/device/token` and set no cookie of any kind.
|
|
29
|
-
* `auth.oxy.so` alone holds a handle, first-party only. There is no
|
|
30
|
-
* refresh-token family and no bootstrap hop.
|
|
31
|
-
*/
|
|
32
|
-
/* -------------------------------------------------------------------------- */
|
|
33
|
-
/* The cookie */
|
|
34
|
-
/* -------------------------------------------------------------------------- */
|
|
35
|
-
/**
|
|
36
|
-
* The one cookie name, `__Host-` prefixed.
|
|
37
|
-
*
|
|
38
|
-
* The prefix is not decoration: a browser refuses to store a `__Host-` cookie
|
|
39
|
-
* that carries a `Domain` attribute or a `Path` other than `/`, or that arrives
|
|
40
|
-
* without `Secure`. So the name itself is what makes "bound to `auth.oxy.so`
|
|
41
|
-
* alone, readable by no other `oxy.so` host" enforced by the client rather than
|
|
42
|
-
* merely intended by the server — including against a compromised sibling
|
|
43
|
-
* subdomain, which is the specific attack `Domain=.oxy.so` would have opened.
|
|
44
|
-
*/
|
|
45
|
-
exports.BROWSER_HUB_COOKIE_NAME = '__Host-oxy-device';
|
|
46
|
-
/**
|
|
47
|
-
* The exact attribute set the edge sets, in the order it writes them.
|
|
48
|
-
*
|
|
49
|
-
* Held as data rather than as a template string so a test can assert the set
|
|
50
|
-
* rather than a rendered line, and so removing one attribute is a diff to a
|
|
51
|
-
* named constant instead of an edit inside a string literal.
|
|
52
|
-
*
|
|
53
|
-
* `Max-Age` is deliberately NOT in this list — see
|
|
54
|
-
* {@link BROWSER_HUB_HANDLE_TTL_MS}, which the edge appends. Everything here is
|
|
55
|
-
* a SECURITY attribute and none of them is ever conditional.
|
|
56
|
-
*/
|
|
57
|
-
exports.BROWSER_HUB_COOKIE_ATTRIBUTES = ['Secure', 'HttpOnly', 'SameSite=Lax', 'Path=/'];
|
|
58
|
-
/**
|
|
59
|
-
* How long a hub handle lives, server-side and in the cookie alike.
|
|
60
|
-
*
|
|
61
|
-
* Thirty days. The cookie's `Max-Age` is derived from this same constant so the
|
|
62
|
-
* two cannot disagree: a cookie outliving its credential produces a browser that
|
|
63
|
-
* believes it is signed in and is refused on every call, and a credential
|
|
64
|
-
* outliving its cookie leaves an un-addressable row alive on the server.
|
|
65
|
-
*
|
|
66
|
-
* A hub handle is NOT a session cookie (one with no `Max-Age`, discarded when
|
|
67
|
-
* the browser closes). It cannot be: the thing it identifies is the browser
|
|
68
|
-
* PROFILE's device session, and a device session that evaporates when the user
|
|
69
|
-
* quits their browser would send them back to a QR scan every morning — the
|
|
70
|
-
* exact failure ADR 0003 exists to remove.
|
|
71
|
-
*/
|
|
72
|
-
exports.BROWSER_HUB_HANDLE_TTL_MS = 30 * 24 * 60 * 60 * 1000;
|
|
73
|
-
/* -------------------------------------------------------------------------- */
|
|
74
|
-
/* api.oxy.so/session/browser-hub/* — spoken by the edge, never a browser */
|
|
75
|
-
/* -------------------------------------------------------------------------- */
|
|
76
|
-
/**
|
|
77
|
-
* The raw handle, as it travels between the edge and the API.
|
|
78
|
-
*
|
|
79
|
-
* An opaque base64url random value and NOTHING else — no token, no user id, no
|
|
80
|
-
* device id, no account id, no serialized state. The server stores only
|
|
81
|
-
* `sha256(handle)`, so a dump of the column cannot address a browser.
|
|
82
|
-
*
|
|
83
|
-
* The minimum length is a floor against an empty or truncated value reaching a
|
|
84
|
-
* hash comparison, not a statement about the entropy: that is fixed by the
|
|
85
|
-
* issuer (`BROWSER_HUB_HANDLE_BYTES` in the API), and a handle is the only
|
|
86
|
-
* credential in this flow, so it is 256 bits.
|
|
87
|
-
*/
|
|
88
|
-
exports.browserHubHandleSchema = zod_1.z.string().min(32);
|
|
89
|
-
/** Request body of every handle-presenting API endpoint. */
|
|
90
|
-
exports.browserHubHandleRequestSchema = zod_1.z.object({
|
|
91
|
-
handle: exports.browserHubHandleSchema,
|
|
92
|
-
});
|
|
93
|
-
/**
|
|
94
|
-
* Response of `POST /session/browser-hub/establish` and `.../rotate`.
|
|
95
|
-
*
|
|
96
|
-
* The raw handle is returned exactly ONCE, to the edge, which puts it straight
|
|
97
|
-
* into the cookie and keeps no copy. It is never logged, never re-readable, and
|
|
98
|
-
* never reaches the browser's script context.
|
|
99
|
-
*/
|
|
100
|
-
exports.browserHubHandleResponseSchema = zod_1.z.object({
|
|
101
|
-
handle: exports.browserHubHandleSchema,
|
|
102
|
-
expiresAt: zod_1.z.string(),
|
|
103
|
-
});
|
|
104
|
-
/**
|
|
105
|
-
* Response of `POST /session/browser-hub/resolve` — the browser's device
|
|
106
|
-
* session, resolved from the handle alone.
|
|
107
|
-
*
|
|
108
|
-
* Carries a bearer because the edge needs one to run the authorize lane on the
|
|
109
|
-
* browser's behalf. It is the ordinary short-lived access token of the device's
|
|
110
|
-
* active context, and it stops at the edge.
|
|
111
|
-
*/
|
|
112
|
-
exports.browserHubResolveResponseSchema = zod_1.z.object({
|
|
113
|
-
accessToken: zod_1.z.string().min(1),
|
|
114
|
-
expiresAt: zod_1.z.string(),
|
|
115
|
-
directory: deviceDirectory_1.deviceDirectorySchema,
|
|
116
|
-
});
|
|
117
|
-
/**
|
|
118
|
-
* Why a handle did not resolve. A CLOSED set, and deliberately coarse.
|
|
119
|
-
*
|
|
120
|
-
* - `invalid_handle` — unknown, expired, or revoked. One code for all
|
|
121
|
-
* three: distinguishing them would tell a caller
|
|
122
|
-
* holding a guessed value whether it ever existed.
|
|
123
|
-
* - `no_active_session` — the handle is good and the device has nothing live
|
|
124
|
-
* to mint for. The credential is NOT revoked; the
|
|
125
|
-
* browser re-authenticates and keeps its cookie.
|
|
126
|
-
*/
|
|
127
|
-
exports.browserHubErrorSchema = zod_1.z.enum(['invalid_handle', 'no_active_session']);
|
|
128
|
-
/** Response of `POST /session/browser-hub/revoke`. Idempotent by construction. */
|
|
129
|
-
exports.browserHubRevokeResponseSchema = zod_1.z.object({
|
|
130
|
-
revoked: zod_1.z.boolean(),
|
|
131
|
-
});
|
|
132
|
-
/* -------------------------------------------------------------------------- */
|
|
133
|
-
/* auth.oxy.so/hub/* — spoken by the IdP SPA */
|
|
134
|
-
/* -------------------------------------------------------------------------- */
|
|
135
|
-
/**
|
|
136
|
-
* What the SPA is allowed to know about the hub session.
|
|
137
|
-
*
|
|
138
|
-
* `signed_out` covers "no cookie", "cookie present but the handle no longer
|
|
139
|
-
* resolves" and "resolved, but the device has nothing live" — from the script's
|
|
140
|
-
* side those are one state, and collapsing them here is what stops a UI from
|
|
141
|
-
* branching on a distinction it must not act on.
|
|
142
|
-
*
|
|
143
|
-
* `active` carries the DIRECTORY and no credential. A switcher renders from it;
|
|
144
|
-
* nothing in it can be spent against the API. The bearer that produced it never
|
|
145
|
-
* left the edge.
|
|
146
|
-
*/
|
|
147
|
-
exports.hubSessionSchema = zod_1.z.discriminatedUnion('status', [
|
|
148
|
-
zod_1.z.object({ status: zod_1.z.literal('signed_out') }),
|
|
149
|
-
zod_1.z.object({ status: zod_1.z.literal('active'), directory: deviceDirectory_1.deviceDirectorySchema }),
|
|
150
|
-
]);
|
|
151
|
-
/** Request body of `POST /hub/claim` — the Commons approval lane's handoff. */
|
|
152
|
-
exports.hubClaimRequestSchema = zod_1.z.object({
|
|
153
|
-
/**
|
|
154
|
-
* The secret `sessionToken` of an approved `AuthSession`, held only by the
|
|
155
|
-
* page that created it. The edge spends it server-side: the access token and
|
|
156
|
-
* device secret the claim yields are consumed to establish the hub and are
|
|
157
|
-
* then discarded, so neither is ever returned to the script.
|
|
158
|
-
*/
|
|
159
|
-
sessionToken: zod_1.z.string().min(1),
|
|
160
|
-
});
|
|
161
|
-
/** Request body of `POST /hub/activate` — pick the globally active context. */
|
|
162
|
-
exports.hubActivateRequestSchema = zod_1.z.object({
|
|
163
|
-
contextId: zod_1.z.string().min(1),
|
|
164
|
-
});
|
|
165
|
-
/**
|
|
166
|
-
* Request body of `POST /hub/authorize` — a later official origin joining.
|
|
167
|
-
*
|
|
168
|
-
* There is no `prompt` field, and that is not an omission. `'none'` is absent
|
|
169
|
-
* from `buildOAuthAuthorizeUrl`'s union in `@oxy.so/core` precisely so a silent
|
|
170
|
-
* loop cannot be rebuilt in one line, and this endpoint would be the second
|
|
171
|
-
* place to rebuild it. A caller that needs a login or consent prompt gets one
|
|
172
|
-
* by not passing `approve`.
|
|
173
|
-
*/
|
|
174
|
-
exports.hubAuthorizeRequestSchema = zod_1.z.object({
|
|
175
|
-
clientId: zod_1.z.string().min(1),
|
|
176
|
-
redirectUri: zod_1.z.string().url(),
|
|
177
|
-
state: zod_1.z.string().optional(),
|
|
178
|
-
codeChallenge: zod_1.z.string().min(1),
|
|
179
|
-
/** S256 only. `plain` is refused before the request leaves the edge. */
|
|
180
|
-
codeChallengeMethod: zod_1.z.literal('S256'),
|
|
181
|
-
scope: zod_1.z.string().optional(),
|
|
182
|
-
/**
|
|
183
|
-
* The user's explicit answer on the consent screen.
|
|
184
|
-
*
|
|
185
|
-
* Absent or `false` means "tell me whether consent is needed"; the edge then
|
|
186
|
-
* returns `consent_required` and mints nothing. Only `true` may mint, and only
|
|
187
|
-
* the consent screen's own button sends it — which is why the decision of
|
|
188
|
-
* WHETHER consent is required is re-read from the server on both passes rather
|
|
189
|
-
* than remembered from the first.
|
|
190
|
-
*/
|
|
191
|
-
approve: zod_1.z.boolean().optional(),
|
|
192
|
-
});
|
|
193
|
-
/**
|
|
194
|
-
* Result of `POST /hub/authorize`.
|
|
195
|
-
*
|
|
196
|
-
* `signed_out` is the honest answer for a browser with no hub session: the SPA
|
|
197
|
-
* runs the ordinary Commons-first authentication and tries again. It is never a
|
|
198
|
-
* redirect the edge performs on the browser's behalf — no automatic chain
|
|
199
|
-
* across Oxy origins, and nothing here can be hidden inside an iframe.
|
|
200
|
-
*/
|
|
201
|
-
exports.hubAuthorizeResultSchema = zod_1.z.discriminatedUnion('status', [
|
|
202
|
-
zod_1.z.object({ status: zod_1.z.literal('signed_out') }),
|
|
203
|
-
zod_1.z.object({
|
|
204
|
-
status: zod_1.z.literal('consent_required'),
|
|
205
|
-
reason: zod_1.z.enum(['new', 'scope_changed']),
|
|
206
|
-
userConsentScopes: zod_1.z.array(zod_1.z.string()).optional(),
|
|
207
|
-
}),
|
|
208
|
-
zod_1.z.object({
|
|
209
|
-
status: zod_1.z.literal('code'),
|
|
210
|
-
code: zod_1.z.string().min(1),
|
|
211
|
-
state: zod_1.z.string().nullable(),
|
|
212
|
-
redirectUri: zod_1.z.string(),
|
|
213
|
-
expiresIn: zod_1.z.number().int().positive(),
|
|
214
|
-
}),
|
|
215
|
-
]);
|