@ankhorage/studio 0.11.10 → 0.11.11
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/host/layout/templates/auth/callback.d.ts.map +1 -1
- package/dist/host/layout/templates/auth/callback.js +11 -1
- package/dist/host/layout/templates/auth/callback.js.map +1 -1
- package/dist/host/layout/templates/auth/oauth.d.ts.map +1 -1
- package/dist/host/layout/templates/auth/oauth.js +65 -26
- package/dist/host/layout/templates/auth/oauth.js.map +1 -1
- package/dist/host/orchestrator/templates.js +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"callback.d.ts","sourceRoot":"","sources":["../../../../../src/host/layout/templates/auth/callback.ts"],"names":[],"mappings":"AAGA,wBAAgB,uBAAuB,CAAC,IAAI,EAAE;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAA;CAAE,
|
|
1
|
+
{"version":3,"file":"callback.d.ts","sourceRoot":"","sources":["../../../../../src/host/layout/templates/auth/callback.ts"],"names":[],"mappings":"AAGA,wBAAgB,uBAAuB,CAAC,IAAI,EAAE;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAA;CAAE,UA4I7F"}
|
|
@@ -24,10 +24,20 @@ let activeCallbackCompletion: ActiveCallbackCompletion | null = null;
|
|
|
24
24
|
|
|
25
25
|
function completeOAuthCallbackOnce(callbackUrl: string) {
|
|
26
26
|
if (!activeCallbackCompletion || activeCallbackCompletion.callbackUrl !== callbackUrl) {
|
|
27
|
-
|
|
27
|
+
const completion: ActiveCallbackCompletion = {
|
|
28
28
|
callbackUrl,
|
|
29
29
|
promise: completeOAuthCallback(callbackUrl),
|
|
30
30
|
};
|
|
31
|
+
activeCallbackCompletion = completion;
|
|
32
|
+
void completion.promise
|
|
33
|
+
.finally(() => {
|
|
34
|
+
if (activeCallbackCompletion === completion) {
|
|
35
|
+
activeCallbackCompletion = null;
|
|
36
|
+
}
|
|
37
|
+
})
|
|
38
|
+
.catch(() => {
|
|
39
|
+
// The original promise remains the callback screen's error boundary.
|
|
40
|
+
});
|
|
31
41
|
}
|
|
32
42
|
return activeCallbackCompletion.promise;
|
|
33
43
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"callback.js","sourceRoot":"","sources":["../../../../../src/host/layout/templates/auth/callback.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAEzD,MAAM,UAAU,uBAAuB,CAAC,IAAsD;IAC5F,MAAM,YAAY,GAAG,mBAAmB,CAAC,sBAAsB,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC;IAC3F,MAAM,gBAAgB,GAAG,mBAAmB,CAAC,sBAAsB,CAAC,IAAI,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC,CAAC;IAElG,OAAO;;;;;;;;yBAQgB,YAAY;8BACP,gBAAgB
|
|
1
|
+
{"version":3,"file":"callback.js","sourceRoot":"","sources":["../../../../../src/host/layout/templates/auth/callback.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAEzD,MAAM,UAAU,uBAAuB,CAAC,IAAsD;IAC5F,MAAM,YAAY,GAAG,mBAAmB,CAAC,sBAAsB,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC;IAC3F,MAAM,gBAAgB,GAAG,mBAAmB,CAAC,sBAAsB,CAAC,IAAI,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC,CAAC;IAElG,OAAO;;;;;;;;yBAQgB,YAAY;8BACP,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8H7C,CAAC;AACF,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../../../../../src/host/layout/templates/auth/oauth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAG5E,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,mBAAmB,
|
|
1
|
+
{"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../../../../../src/host/layout/templates/auth/oauth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAG5E,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,mBAAmB,UA2W9D"}
|
|
@@ -4,7 +4,6 @@ export function getAuthOAuthRuntimeTs(args) {
|
|
|
4
4
|
const providers = JSON.stringify(args.providers);
|
|
5
5
|
return `import type {
|
|
6
6
|
AuthOAuthCompletionResult,
|
|
7
|
-
AuthOAuthProviderId,
|
|
8
7
|
AuthOAuthTransportCancellationReason,
|
|
9
8
|
} from '@ankhorage/contracts/auth';
|
|
10
9
|
import * as Linking from 'expo-linking';
|
|
@@ -18,7 +17,8 @@ import {
|
|
|
18
17
|
} from './session';
|
|
19
18
|
|
|
20
19
|
const OAUTH_CALLBACK_ROUTE = '${callbackRoute}';
|
|
21
|
-
const OAUTH_TRANSPORT_ATTEMPT_KEY = 'ankh.auth.oauth.transport.
|
|
20
|
+
const OAUTH_TRANSPORT_ATTEMPT_KEY = 'ankh.auth.oauth.transport.v2';
|
|
21
|
+
const LEGACY_OAUTH_TRANSPORT_ATTEMPT_KEY = 'ankh.auth.oauth.transport.v1';
|
|
22
22
|
const GENERATED_OAUTH_PROVIDERS = ${providers} as const;
|
|
23
23
|
|
|
24
24
|
export const generatedOAuthProviderItems = GENERATED_OAUTH_PROVIDERS.map((provider) => ({
|
|
@@ -33,9 +33,8 @@ export type GeneratedOAuthTransportOutcome =
|
|
|
33
33
|
| { status: 'error'; message: string; recoverable: boolean };
|
|
34
34
|
|
|
35
35
|
interface StoredTransportAttempt {
|
|
36
|
+
version: 1;
|
|
36
37
|
attemptId: string;
|
|
37
|
-
provider: AuthOAuthProviderId;
|
|
38
|
-
redirectUri: string;
|
|
39
38
|
}
|
|
40
39
|
|
|
41
40
|
let activeAuthorization: Promise<GeneratedOAuthTransportOutcome> | null = null;
|
|
@@ -97,9 +96,8 @@ async function runOAuthAuthorization(
|
|
|
97
96
|
|
|
98
97
|
try {
|
|
99
98
|
await writeTransportAttempt({
|
|
99
|
+
version: 1,
|
|
100
100
|
attemptId: started.data.attemptId,
|
|
101
|
-
provider: started.data.provider,
|
|
102
|
-
redirectUri: started.data.redirectUri,
|
|
103
101
|
});
|
|
104
102
|
} catch {
|
|
105
103
|
await cancelOAuthAttempt(started.data.attemptId, 'user_cancelled');
|
|
@@ -198,6 +196,9 @@ export async function completeOAuthCallback(
|
|
|
198
196
|
|
|
199
197
|
const attempt = await readTransportAttempt();
|
|
200
198
|
if (!attempt) {
|
|
199
|
+
if (getStoredAuthSession() && isCanonicalOAuthCallback(callbackUrl)) {
|
|
200
|
+
return { status: 'authenticated' };
|
|
201
|
+
}
|
|
201
202
|
return {
|
|
202
203
|
status: 'error',
|
|
203
204
|
message: 'The OAuth authorization attempt was not found or has expired.',
|
|
@@ -205,10 +206,20 @@ export async function completeOAuthCallback(
|
|
|
205
206
|
};
|
|
206
207
|
}
|
|
207
208
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
209
|
+
let completed: AuthOAuthCompletionResult;
|
|
210
|
+
try {
|
|
211
|
+
completed = await oauth.completeAuthorization({
|
|
212
|
+
attemptId: attempt.attemptId,
|
|
213
|
+
response: { type: 'callback', url: callbackUrl },
|
|
214
|
+
});
|
|
215
|
+
} catch {
|
|
216
|
+
await clearTransportAttempt();
|
|
217
|
+
return {
|
|
218
|
+
status: 'error',
|
|
219
|
+
message: 'The OAuth callback could not be completed.',
|
|
220
|
+
recoverable: true,
|
|
221
|
+
};
|
|
222
|
+
}
|
|
212
223
|
await clearTransportAttempt();
|
|
213
224
|
|
|
214
225
|
if (
|
|
@@ -240,6 +251,23 @@ function resolveOAuthRedirectUri(): string {
|
|
|
240
251
|
return Linking.createURL(callbackPath);
|
|
241
252
|
}
|
|
242
253
|
|
|
254
|
+
function isCanonicalOAuthCallback(callbackUrl: string): boolean {
|
|
255
|
+
try {
|
|
256
|
+
const delivered = new URL(callbackUrl);
|
|
257
|
+
const expected = new URL(resolveOAuthRedirectUri());
|
|
258
|
+
return (
|
|
259
|
+
delivered.protocol === expected.protocol &&
|
|
260
|
+
delivered.username === expected.username &&
|
|
261
|
+
delivered.password === expected.password &&
|
|
262
|
+
delivered.host === expected.host &&
|
|
263
|
+
delivered.pathname === expected.pathname &&
|
|
264
|
+
delivered.hash.length === 0
|
|
265
|
+
);
|
|
266
|
+
} catch {
|
|
267
|
+
return false;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
243
271
|
function getBrowserLocation(): object | null {
|
|
244
272
|
const location = Reflect.get(globalThis, 'location');
|
|
245
273
|
return typeof location === 'object' && location !== null ? location : null;
|
|
@@ -284,35 +312,46 @@ async function cancelOAuthAttempt(
|
|
|
284
312
|
}
|
|
285
313
|
|
|
286
314
|
async function writeTransportAttempt(attempt: StoredTransportAttempt): Promise<void> {
|
|
315
|
+
await clearLegacyTransportAttempt();
|
|
287
316
|
await authSessionStorage.setItem(OAUTH_TRANSPORT_ATTEMPT_KEY, JSON.stringify(attempt));
|
|
288
317
|
}
|
|
289
318
|
|
|
290
319
|
async function readTransportAttempt(): Promise<StoredTransportAttempt | null> {
|
|
291
320
|
const raw = await authSessionStorage.getItem(OAUTH_TRANSPORT_ATTEMPT_KEY);
|
|
292
|
-
if (!raw)
|
|
321
|
+
if (!raw) {
|
|
322
|
+
await clearLegacyTransportAttempt();
|
|
323
|
+
return null;
|
|
324
|
+
}
|
|
293
325
|
try {
|
|
294
326
|
const value: unknown = JSON.parse(raw);
|
|
295
|
-
if (
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
: undefined;
|
|
303
|
-
return typeof attemptId === 'string' &&
|
|
304
|
-
configuredProvider !== undefined &&
|
|
305
|
-
typeof redirectUri === 'string'
|
|
306
|
-
? { attemptId, provider: configuredProvider.id, redirectUri }
|
|
307
|
-
: null;
|
|
327
|
+
if (isRecord(value)) {
|
|
328
|
+
const version = Reflect.get(value, 'version');
|
|
329
|
+
const attemptId = Reflect.get(value, 'attemptId');
|
|
330
|
+
if (version === 1 && typeof attemptId === 'string' && attemptId.trim().length > 0) {
|
|
331
|
+
return { version, attemptId };
|
|
332
|
+
}
|
|
333
|
+
}
|
|
308
334
|
} catch {
|
|
309
|
-
|
|
335
|
+
// Invalid transport state is cleaned below without exposing its contents.
|
|
310
336
|
}
|
|
337
|
+
await clearTransportAttempt();
|
|
338
|
+
return null;
|
|
311
339
|
}
|
|
312
340
|
|
|
313
341
|
async function clearTransportAttempt(): Promise<void> {
|
|
342
|
+
await Promise.all([
|
|
343
|
+
safeRemoveTransportItem(OAUTH_TRANSPORT_ATTEMPT_KEY),
|
|
344
|
+
safeRemoveTransportItem(LEGACY_OAUTH_TRANSPORT_ATTEMPT_KEY),
|
|
345
|
+
]);
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
async function clearLegacyTransportAttempt(): Promise<void> {
|
|
349
|
+
await safeRemoveTransportItem(LEGACY_OAUTH_TRANSPORT_ATTEMPT_KEY);
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
async function safeRemoveTransportItem(key: string): Promise<void> {
|
|
314
353
|
try {
|
|
315
|
-
await authSessionStorage.removeItem(
|
|
354
|
+
await authSessionStorage.removeItem(key);
|
|
316
355
|
} catch {
|
|
317
356
|
// Cleanup failures are intentionally not surfaced with persisted state.
|
|
318
357
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oauth.js","sourceRoot":"","sources":["../../../../../src/host/layout/templates/auth/oauth.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAEtE,MAAM,UAAU,qBAAqB,CAAC,IAAyB;IAC7D,MAAM,aAAa,GAAG,mBAAmB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAC9D,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAEjD,OAAO
|
|
1
|
+
{"version":3,"file":"oauth.js","sourceRoot":"","sources":["../../../../../src/host/layout/templates/auth/oauth.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAEtE,MAAM,UAAU,qBAAqB,CAAC,IAAyB;IAC7D,MAAM,aAAa,GAAG,mBAAmB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAC9D,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAEjD,OAAO;;;;;;;;;;;;;;gCAcuB,aAAa;;;oCAGT,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqV5C,CAAC;AACF,CAAC"}
|
|
@@ -3,7 +3,7 @@ import { EXPO_SDK_54_ANIMATION_COMPATIBILITY } from './expoSdk54AnimationCompati
|
|
|
3
3
|
const EXPO_MODULES_CORE_VERSION = '~3.0.30';
|
|
4
4
|
const CONTRACTS_VERSION = '^4.0.0';
|
|
5
5
|
const RUNTIME_VERSION = '^0.3.0';
|
|
6
|
-
const SUPABASE_AUTH_VERSION = '^1.
|
|
6
|
+
const SUPABASE_AUTH_VERSION = '^1.1.2';
|
|
7
7
|
const ZORA_VERSION = '^2.9.0';
|
|
8
8
|
const EXPO_SECURE_STORE_VERSION = '~15.0.8';
|
|
9
9
|
const EXPO_WEB_BROWSER_VERSION = '~15.0.11';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ankhorage/studio",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.11",
|
|
4
4
|
"description": "Studio authoring package for Ankhorage apps",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://github.com/ankhorage/studio#readme",
|
|
@@ -237,7 +237,7 @@
|
|
|
237
237
|
"@ankhorage/orchestrator-module-expo-localization": "^0.1.5",
|
|
238
238
|
"@ankhorage/react-native-reanimated-dnd-web": "^0.3.2",
|
|
239
239
|
"@ankhorage/runtime": "^0.3.0",
|
|
240
|
-
"@ankhorage/supabase-auth": "^1.1.
|
|
240
|
+
"@ankhorage/supabase-auth": "^1.1.2",
|
|
241
241
|
"@ankhorage/supabase-vault": "^0.2.4",
|
|
242
242
|
"@ankhorage/templates": "^3.0.0",
|
|
243
243
|
"@ankhorage/zora": "^2.9.1",
|