@stackframe/stack 2.8.36 → 2.8.40
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/CHANGELOG.md +40 -0
- package/dist/components/user-button.js +2 -2
- package/dist/components/user-button.js.map +1 -1
- package/dist/esm/components/user-button.js +2 -2
- package/dist/esm/components/user-button.js.map +1 -1
- package/dist/esm/index.js +3 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/integrations/convex.js +18 -0
- package/dist/esm/integrations/convex.js.map +1 -0
- package/dist/esm/lib/stack-app/apps/implementations/admin-app-impl.js +59 -6
- package/dist/esm/lib/stack-app/apps/implementations/admin-app-impl.js.map +1 -1
- package/dist/esm/lib/stack-app/apps/implementations/client-app-impl.js +140 -3
- package/dist/esm/lib/stack-app/apps/implementations/client-app-impl.js.map +1 -1
- package/dist/esm/lib/stack-app/apps/implementations/common.js +7 -7
- package/dist/esm/lib/stack-app/apps/implementations/common.js.map +1 -1
- package/dist/esm/lib/stack-app/apps/implementations/server-app-impl.js +112 -4
- package/dist/esm/lib/stack-app/apps/implementations/server-app-impl.js.map +1 -1
- package/dist/esm/lib/stack-app/apps/interfaces/admin-app.js.map +1 -1
- package/dist/esm/lib/stack-app/apps/interfaces/client-app.js.map +1 -1
- package/dist/esm/lib/stack-app/apps/interfaces/server-app.js.map +1 -1
- package/dist/esm/lib/stack-app/common.js.map +1 -1
- package/dist/esm/lib/stack-app/index.js.map +1 -1
- package/dist/esm/lib/stack-app/users/index.js.map +1 -1
- package/dist/esm/providers/stack-provider-client.js.map +1 -1
- package/dist/index.d.mts +200 -43
- package/dist/index.d.ts +200 -43
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/integrations/convex.js +43 -0
- package/dist/integrations/convex.js.map +1 -0
- package/dist/lib/stack-app/apps/implementations/admin-app-impl.js +58 -5
- package/dist/lib/stack-app/apps/implementations/admin-app-impl.js.map +1 -1
- package/dist/lib/stack-app/apps/implementations/client-app-impl.js +140 -3
- package/dist/lib/stack-app/apps/implementations/client-app-impl.js.map +1 -1
- package/dist/lib/stack-app/apps/implementations/common.js +7 -7
- package/dist/lib/stack-app/apps/implementations/common.js.map +1 -1
- package/dist/lib/stack-app/apps/implementations/server-app-impl.js +111 -3
- package/dist/lib/stack-app/apps/implementations/server-app-impl.js.map +1 -1
- package/dist/lib/stack-app/apps/interfaces/admin-app.js.map +1 -1
- package/dist/lib/stack-app/apps/interfaces/client-app.js.map +1 -1
- package/dist/lib/stack-app/apps/interfaces/server-app.js.map +1 -1
- package/dist/lib/stack-app/common.js.map +1 -1
- package/dist/lib/stack-app/email/index.js.map +1 -1
- package/dist/lib/stack-app/index.js.map +1 -1
- package/dist/lib/stack-app/project-configs/index.js.map +1 -1
- package/dist/lib/stack-app/users/index.js.map +1 -1
- package/dist/providers/stack-provider-client.js.map +1 -1
- package/package.json +6 -5
|
@@ -128,6 +128,11 @@ var __StackClientAppImplIncomplete = class __StackClientAppImplIncomplete {
|
|
|
128
128
|
return results;
|
|
129
129
|
}
|
|
130
130
|
);
|
|
131
|
+
this._currentUserOAuthProvidersCache = createCacheBySession(
|
|
132
|
+
async (session) => {
|
|
133
|
+
return await this._interface.listOAuthProviders({ user_id: "me" }, session);
|
|
134
|
+
}
|
|
135
|
+
);
|
|
131
136
|
this._userItemCache = createCacheBySession(
|
|
132
137
|
async (session, [userId, itemId]) => {
|
|
133
138
|
return await this._interface.getItem({ userId, itemId }, session);
|
|
@@ -143,6 +148,9 @@ var __StackClientAppImplIncomplete = class __StackClientAppImplIncomplete {
|
|
|
143
148
|
return await this._interface.getItem({ customCustomerId, itemId }, session);
|
|
144
149
|
}
|
|
145
150
|
);
|
|
151
|
+
this._convexPartialUserCache = createCache(
|
|
152
|
+
async ([ctx]) => await this._getPartialUserFromConvex(ctx)
|
|
153
|
+
);
|
|
146
154
|
this._anonymousSignUpInProgress = null;
|
|
147
155
|
this._memoryTokenStore = createEmptyTokenStore();
|
|
148
156
|
this._nextServerCookiesTokenStores = /* @__PURE__ */ new WeakMap();
|
|
@@ -432,7 +440,8 @@ var __StackClientAppImplIncomplete = class __StackClientAppImplIncomplete {
|
|
|
432
440
|
}
|
|
433
441
|
async _getSession(overrideTokenStoreInit) {
|
|
434
442
|
const tokenStore = this._getOrCreateTokenStore(await this._createCookieHelper(), overrideTokenStoreInit);
|
|
435
|
-
|
|
443
|
+
const session = this._getSessionFromTokenStore(tokenStore);
|
|
444
|
+
return session;
|
|
436
445
|
}
|
|
437
446
|
_useSession(overrideTokenStoreInit) {
|
|
438
447
|
const tokenStore = this._useTokenStore(overrideTokenStoreInit);
|
|
@@ -653,6 +662,41 @@ var __StackClientAppImplIncomplete = class __StackClientAppImplIncomplete {
|
|
|
653
662
|
}
|
|
654
663
|
};
|
|
655
664
|
}
|
|
665
|
+
_clientOAuthProviderFromCrud(crud, session) {
|
|
666
|
+
const app = this;
|
|
667
|
+
return {
|
|
668
|
+
id: crud.id,
|
|
669
|
+
type: crud.type,
|
|
670
|
+
userId: crud.user_id,
|
|
671
|
+
email: crud.email,
|
|
672
|
+
allowSignIn: crud.allow_sign_in,
|
|
673
|
+
allowConnectedAccounts: crud.allow_connected_accounts,
|
|
674
|
+
async update(data) {
|
|
675
|
+
try {
|
|
676
|
+
await app._interface.updateOAuthProvider(
|
|
677
|
+
crud.user_id,
|
|
678
|
+
crud.id,
|
|
679
|
+
{
|
|
680
|
+
allow_sign_in: data.allowSignIn,
|
|
681
|
+
allow_connected_accounts: data.allowConnectedAccounts
|
|
682
|
+
},
|
|
683
|
+
session
|
|
684
|
+
);
|
|
685
|
+
await app._currentUserOAuthProvidersCache.refresh([session]);
|
|
686
|
+
return Result.ok(void 0);
|
|
687
|
+
} catch (error) {
|
|
688
|
+
if (KnownErrors.OAuthProviderAccountIdAlreadyUsedForSignIn.isInstance(error)) {
|
|
689
|
+
return Result.error(error);
|
|
690
|
+
}
|
|
691
|
+
throw error;
|
|
692
|
+
}
|
|
693
|
+
},
|
|
694
|
+
async delete() {
|
|
695
|
+
await app._interface.deleteOAuthProvider(crud.user_id, crud.id, session);
|
|
696
|
+
await app._currentUserOAuthProvidersCache.refresh([session]);
|
|
697
|
+
}
|
|
698
|
+
};
|
|
699
|
+
}
|
|
656
700
|
_clientItemFromCrud(crud) {
|
|
657
701
|
const app = this;
|
|
658
702
|
return {
|
|
@@ -944,6 +988,22 @@ var __StackClientAppImplIncomplete = class __StackClientAppImplIncomplete {
|
|
|
944
988
|
);
|
|
945
989
|
await app._userApiKeysCache.refresh([session]);
|
|
946
990
|
return app._clientApiKeyFromCrud(session, result);
|
|
991
|
+
},
|
|
992
|
+
useOAuthProviders() {
|
|
993
|
+
const results = useAsyncCache(app._currentUserOAuthProvidersCache, [session], "user.useOAuthProviders()");
|
|
994
|
+
return results.map((crud2) => app._clientOAuthProviderFromCrud(crud2, session));
|
|
995
|
+
},
|
|
996
|
+
async listOAuthProviders() {
|
|
997
|
+
const results = Result.orThrow(await app._currentUserOAuthProvidersCache.getOrWait([session], "write-only"));
|
|
998
|
+
return results.map((crud2) => app._clientOAuthProviderFromCrud(crud2, session));
|
|
999
|
+
},
|
|
1000
|
+
useOAuthProvider(id) {
|
|
1001
|
+
const providers = this.useOAuthProviders();
|
|
1002
|
+
return useMemo(() => providers.find((p) => p.id === id) ?? null, [providers, id]);
|
|
1003
|
+
},
|
|
1004
|
+
async getOAuthProvider(id) {
|
|
1005
|
+
const providers = await this.listOAuthProviders();
|
|
1006
|
+
return providers.find((p) => p.id === id) ?? null;
|
|
947
1007
|
}
|
|
948
1008
|
};
|
|
949
1009
|
}
|
|
@@ -1272,12 +1332,89 @@ var __StackClientAppImplIncomplete = class __StackClientAppImplIncomplete {
|
|
|
1272
1332
|
return crud && this._currentUserFromCrud(crud, session);
|
|
1273
1333
|
}, [crud, session, options?.or]);
|
|
1274
1334
|
}
|
|
1335
|
+
_getTokenPartialUserFromSession(session, options) {
|
|
1336
|
+
const accessToken = session.getAccessTokenIfNotExpiredYet(0);
|
|
1337
|
+
if (!accessToken) {
|
|
1338
|
+
return null;
|
|
1339
|
+
}
|
|
1340
|
+
const isAnonymous = accessToken.payload.is_anonymous;
|
|
1341
|
+
if (isAnonymous && options.or !== "anonymous") {
|
|
1342
|
+
return null;
|
|
1343
|
+
}
|
|
1344
|
+
return {
|
|
1345
|
+
id: accessToken.payload.sub,
|
|
1346
|
+
primaryEmail: accessToken.payload.email,
|
|
1347
|
+
displayName: accessToken.payload.name,
|
|
1348
|
+
primaryEmailVerified: accessToken.payload.email_verified,
|
|
1349
|
+
isAnonymous
|
|
1350
|
+
};
|
|
1351
|
+
}
|
|
1352
|
+
async _getPartialUserFromConvex(ctx) {
|
|
1353
|
+
const auth = await ctx.auth.getUserIdentity();
|
|
1354
|
+
if (!auth) {
|
|
1355
|
+
return null;
|
|
1356
|
+
}
|
|
1357
|
+
return {
|
|
1358
|
+
id: auth.subject,
|
|
1359
|
+
displayName: auth.name ?? null,
|
|
1360
|
+
primaryEmail: auth.email ?? null,
|
|
1361
|
+
primaryEmailVerified: auth.email_verified,
|
|
1362
|
+
isAnonymous: auth.is_anonymous
|
|
1363
|
+
};
|
|
1364
|
+
}
|
|
1365
|
+
async getPartialUser(options) {
|
|
1366
|
+
switch (options.from) {
|
|
1367
|
+
case "token": {
|
|
1368
|
+
this._ensurePersistentTokenStore(options.tokenStore ?? this._tokenStoreInit);
|
|
1369
|
+
const session = await this._getSession(options.tokenStore);
|
|
1370
|
+
return this._getTokenPartialUserFromSession(session, options);
|
|
1371
|
+
}
|
|
1372
|
+
case "convex": {
|
|
1373
|
+
return await this._getPartialUserFromConvex(options.ctx);
|
|
1374
|
+
}
|
|
1375
|
+
default: {
|
|
1376
|
+
throw new Error(`Invalid 'from' option: ${options.from}`);
|
|
1377
|
+
}
|
|
1378
|
+
}
|
|
1379
|
+
}
|
|
1380
|
+
usePartialUser(options) {
|
|
1381
|
+
switch (options.from) {
|
|
1382
|
+
case "token": {
|
|
1383
|
+
this._ensurePersistentTokenStore(options.tokenStore ?? this._tokenStoreInit);
|
|
1384
|
+
const session = this._useSession(options.tokenStore);
|
|
1385
|
+
return this._getTokenPartialUserFromSession(session, options);
|
|
1386
|
+
}
|
|
1387
|
+
case "convex": {
|
|
1388
|
+
const result = useAsyncCache(this._convexPartialUserCache, [options.ctx], "usePartialUser(convex)");
|
|
1389
|
+
return result;
|
|
1390
|
+
}
|
|
1391
|
+
default: {
|
|
1392
|
+
throw new Error(`Invalid 'from' option: ${options.from}`);
|
|
1393
|
+
}
|
|
1394
|
+
}
|
|
1395
|
+
}
|
|
1396
|
+
getConvexClientAuth(options) {
|
|
1397
|
+
return async (args) => {
|
|
1398
|
+
const session = await this._getSession(options.tokenStore);
|
|
1399
|
+
if (!args.forceRefreshToken) {
|
|
1400
|
+
const tokens2 = await session.getOrFetchLikelyValidTokens(2e4);
|
|
1401
|
+
return tokens2?.accessToken.token ?? null;
|
|
1402
|
+
}
|
|
1403
|
+
const tokens = await session.fetchNewTokens();
|
|
1404
|
+
return tokens?.accessToken.token ?? null;
|
|
1405
|
+
};
|
|
1406
|
+
}
|
|
1407
|
+
async getConvexHttpClientAuth(options) {
|
|
1408
|
+
const session = await this._getSession(options.tokenStore);
|
|
1409
|
+
const tokens = await session.getOrFetchLikelyValidTokens(2e4);
|
|
1410
|
+
return tokens?.accessToken.token ?? throwErr("No access token available");
|
|
1411
|
+
}
|
|
1275
1412
|
async _updateClientUser(update, session) {
|
|
1276
1413
|
const res = await this._interface.updateClientUser(userUpdateOptionsToCrud(update), session);
|
|
1277
1414
|
await this._refreshUser(session);
|
|
1278
1415
|
return res;
|
|
1279
1416
|
}
|
|
1280
|
-
async signInWithOAuth(provider) {
|
|
1417
|
+
async signInWithOAuth(provider, options) {
|
|
1281
1418
|
if (typeof window === "undefined") {
|
|
1282
1419
|
throw new Error("signInWithOAuth can currently only be called in a browser environment");
|
|
1283
1420
|
}
|
|
@@ -1287,7 +1424,7 @@ var __StackClientAppImplIncomplete = class __StackClientAppImplIncomplete {
|
|
|
1287
1424
|
this._interface,
|
|
1288
1425
|
{
|
|
1289
1426
|
provider,
|
|
1290
|
-
redirectUrl: this.urls.oauthCallback,
|
|
1427
|
+
redirectUrl: options?.returnTo ?? this.urls.oauthCallback,
|
|
1291
1428
|
errorRedirectUrl: this.urls.error,
|
|
1292
1429
|
providerScope: this._oauthScopesOnSignIn[provider]?.join(" ")
|
|
1293
1430
|
},
|