@agent-native/core 0.157.21 → 0.157.23
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/collab/awareness.d.ts +2 -2
- package/dist/mcp/screen-memory-stdio.d.ts +7 -7
- package/dist/notifications/routes.d.ts +3 -3
- package/dist/progress/routes.d.ts +1 -1
- package/dist/server/embed-route.js +62 -1
- package/dist/server/embed-session.d.ts +11 -0
- package/dist/server/embed-session.js +92 -6
- package/dist/server/identity-sso-store.d.ts +1 -0
- package/dist/server/identity-sso-store.js +4 -0
- package/dist/server/identity-sso.js +3 -3
- package/dist/server/realtime-token.d.ts +1 -1
- package/package.json +1 -1
|
@@ -62,11 +62,11 @@ export declare const postAwareness: import("h3").EventHandlerWithFetch<import("h
|
|
|
62
62
|
error: string;
|
|
63
63
|
states?: undefined;
|
|
64
64
|
} | {
|
|
65
|
+
error?: undefined;
|
|
65
66
|
states: {
|
|
66
67
|
clientId: number;
|
|
67
68
|
state: string;
|
|
68
69
|
}[];
|
|
69
|
-
error?: undefined;
|
|
70
70
|
}>>;
|
|
71
71
|
/**
|
|
72
72
|
* GET /_agent-native/collab/:docId/users
|
|
@@ -77,9 +77,9 @@ export declare const getActiveUsers: import("h3").EventHandlerWithFetch<import("
|
|
|
77
77
|
error: string;
|
|
78
78
|
users?: undefined;
|
|
79
79
|
} | {
|
|
80
|
+
error?: undefined;
|
|
80
81
|
users: {
|
|
81
82
|
clientId: number;
|
|
82
83
|
lastSeen: number;
|
|
83
84
|
}[];
|
|
84
|
-
error?: undefined;
|
|
85
85
|
}>>;
|
|
@@ -137,13 +137,13 @@ export declare function screenMemoryMcpToolDefinitions(): ({
|
|
|
137
137
|
inputSchema: {
|
|
138
138
|
type: string;
|
|
139
139
|
properties: {
|
|
140
|
+
count?: undefined;
|
|
140
141
|
query?: undefined;
|
|
141
142
|
minutes?: undefined;
|
|
142
143
|
limit?: undefined;
|
|
143
144
|
clientHint?: undefined;
|
|
144
145
|
timestamp?: undefined;
|
|
145
146
|
chapterId?: undefined;
|
|
146
|
-
count?: undefined;
|
|
147
147
|
startAt?: undefined;
|
|
148
148
|
endAt?: undefined;
|
|
149
149
|
reason?: undefined;
|
|
@@ -159,6 +159,7 @@ export declare function screenMemoryMcpToolDefinitions(): ({
|
|
|
159
159
|
inputSchema: {
|
|
160
160
|
type: string;
|
|
161
161
|
properties: {
|
|
162
|
+
count?: undefined;
|
|
162
163
|
query: {
|
|
163
164
|
type: string;
|
|
164
165
|
description: string;
|
|
@@ -174,7 +175,6 @@ export declare function screenMemoryMcpToolDefinitions(): ({
|
|
|
174
175
|
clientHint?: undefined;
|
|
175
176
|
timestamp?: undefined;
|
|
176
177
|
chapterId?: undefined;
|
|
177
|
-
count?: undefined;
|
|
178
178
|
startAt?: undefined;
|
|
179
179
|
endAt?: undefined;
|
|
180
180
|
reason?: undefined;
|
|
@@ -190,6 +190,7 @@ export declare function screenMemoryMcpToolDefinitions(): ({
|
|
|
190
190
|
inputSchema: {
|
|
191
191
|
type: string;
|
|
192
192
|
properties: {
|
|
193
|
+
count?: undefined;
|
|
193
194
|
minutes: {
|
|
194
195
|
type: string;
|
|
195
196
|
description: string;
|
|
@@ -199,7 +200,6 @@ export declare function screenMemoryMcpToolDefinitions(): ({
|
|
|
199
200
|
clientHint?: undefined;
|
|
200
201
|
timestamp?: undefined;
|
|
201
202
|
chapterId?: undefined;
|
|
202
|
-
count?: undefined;
|
|
203
203
|
startAt?: undefined;
|
|
204
204
|
endAt?: undefined;
|
|
205
205
|
reason?: undefined;
|
|
@@ -216,6 +216,7 @@ export declare function screenMemoryMcpToolDefinitions(): ({
|
|
|
216
216
|
type: string;
|
|
217
217
|
required: string[];
|
|
218
218
|
properties: {
|
|
219
|
+
count?: undefined;
|
|
219
220
|
query: {
|
|
220
221
|
type: string;
|
|
221
222
|
description: string;
|
|
@@ -234,7 +235,6 @@ export declare function screenMemoryMcpToolDefinitions(): ({
|
|
|
234
235
|
};
|
|
235
236
|
timestamp?: undefined;
|
|
236
237
|
chapterId?: undefined;
|
|
237
|
-
count?: undefined;
|
|
238
238
|
startAt?: undefined;
|
|
239
239
|
endAt?: undefined;
|
|
240
240
|
reason?: undefined;
|
|
@@ -250,6 +250,7 @@ export declare function screenMemoryMcpToolDefinitions(): ({
|
|
|
250
250
|
type: string;
|
|
251
251
|
required: string[];
|
|
252
252
|
properties: {
|
|
253
|
+
count?: undefined;
|
|
253
254
|
query?: undefined;
|
|
254
255
|
minutes?: undefined;
|
|
255
256
|
limit?: undefined;
|
|
@@ -263,7 +264,6 @@ export declare function screenMemoryMcpToolDefinitions(): ({
|
|
|
263
264
|
description: string;
|
|
264
265
|
};
|
|
265
266
|
chapterId?: undefined;
|
|
266
|
-
count?: undefined;
|
|
267
267
|
startAt?: undefined;
|
|
268
268
|
endAt?: undefined;
|
|
269
269
|
includeMicrophone?: undefined;
|
|
@@ -314,13 +314,13 @@ export declare function screenMemoryMcpToolDefinitions(): ({
|
|
|
314
314
|
type: string;
|
|
315
315
|
required: string[];
|
|
316
316
|
properties: {
|
|
317
|
+
count?: undefined;
|
|
317
318
|
query?: undefined;
|
|
318
319
|
minutes?: undefined;
|
|
319
320
|
limit?: undefined;
|
|
320
321
|
clientHint?: undefined;
|
|
321
322
|
timestamp?: undefined;
|
|
322
323
|
chapterId?: undefined;
|
|
323
|
-
count?: undefined;
|
|
324
324
|
startAt: {
|
|
325
325
|
type: string;
|
|
326
326
|
description: string;
|
|
@@ -349,13 +349,13 @@ export declare function screenMemoryMcpToolDefinitions(): ({
|
|
|
349
349
|
type: string;
|
|
350
350
|
required: string[];
|
|
351
351
|
properties: {
|
|
352
|
+
count?: undefined;
|
|
352
353
|
query?: undefined;
|
|
353
354
|
minutes?: undefined;
|
|
354
355
|
limit?: undefined;
|
|
355
356
|
clientHint?: undefined;
|
|
356
357
|
timestamp?: undefined;
|
|
357
358
|
chapterId?: undefined;
|
|
358
|
-
count?: undefined;
|
|
359
359
|
startAt?: undefined;
|
|
360
360
|
endAt?: undefined;
|
|
361
361
|
reason?: undefined;
|
|
@@ -16,18 +16,18 @@ export declare function createNotificationsHandler(): import("h3").EventHandlerW
|
|
|
16
16
|
error?: undefined;
|
|
17
17
|
ok?: undefined;
|
|
18
18
|
} | {
|
|
19
|
+
count?: undefined;
|
|
19
20
|
updated: number;
|
|
20
21
|
error?: undefined;
|
|
21
22
|
ok?: undefined;
|
|
22
|
-
count?: undefined;
|
|
23
23
|
} | {
|
|
24
|
+
count?: undefined;
|
|
24
25
|
updated?: undefined;
|
|
25
26
|
error: string;
|
|
26
27
|
ok?: undefined;
|
|
27
|
-
count?: undefined;
|
|
28
28
|
} | {
|
|
29
|
+
count?: undefined;
|
|
29
30
|
updated?: undefined;
|
|
30
31
|
error?: undefined;
|
|
31
32
|
ok: boolean;
|
|
32
|
-
count?: undefined;
|
|
33
33
|
}>>;
|
|
@@ -83,6 +83,53 @@ function textResponse(event, message, status) {
|
|
|
83
83
|
}),
|
|
84
84
|
});
|
|
85
85
|
}
|
|
86
|
+
function embedTargetOrigin(event) {
|
|
87
|
+
const host = getHeader(event, "host")?.trim();
|
|
88
|
+
if (!host)
|
|
89
|
+
return null;
|
|
90
|
+
const forwardedProto = getHeader(event, "x-forwarded-proto")
|
|
91
|
+
?.split(",", 1)[0]
|
|
92
|
+
?.trim()
|
|
93
|
+
.toLowerCase();
|
|
94
|
+
const protocol = forwardedProto === "http" || forwardedProto === "https"
|
|
95
|
+
? forwardedProto
|
|
96
|
+
: "https";
|
|
97
|
+
return `${protocol}://${host}`;
|
|
98
|
+
}
|
|
99
|
+
function embedTargetAppId(origin) {
|
|
100
|
+
if (origin) {
|
|
101
|
+
try {
|
|
102
|
+
const hostname = new URL(origin).hostname;
|
|
103
|
+
const suffix = ".agent-native.com";
|
|
104
|
+
if (hostname.endsWith(suffix) && hostname.length > suffix.length) {
|
|
105
|
+
return hostname.slice(0, -suffix.length);
|
|
106
|
+
}
|
|
107
|
+
// coercion-ok: diagnostic host parsing must never change the auth response.
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
// The host is diagnostic context only; keep the response path independent.
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
const configured = [process.env.AGENT_NATIVE_APP_ID, process.env.APP_ID].find((value) => /^[a-z0-9][a-z0-9._-]{0,63}$/i.test(value?.trim() ?? ""));
|
|
114
|
+
if (configured)
|
|
115
|
+
return configured.trim();
|
|
116
|
+
return "unknown";
|
|
117
|
+
}
|
|
118
|
+
function logEmbedConsumeResult(event, diagnostic, responseStatus) {
|
|
119
|
+
const targetOrigin = embedTargetOrigin(event);
|
|
120
|
+
console.info("[agent-native] workspace embed consume", {
|
|
121
|
+
targetAppId: embedTargetAppId(targetOrigin),
|
|
122
|
+
targetOrigin,
|
|
123
|
+
ticketKey: diagnostic.ticketKey,
|
|
124
|
+
outcome: diagnostic.outcome,
|
|
125
|
+
ticketRowFound: diagnostic.ticketRowFound,
|
|
126
|
+
consumed: diagnostic.consumed,
|
|
127
|
+
expired: diagnostic.expired,
|
|
128
|
+
expectedOrgKey: diagnostic.expectedOrgKey,
|
|
129
|
+
ticketOrgKey: diagnostic.ticketOrgKey,
|
|
130
|
+
responseStatus,
|
|
131
|
+
});
|
|
132
|
+
}
|
|
86
133
|
function expiredEmbedSessionResponse(event) {
|
|
87
134
|
setEmbedStartResponseHeaders(event);
|
|
88
135
|
return new Response(`<!doctype html>
|
|
@@ -204,14 +251,24 @@ export function createEmbedStartRouteHandler(options = {}) {
|
|
|
204
251
|
const existingSession = await options
|
|
205
252
|
.getExistingSession?.(event)
|
|
206
253
|
.catch(() => null);
|
|
254
|
+
let consumeDiagnostic = null;
|
|
207
255
|
const consumed = await consumeEmbedSessionTicket(ticket, {
|
|
208
256
|
expectedOrgId: existingSession?.orgId ?? null,
|
|
257
|
+
onResult: (diagnostic) => {
|
|
258
|
+
consumeDiagnostic = diagnostic;
|
|
259
|
+
},
|
|
209
260
|
});
|
|
210
261
|
if (!consumed) {
|
|
262
|
+
if (consumeDiagnostic) {
|
|
263
|
+
logEmbedConsumeResult(event, consumeDiagnostic, 401);
|
|
264
|
+
}
|
|
211
265
|
return expiredEmbedSessionResponse(event);
|
|
212
266
|
}
|
|
213
267
|
const target = normalizeEmbedTargetPath(consumed.targetPath);
|
|
214
268
|
if (!target) {
|
|
269
|
+
if (consumeDiagnostic) {
|
|
270
|
+
logEmbedConsumeResult(event, consumeDiagnostic, 400);
|
|
271
|
+
}
|
|
215
272
|
return textResponse(event, "Invalid embed target.", 400);
|
|
216
273
|
}
|
|
217
274
|
const token = signEmbedSessionToken({
|
|
@@ -230,7 +287,11 @@ export function createEmbedStartRouteHandler(options = {}) {
|
|
|
230
287
|
const chatBridgeActive = firstQueryValue(query[MCP_APP_CHAT_BRIDGE_QUERY_PARAM]) === "1" ||
|
|
231
288
|
firstQueryValue(query[MCP_APP_CHAT_BRIDGE_QUERY_PARAM]) === "true";
|
|
232
289
|
const location = withConfiguredBasePath(withCollapsedAgentSidebarParam(appendEmbedParams(target, token, chatBridgeActive)));
|
|
233
|
-
|
|
290
|
+
const transplant = wantsTransplantLocationResponse(event);
|
|
291
|
+
if (consumeDiagnostic) {
|
|
292
|
+
logEmbedConsumeResult(event, consumeDiagnostic, transplant ? 200 : 302);
|
|
293
|
+
}
|
|
294
|
+
if (transplant) {
|
|
234
295
|
return transplantLocationResponse(event, location);
|
|
235
296
|
}
|
|
236
297
|
return redirectWithStagedCookies(event, location);
|
|
@@ -12,8 +12,19 @@ export interface EmbedSessionTicket {
|
|
|
12
12
|
ticketHash: string;
|
|
13
13
|
expiresAt: number;
|
|
14
14
|
}
|
|
15
|
+
export type EmbedSessionTicketConsumeOutcome = "missing-ticket" | "not-found" | "already-consumed" | "expired" | "org-mismatch" | "consumption-race" | "invalid-row" | "consumed";
|
|
16
|
+
export interface EmbedSessionTicketConsumeDiagnostic {
|
|
17
|
+
outcome: EmbedSessionTicketConsumeOutcome;
|
|
18
|
+
ticketKey: string | null;
|
|
19
|
+
ticketRowFound: boolean;
|
|
20
|
+
consumed: boolean;
|
|
21
|
+
expired: boolean;
|
|
22
|
+
expectedOrgKey: string | null;
|
|
23
|
+
ticketOrgKey: string | null;
|
|
24
|
+
}
|
|
15
25
|
export interface ConsumeEmbedSessionTicketOptions {
|
|
16
26
|
expectedOrgId?: string | null;
|
|
27
|
+
onResult?: (result: EmbedSessionTicketConsumeDiagnostic) => void;
|
|
17
28
|
}
|
|
18
29
|
export interface ConsumedEmbedSessionTicket {
|
|
19
30
|
ownerEmail: string;
|
|
@@ -133,6 +133,11 @@ function signPayload(payload) {
|
|
|
133
133
|
function hashTicket(ticket) {
|
|
134
134
|
return crypto.createHash("sha256").update(ticket).digest("hex");
|
|
135
135
|
}
|
|
136
|
+
function redactedIdentifier(value) {
|
|
137
|
+
if (!value)
|
|
138
|
+
return null;
|
|
139
|
+
return crypto.createHash("sha256").update(value).digest("hex").slice(0, 12);
|
|
140
|
+
}
|
|
136
141
|
function numberOrNull(value) {
|
|
137
142
|
if (value == null)
|
|
138
143
|
return null;
|
|
@@ -458,27 +463,79 @@ export async function createEmbedSessionTicket(input) {
|
|
|
458
463
|
return { ticket, ticketHash, expiresAt };
|
|
459
464
|
}
|
|
460
465
|
export async function consumeEmbedSessionTicket(ticket, options = {}) {
|
|
461
|
-
|
|
466
|
+
const expectedOrgKey = redactedIdentifier(options.expectedOrgId);
|
|
467
|
+
if (!ticket) {
|
|
468
|
+
options.onResult?.({
|
|
469
|
+
outcome: "missing-ticket",
|
|
470
|
+
ticketKey: null,
|
|
471
|
+
ticketRowFound: false,
|
|
472
|
+
consumed: false,
|
|
473
|
+
expired: false,
|
|
474
|
+
expectedOrgKey,
|
|
475
|
+
ticketOrgKey: null,
|
|
476
|
+
});
|
|
462
477
|
return null;
|
|
478
|
+
}
|
|
463
479
|
await ensureTable();
|
|
464
480
|
const ticketHash = hashTicket(ticket);
|
|
481
|
+
const ticketKey = ticketHash.slice(0, 12);
|
|
465
482
|
const now = Date.now();
|
|
466
483
|
const { rows } = await getDbExec().execute({
|
|
467
484
|
sql: "SELECT ticket_hash, owner_email, org_id, target_path, scope, expires_at, consumed_at " +
|
|
468
485
|
"FROM agent_native_embed_tickets WHERE ticket_hash = ?",
|
|
469
486
|
args: [ticketHash],
|
|
470
487
|
});
|
|
471
|
-
if (rows.length === 0)
|
|
488
|
+
if (rows.length === 0) {
|
|
489
|
+
options.onResult?.({
|
|
490
|
+
outcome: "not-found",
|
|
491
|
+
ticketKey,
|
|
492
|
+
ticketRowFound: false,
|
|
493
|
+
consumed: false,
|
|
494
|
+
expired: false,
|
|
495
|
+
expectedOrgKey,
|
|
496
|
+
ticketOrgKey: null,
|
|
497
|
+
});
|
|
472
498
|
return null;
|
|
499
|
+
}
|
|
473
500
|
const row = rows[0];
|
|
474
501
|
const expiresAt = numberOrNull(row.expires_at ?? row.expiresAt);
|
|
475
502
|
const consumedAt = numberOrNull(row.consumed_at ?? row.consumedAt);
|
|
476
503
|
const orgId = stringOrUndefined(row.org_id ?? row.orgId);
|
|
477
|
-
|
|
504
|
+
const ticketOrgKey = redactedIdentifier(orgId);
|
|
505
|
+
if (consumedAt != null) {
|
|
506
|
+
options.onResult?.({
|
|
507
|
+
outcome: "already-consumed",
|
|
508
|
+
ticketKey,
|
|
509
|
+
ticketRowFound: true,
|
|
510
|
+
consumed: true,
|
|
511
|
+
expired: false,
|
|
512
|
+
expectedOrgKey,
|
|
513
|
+
ticketOrgKey,
|
|
514
|
+
});
|
|
478
515
|
return null;
|
|
479
|
-
|
|
516
|
+
}
|
|
517
|
+
if (expiresAt != null && expiresAt < now) {
|
|
518
|
+
options.onResult?.({
|
|
519
|
+
outcome: "expired",
|
|
520
|
+
ticketKey,
|
|
521
|
+
ticketRowFound: true,
|
|
522
|
+
consumed: false,
|
|
523
|
+
expired: true,
|
|
524
|
+
expectedOrgKey,
|
|
525
|
+
ticketOrgKey,
|
|
526
|
+
});
|
|
480
527
|
return null;
|
|
528
|
+
}
|
|
481
529
|
if (options.expectedOrgId && orgId && orgId !== options.expectedOrgId) {
|
|
530
|
+
options.onResult?.({
|
|
531
|
+
outcome: "org-mismatch",
|
|
532
|
+
ticketKey,
|
|
533
|
+
ticketRowFound: true,
|
|
534
|
+
consumed: false,
|
|
535
|
+
expired: false,
|
|
536
|
+
expectedOrgKey,
|
|
537
|
+
ticketOrgKey,
|
|
538
|
+
});
|
|
482
539
|
return null;
|
|
483
540
|
}
|
|
484
541
|
const result = await getDbExec().execute({
|
|
@@ -486,12 +543,41 @@ export async function consumeEmbedSessionTicket(ticket, options = {}) {
|
|
|
486
543
|
"WHERE ticket_hash = ? AND consumed_at IS NULL",
|
|
487
544
|
args: [now, ticketHash],
|
|
488
545
|
});
|
|
489
|
-
if (result.rowsAffected === 0)
|
|
546
|
+
if (result.rowsAffected === 0) {
|
|
547
|
+
options.onResult?.({
|
|
548
|
+
outcome: "consumption-race",
|
|
549
|
+
ticketKey,
|
|
550
|
+
ticketRowFound: true,
|
|
551
|
+
consumed: false,
|
|
552
|
+
expired: false,
|
|
553
|
+
expectedOrgKey,
|
|
554
|
+
ticketOrgKey,
|
|
555
|
+
});
|
|
490
556
|
return null;
|
|
557
|
+
}
|
|
491
558
|
const targetPath = normalizeEmbedTargetPath(stringOrUndefined(row.target_path ?? row.targetPath));
|
|
492
559
|
const ownerEmail = stringOrUndefined(row.owner_email ?? row.ownerEmail);
|
|
493
|
-
if (!targetPath || !ownerEmail || expiresAt == null)
|
|
560
|
+
if (!targetPath || !ownerEmail || expiresAt == null) {
|
|
561
|
+
options.onResult?.({
|
|
562
|
+
outcome: "invalid-row",
|
|
563
|
+
ticketKey,
|
|
564
|
+
ticketRowFound: true,
|
|
565
|
+
consumed: true,
|
|
566
|
+
expired: false,
|
|
567
|
+
expectedOrgKey,
|
|
568
|
+
ticketOrgKey,
|
|
569
|
+
});
|
|
494
570
|
return null;
|
|
571
|
+
}
|
|
572
|
+
options.onResult?.({
|
|
573
|
+
outcome: "consumed",
|
|
574
|
+
ticketKey,
|
|
575
|
+
ticketRowFound: true,
|
|
576
|
+
consumed: true,
|
|
577
|
+
expired: false,
|
|
578
|
+
expectedOrgKey,
|
|
579
|
+
ticketOrgKey,
|
|
580
|
+
});
|
|
495
581
|
return {
|
|
496
582
|
ownerEmail,
|
|
497
583
|
...(orgId ? { orgId } : {}),
|
|
@@ -23,6 +23,7 @@ export declare function getIdentityHubUrl(): string | undefined;
|
|
|
23
23
|
export declare function isIdentitySsoExplicitlyEnabled(): boolean;
|
|
24
24
|
export declare function isIdentitySsoEnabled(): boolean;
|
|
25
25
|
export declare function isDesktopSsoCanaryUserAgent(userAgent: string | undefined): boolean;
|
|
26
|
+
export declare function isDesktopSsoUserAgent(userAgent: string | undefined): boolean;
|
|
26
27
|
export declare function isCanonicalAgentNativeAppOrigin(origin: string | undefined): boolean;
|
|
27
28
|
export declare function isCanonicalIdentitySsoClientOrigin(origin: string | undefined): boolean;
|
|
28
29
|
export declare function isCanonicalAgentNativeAppRequest(host: string | undefined, forwardedProtocol: string | undefined): boolean;
|
|
@@ -19,6 +19,7 @@ import { randomBytes } from "node:crypto";
|
|
|
19
19
|
import { getDbExec, intType, isConnectionError, isPostgres, isProductionServerlessFunctionRuntime, } from "../db/client.js";
|
|
20
20
|
import { ensureTableExists } from "../db/ddl-guard.js";
|
|
21
21
|
let _initPromise;
|
|
22
|
+
const DESKTOP_SSO_USER_AGENT = /AgentNativeDesktop(?:SsoCanary)?\//i;
|
|
22
23
|
const DESKTOP_SSO_CANARY_USER_AGENT = /AgentNativeDesktopSsoCanary\//i;
|
|
23
24
|
export const CANONICAL_IDENTITY_SSO_HUB_URL = "https://dispatch.agent-native.com";
|
|
24
25
|
const CANONICAL_IDENTITY_SSO_APP_ORIGINS = new Set([
|
|
@@ -110,6 +111,9 @@ export function isIdentitySsoEnabled() {
|
|
|
110
111
|
export function isDesktopSsoCanaryUserAgent(userAgent) {
|
|
111
112
|
return DESKTOP_SSO_CANARY_USER_AGENT.test(userAgent ?? "");
|
|
112
113
|
}
|
|
114
|
+
export function isDesktopSsoUserAgent(userAgent) {
|
|
115
|
+
return DESKTOP_SSO_USER_AGENT.test(userAgent ?? "");
|
|
116
|
+
}
|
|
113
117
|
export function isCanonicalAgentNativeAppOrigin(origin) {
|
|
114
118
|
if (!origin)
|
|
115
119
|
return false;
|
|
@@ -21,7 +21,7 @@ import { getAppName } from "./app-name.js";
|
|
|
21
21
|
import { getSession, isExpectedAuthFailure, safeReturnPath } from "./auth.js";
|
|
22
22
|
import { getBetterAuth, getBetterAuthInternalAdapter, } from "./better-auth-instance.js";
|
|
23
23
|
import { createOAuthSession, getOrigin } from "./google-oauth.js";
|
|
24
|
-
import { consumeSsoState, createSsoState, CANONICAL_IDENTITY_SSO_HUB_URL, getIdentityHubUrl, identitySsoLoginButtonHtml,
|
|
24
|
+
import { consumeSsoState, createSsoState, CANONICAL_IDENTITY_SSO_HUB_URL, getIdentityHubUrl, identitySsoLoginButtonHtml, isCanonicalIdentitySsoClientRequest, isDesktopSsoUserAgent, isIdentitySsoExplicitlyEnabled, isIdentitySsoEnabled, isJtiReplayed, SSO_STATE_TTL_MS, } from "./identity-sso-store.js";
|
|
25
25
|
export { getIdentityHubUrl, identitySsoLoginButtonHtml, isIdentitySsoEnabled };
|
|
26
26
|
export const IDENTITY_SSO_PROVIDER_ID = "agent-native";
|
|
27
27
|
export const IDENTITY_SSO_SCOPE = "identity";
|
|
@@ -164,11 +164,11 @@ export function resolveIdentityHubUrl(event) {
|
|
|
164
164
|
if (isCanonicalIdentitySsoClientRequest(getHeader(event, "host"), getHeader(event, "x-forwarded-proto"))) {
|
|
165
165
|
return CANONICAL_IDENTITY_SSO_HUB_URL;
|
|
166
166
|
}
|
|
167
|
-
if (!
|
|
167
|
+
if (!isDesktopSsoUserAgent(getHeader(event, "user-agent"))) {
|
|
168
168
|
return undefined;
|
|
169
169
|
}
|
|
170
170
|
try {
|
|
171
|
-
if (!
|
|
171
|
+
if (!isCanonicalIdentitySsoClientRequest(getHeader(event, "host"), getHeader(event, "x-forwarded-proto"))) {
|
|
172
172
|
return undefined;
|
|
173
173
|
}
|
|
174
174
|
return CANONICAL_IDENTITY_SSO_HUB_URL;
|
|
@@ -26,8 +26,8 @@ export declare function createRealtimeTokenHandler(): import("h3").EventHandlerW
|
|
|
26
26
|
expiresAt?: undefined;
|
|
27
27
|
ttlSeconds?: undefined;
|
|
28
28
|
} | {
|
|
29
|
-
error?: undefined;
|
|
30
29
|
token: string;
|
|
31
30
|
expiresAt: string;
|
|
32
31
|
ttlSeconds: number;
|
|
32
|
+
error?: undefined;
|
|
33
33
|
}>>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-native/core",
|
|
3
|
-
"version": "0.157.
|
|
3
|
+
"version": "0.157.23",
|
|
4
4
|
"description": "Framework for agent-native application development — where AI agents and UI share SQL state, actions, and context",
|
|
5
5
|
"homepage": "https://github.com/BuilderIO/agent-native#readme",
|
|
6
6
|
"bugs": {
|