@stackframe/stack-shared 2.5.29 → 2.5.31

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 CHANGED
@@ -1,5 +1,19 @@
1
1
  # @stackframe/stack-shared
2
2
 
3
+ ## 2.5.31
4
+
5
+ ### Patch Changes
6
+
7
+ - JWKS
8
+ - @stackframe/stack-sc@2.5.31
9
+
10
+ ## 2.5.30
11
+
12
+ ### Patch Changes
13
+
14
+ - More OAuth providers
15
+ - @stackframe/stack-sc@2.5.30
16
+
3
17
  ## 2.5.29
4
18
 
5
19
  ### Patch Changes
@@ -17,12 +17,13 @@ export declare const projectsCrudAdminReadSchema: import("yup").ObjectSchema<{
17
17
  client_id?: string | undefined;
18
18
  client_secret?: string | undefined;
19
19
  facebook_config_id?: string | undefined;
20
+ microsoft_tenant_id?: string | undefined;
20
21
  type: NonNullable<"shared" | "standard" | undefined>;
21
- id: NonNullable<"google" | "github" | "facebook" | "microsoft" | "spotify" | "discord" | "gitlab" | undefined>;
22
+ id: NonNullable<"google" | "github" | "facebook" | "microsoft" | "spotify" | "discord" | "gitlab" | "bitbucket" | undefined>;
22
23
  enabled: NonNullable<boolean | undefined>;
23
24
  }[];
24
25
  enabled_oauth_providers: {
25
- id: NonNullable<"google" | "github" | "facebook" | "microsoft" | "spotify" | "discord" | "gitlab" | undefined>;
26
+ id: NonNullable<"google" | "github" | "facebook" | "microsoft" | "spotify" | "discord" | "gitlab" | "bitbucket" | undefined>;
26
27
  }[];
27
28
  domains: {
28
29
  domain: string;
@@ -85,7 +86,7 @@ export declare const projectsCrudClientReadSchema: import("yup").ObjectSchema<{
85
86
  magic_link_enabled: NonNullable<boolean | undefined>;
86
87
  client_team_creation_enabled: NonNullable<boolean | undefined>;
87
88
  enabled_oauth_providers: {
88
- id: NonNullable<"google" | "github" | "facebook" | "microsoft" | "spotify" | "discord" | "gitlab" | undefined>;
89
+ id: NonNullable<"google" | "github" | "facebook" | "microsoft" | "spotify" | "discord" | "gitlab" | "bitbucket" | undefined>;
89
90
  }[];
90
91
  };
91
92
  }, import("yup").AnyObject, {
@@ -113,8 +114,9 @@ export declare const projectsCrudAdminUpdateSchema: import("yup").ObjectSchema<{
113
114
  client_id?: string | undefined;
114
115
  client_secret?: string | undefined;
115
116
  facebook_config_id?: string | undefined;
117
+ microsoft_tenant_id?: string | undefined;
116
118
  type: NonNullable<"shared" | "standard" | undefined>;
117
- id: NonNullable<"google" | "github" | "facebook" | "microsoft" | "spotify" | "discord" | "gitlab" | undefined>;
119
+ id: NonNullable<"google" | "github" | "facebook" | "microsoft" | "spotify" | "discord" | "gitlab" | "bitbucket" | undefined>;
118
120
  enabled: NonNullable<boolean | undefined>;
119
121
  }[] | undefined;
120
122
  domains?: {
@@ -158,8 +160,9 @@ export declare const projectsCrudAdminCreateSchema: import("yup").ObjectSchema<{
158
160
  client_id?: string | undefined;
159
161
  client_secret?: string | undefined;
160
162
  facebook_config_id?: string | undefined;
163
+ microsoft_tenant_id?: string | undefined;
161
164
  type: NonNullable<"shared" | "standard" | undefined>;
162
- id: NonNullable<"google" | "github" | "facebook" | "microsoft" | "spotify" | "discord" | "gitlab" | undefined>;
165
+ id: NonNullable<"google" | "github" | "facebook" | "microsoft" | "spotify" | "discord" | "gitlab" | "bitbucket" | undefined>;
163
166
  enabled: NonNullable<boolean | undefined>;
164
167
  }[] | undefined;
165
168
  domains?: {
@@ -202,7 +205,7 @@ export declare const projectsCrud: import("../../crud").CrudSchemaFromOptions<{
202
205
  magic_link_enabled: NonNullable<boolean | undefined>;
203
206
  client_team_creation_enabled: NonNullable<boolean | undefined>;
204
207
  enabled_oauth_providers: {
205
- id: NonNullable<"google" | "github" | "facebook" | "microsoft" | "spotify" | "discord" | "gitlab" | undefined>;
208
+ id: NonNullable<"google" | "github" | "facebook" | "microsoft" | "spotify" | "discord" | "gitlab" | "bitbucket" | undefined>;
206
209
  }[];
207
210
  };
208
211
  }, import("yup").AnyObject, {
@@ -234,12 +237,13 @@ export declare const projectsCrud: import("../../crud").CrudSchemaFromOptions<{
234
237
  client_id?: string | undefined;
235
238
  client_secret?: string | undefined;
236
239
  facebook_config_id?: string | undefined;
240
+ microsoft_tenant_id?: string | undefined;
237
241
  type: NonNullable<"shared" | "standard" | undefined>;
238
- id: NonNullable<"google" | "github" | "facebook" | "microsoft" | "spotify" | "discord" | "gitlab" | undefined>;
242
+ id: NonNullable<"google" | "github" | "facebook" | "microsoft" | "spotify" | "discord" | "gitlab" | "bitbucket" | undefined>;
239
243
  enabled: NonNullable<boolean | undefined>;
240
244
  }[];
241
245
  enabled_oauth_providers: {
242
- id: NonNullable<"google" | "github" | "facebook" | "microsoft" | "spotify" | "discord" | "gitlab" | undefined>;
246
+ id: NonNullable<"google" | "github" | "facebook" | "microsoft" | "spotify" | "discord" | "gitlab" | "bitbucket" | undefined>;
243
247
  }[];
244
248
  domains: {
245
249
  domain: string;
@@ -307,8 +311,9 @@ export declare const projectsCrud: import("../../crud").CrudSchemaFromOptions<{
307
311
  client_id?: string | undefined;
308
312
  client_secret?: string | undefined;
309
313
  facebook_config_id?: string | undefined;
314
+ microsoft_tenant_id?: string | undefined;
310
315
  type: NonNullable<"shared" | "standard" | undefined>;
311
- id: NonNullable<"google" | "github" | "facebook" | "microsoft" | "spotify" | "discord" | "gitlab" | undefined>;
316
+ id: NonNullable<"google" | "github" | "facebook" | "microsoft" | "spotify" | "discord" | "gitlab" | "bitbucket" | undefined>;
312
317
  enabled: NonNullable<boolean | undefined>;
313
318
  }[] | undefined;
314
319
  domains?: {
@@ -382,12 +387,13 @@ export declare const internalProjectsCrud: import("../../crud").CrudSchemaFromOp
382
387
  client_id?: string | undefined;
383
388
  client_secret?: string | undefined;
384
389
  facebook_config_id?: string | undefined;
390
+ microsoft_tenant_id?: string | undefined;
385
391
  type: NonNullable<"shared" | "standard" | undefined>;
386
- id: NonNullable<"google" | "github" | "facebook" | "microsoft" | "spotify" | "discord" | "gitlab" | undefined>;
392
+ id: NonNullable<"google" | "github" | "facebook" | "microsoft" | "spotify" | "discord" | "gitlab" | "bitbucket" | undefined>;
387
393
  enabled: NonNullable<boolean | undefined>;
388
394
  }[];
389
395
  enabled_oauth_providers: {
390
- id: NonNullable<"google" | "github" | "facebook" | "microsoft" | "spotify" | "discord" | "gitlab" | undefined>;
396
+ id: NonNullable<"google" | "github" | "facebook" | "microsoft" | "spotify" | "discord" | "gitlab" | "bitbucket" | undefined>;
391
397
  }[];
392
398
  domains: {
393
399
  domain: string;
@@ -455,8 +461,9 @@ export declare const internalProjectsCrud: import("../../crud").CrudSchemaFromOp
455
461
  client_id?: string | undefined;
456
462
  client_secret?: string | undefined;
457
463
  facebook_config_id?: string | undefined;
464
+ microsoft_tenant_id?: string | undefined;
458
465
  type: NonNullable<"shared" | "standard" | undefined>;
459
- id: NonNullable<"google" | "github" | "facebook" | "microsoft" | "spotify" | "discord" | "gitlab" | undefined>;
466
+ id: NonNullable<"google" | "github" | "facebook" | "microsoft" | "spotify" | "discord" | "gitlab" | "bitbucket" | undefined>;
460
467
  enabled: NonNullable<boolean | undefined>;
461
468
  }[] | undefined;
462
469
  domains?: {
@@ -12,6 +12,7 @@ const oauthProviderSchema = yupObject({
12
12
  client_secret: yupRequiredWhen(schemaFields.oauthClientSecretSchema, 'type', 'standard'),
13
13
  // extra params
14
14
  facebook_config_id: yupString().optional().meta({ openapiField: { description: 'This parameter is the configuration id for Facebook business login (for things like ads and marketing).' } }),
15
+ microsoft_tenant_id: yupString().optional().meta({ openapiField: { description: 'This parameter is the Microsoft tenant id for Microsoft directory' } }),
15
16
  });
16
17
  const enabledOAuthProviderSchema = yupObject({
17
18
  id: schemaFields.oauthIdSchema.required(),
@@ -15,7 +15,7 @@ export declare const projectsCrudAdminReadSchema: import("yup").ObjectSchema<{
15
15
  client_id?: string | undefined;
16
16
  client_secret?: string | undefined;
17
17
  type: NonNullable<"shared" | "standard" | undefined>;
18
- id: NonNullable<"google" | "github" | "facebook" | "microsoft" | "spotify" | "discord" | "gitlab" | undefined>;
18
+ id: NonNullable<"google" | "github" | "facebook" | "microsoft" | "spotify" | "discord" | "gitlab" | "bitbucket" | undefined>;
19
19
  enabled: NonNullable<boolean | undefined>;
20
20
  }[];
21
21
  domains: {
@@ -72,7 +72,7 @@ export declare const projectsCrudClientReadSchema: import("yup").ObjectSchema<{
72
72
  credential_enabled: NonNullable<boolean | undefined>;
73
73
  magic_link_enabled: NonNullable<boolean | undefined>;
74
74
  oauth_providers: {
75
- id: NonNullable<"google" | "github" | "facebook" | "microsoft" | "spotify" | "discord" | "gitlab" | undefined>;
75
+ id: NonNullable<"google" | "github" | "facebook" | "microsoft" | "spotify" | "discord" | "gitlab" | "bitbucket" | undefined>;
76
76
  }[];
77
77
  };
78
78
  }, import("yup").AnyObject, {
@@ -96,7 +96,7 @@ export declare const projectsCrudAdminUpdateSchema: import("yup").ObjectSchema<{
96
96
  client_id?: string | undefined;
97
97
  client_secret?: string | undefined;
98
98
  type: NonNullable<"shared" | "standard" | undefined>;
99
- id: NonNullable<"google" | "github" | "facebook" | "microsoft" | "spotify" | "discord" | "gitlab" | undefined>;
99
+ id: NonNullable<"google" | "github" | "facebook" | "microsoft" | "spotify" | "discord" | "gitlab" | "bitbucket" | undefined>;
100
100
  enabled: NonNullable<boolean | undefined>;
101
101
  }[] | undefined;
102
102
  domains?: {
@@ -138,7 +138,7 @@ export declare const projectsCrudAdminCreateSchema: import("yup").ObjectSchema<{
138
138
  client_id?: string | undefined;
139
139
  client_secret?: string | undefined;
140
140
  type: NonNullable<"shared" | "standard" | undefined>;
141
- id: NonNullable<"google" | "github" | "facebook" | "microsoft" | "spotify" | "discord" | "gitlab" | undefined>;
141
+ id: NonNullable<"google" | "github" | "facebook" | "microsoft" | "spotify" | "discord" | "gitlab" | "bitbucket" | undefined>;
142
142
  enabled: NonNullable<boolean | undefined>;
143
143
  }[] | undefined;
144
144
  domains?: {
@@ -178,7 +178,7 @@ export declare const projectsCrud: import("../../crud").CrudSchemaFromOptions<{
178
178
  credential_enabled: NonNullable<boolean | undefined>;
179
179
  magic_link_enabled: NonNullable<boolean | undefined>;
180
180
  oauth_providers: {
181
- id: NonNullable<"google" | "github" | "facebook" | "microsoft" | "spotify" | "discord" | "gitlab" | undefined>;
181
+ id: NonNullable<"google" | "github" | "facebook" | "microsoft" | "spotify" | "discord" | "gitlab" | "bitbucket" | undefined>;
182
182
  }[];
183
183
  };
184
184
  }, import("yup").AnyObject, {
@@ -206,7 +206,7 @@ export declare const projectsCrud: import("../../crud").CrudSchemaFromOptions<{
206
206
  client_id?: string | undefined;
207
207
  client_secret?: string | undefined;
208
208
  type: NonNullable<"shared" | "standard" | undefined>;
209
- id: NonNullable<"google" | "github" | "facebook" | "microsoft" | "spotify" | "discord" | "gitlab" | undefined>;
209
+ id: NonNullable<"google" | "github" | "facebook" | "microsoft" | "spotify" | "discord" | "gitlab" | "bitbucket" | undefined>;
210
210
  enabled: NonNullable<boolean | undefined>;
211
211
  }[];
212
212
  domains: {
@@ -268,7 +268,7 @@ export declare const projectsCrud: import("../../crud").CrudSchemaFromOptions<{
268
268
  client_id?: string | undefined;
269
269
  client_secret?: string | undefined;
270
270
  type: NonNullable<"shared" | "standard" | undefined>;
271
- id: NonNullable<"google" | "github" | "facebook" | "microsoft" | "spotify" | "discord" | "gitlab" | undefined>;
271
+ id: NonNullable<"google" | "github" | "facebook" | "microsoft" | "spotify" | "discord" | "gitlab" | "bitbucket" | undefined>;
272
272
  enabled: NonNullable<boolean | undefined>;
273
273
  }[] | undefined;
274
274
  domains?: {
@@ -334,7 +334,7 @@ export declare const internalProjectsCrud: import("../../crud").CrudSchemaFromOp
334
334
  client_id?: string | undefined;
335
335
  client_secret?: string | undefined;
336
336
  type: NonNullable<"shared" | "standard" | undefined>;
337
- id: NonNullable<"google" | "github" | "facebook" | "microsoft" | "spotify" | "discord" | "gitlab" | undefined>;
337
+ id: NonNullable<"google" | "github" | "facebook" | "microsoft" | "spotify" | "discord" | "gitlab" | "bitbucket" | undefined>;
338
338
  enabled: NonNullable<boolean | undefined>;
339
339
  }[];
340
340
  domains: {
@@ -396,7 +396,7 @@ export declare const internalProjectsCrud: import("../../crud").CrudSchemaFromOp
396
396
  client_id?: string | undefined;
397
397
  client_secret?: string | undefined;
398
398
  type: NonNullable<"shared" | "standard" | undefined>;
399
- id: NonNullable<"google" | "github" | "facebook" | "microsoft" | "spotify" | "discord" | "gitlab" | undefined>;
399
+ id: NonNullable<"google" | "github" | "facebook" | "microsoft" | "spotify" | "discord" | "gitlab" | "bitbucket" | undefined>;
400
400
  enabled: NonNullable<boolean | undefined>;
401
401
  }[] | undefined;
402
402
  domains?: {
@@ -39,7 +39,7 @@ export declare const projectMagicLinkEnabledSchema: yup.BooleanSchema<boolean |
39
39
  export declare const projectClientTeamCreationEnabledSchema: yup.BooleanSchema<boolean | undefined, yup.AnyObject, undefined, "">;
40
40
  export declare const projectSignUpEnabledSchema: yup.BooleanSchema<boolean | undefined, yup.AnyObject, undefined, "">;
41
41
  export declare const projectCredentialEnabledSchema: yup.BooleanSchema<boolean | undefined, yup.AnyObject, undefined, "">;
42
- export declare const oauthIdSchema: yup.StringSchema<"google" | "github" | "facebook" | "microsoft" | "spotify" | "discord" | "gitlab" | undefined, yup.AnyObject, undefined, "">;
42
+ export declare const oauthIdSchema: yup.StringSchema<"google" | "github" | "facebook" | "microsoft" | "spotify" | "discord" | "gitlab" | "bitbucket" | undefined, yup.AnyObject, undefined, "">;
43
43
  export declare const oauthEnabledSchema: yup.BooleanSchema<boolean | undefined, yup.AnyObject, undefined, "">;
44
44
  export declare const oauthTypeSchema: yup.StringSchema<"shared" | "standard" | undefined, yup.AnyObject, undefined, "">;
45
45
  export declare const oauthClientIdSchema: yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">;
@@ -1,3 +1,21 @@
1
1
  import * as jose from "jose";
2
- export declare function encryptJWT(payload: any, expirationTime?: string): Promise<string>;
3
- export declare function decryptJWT(jwt: string): Promise<jose.JWTPayload>;
2
+ export declare function signJWT(issuer: string, payload: any, expirationTime?: string): Promise<string>;
3
+ export declare function verifyJWT(issuer: string, jwt: string): Promise<jose.JWTPayload>;
4
+ export declare function getPrivateJwk(): Promise<{
5
+ kty: string;
6
+ crv: string;
7
+ d: string;
8
+ x: string;
9
+ y: string;
10
+ }>;
11
+ export declare function getPublicJwkSet(): Promise<{
12
+ keys: Pick<{
13
+ kty: string;
14
+ crv: string;
15
+ d: string;
16
+ x: string;
17
+ y: string;
18
+ }, "kty" | "crv" | "x" | "y">[];
19
+ }>;
20
+ export declare function encryptJWE(payload: any, expirationTime?: string): Promise<string>;
21
+ export declare function decryptJWE(jwt: string): Promise<jose.JWTPayload>;
package/dist/utils/jwt.js CHANGED
@@ -1,14 +1,56 @@
1
1
  import * as jose from "jose";
2
2
  import { getEnvVariable } from "./env";
3
+ import elliptic from "elliptic";
4
+ import { globalVar } from "./globals";
5
+ import { encodeBase64 } from "./bytes";
6
+ import { pick } from "./objects";
3
7
  const STACK_SERVER_SECRET = jose.base64url.decode(getEnvVariable("STACK_SERVER_SECRET"));
4
- export async function encryptJWT(payload, expirationTime = "5m") {
8
+ export async function signJWT(issuer, payload, expirationTime = "5m") {
9
+ const privateJwk = await jose.importJWK(await getPrivateJwk());
10
+ return await new jose.SignJWT(payload)
11
+ .setProtectedHeader({ alg: "ES256" })
12
+ .setIssuer(issuer)
13
+ .setIssuedAt()
14
+ .setExpirationTime(expirationTime)
15
+ .sign(privateJwk);
16
+ }
17
+ export async function verifyJWT(issuer, jwt) {
18
+ const jwkSet = jose.createLocalJWKSet(await getPublicJwkSet());
19
+ const verified = await jose.jwtVerify(jwt, jwkSet, {
20
+ issuer,
21
+ });
22
+ return verified.payload;
23
+ }
24
+ export async function getPrivateJwk() {
25
+ const secretHash = await globalVar.crypto.subtle.digest("SHA-256", STACK_SERVER_SECRET);
26
+ const priv = new Uint8Array(secretHash);
27
+ const ec = new elliptic.ec('p256');
28
+ const key = ec.keyFromPrivate(priv);
29
+ const publicKey = key.getPublic();
30
+ return {
31
+ kty: 'EC',
32
+ crv: 'P-256',
33
+ d: encodeBase64(priv),
34
+ x: encodeBase64(publicKey.getX().toBuffer()),
35
+ y: encodeBase64(publicKey.getY().toBuffer()),
36
+ };
37
+ }
38
+ export async function getPublicJwkSet() {
39
+ const privateJwk = await getPrivateJwk();
40
+ const jwk = pick(privateJwk, ["kty", "crv", "x", "y"]);
41
+ return {
42
+ keys: [jwk]
43
+ };
44
+ }
45
+ export async function encryptJWE(payload, expirationTime = "5m") {
5
46
  return await new jose.EncryptJWT(payload)
6
47
  .setProtectedHeader({ alg: "dir", enc: "A128CBC-HS256" })
48
+ .setIssuer("stack")
7
49
  .setIssuedAt()
8
50
  .setExpirationTime(expirationTime)
9
51
  .encrypt(STACK_SERVER_SECRET);
10
52
  }
11
- export async function decryptJWT(jwt) {
53
+ export async function decryptJWE(jwt) {
12
54
  if (!jwt) {
13
55
  throw new Error("Provided JWT is empty");
14
56
  }
@@ -1,6 +1,6 @@
1
- export declare const standardProviders: readonly ["google", "github", "facebook", "microsoft", "spotify", "discord", "gitlab"];
1
+ export declare const standardProviders: readonly ["google", "github", "facebook", "microsoft", "spotify", "discord", "gitlab", "bitbucket"];
2
2
  export declare const sharedProviders: readonly ["google", "github", "facebook", "microsoft", "spotify"];
3
- export declare const allProviders: readonly ["google", "github", "facebook", "microsoft", "spotify", "discord", "gitlab"];
3
+ export declare const allProviders: readonly ["google", "github", "facebook", "microsoft", "spotify", "discord", "gitlab", "bitbucket"];
4
4
  export type ProviderType = typeof allProviders[number];
5
5
  export type StandardProviderType = typeof standardProviders[number];
6
6
  export type SharedProviderType = typeof sharedProviders[number];
@@ -1,4 +1,4 @@
1
- export const standardProviders = ["google", "github", "facebook", "microsoft", "spotify", "discord", "gitlab"];
1
+ export const standardProviders = ["google", "github", "facebook", "microsoft", "spotify", "discord", "gitlab", "bitbucket"];
2
2
  // No more shared providers should be added except for special cases
3
3
  export const sharedProviders = ["google", "github", "facebook", "microsoft", "spotify"];
4
- export const allProviders = ["google", "github", "facebook", "microsoft", "spotify", "discord", "gitlab"];
4
+ export const allProviders = ["google", "github", "facebook", "microsoft", "spotify", "discord", "gitlab", "bitbucket"];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stackframe/stack-shared",
3
- "version": "2.5.29",
3
+ "version": "2.5.31",
4
4
  "main": "./dist/index.js",
5
5
  "types": "./dist/index.d.ts",
6
6
  "files": [
@@ -33,18 +33,20 @@
33
33
  },
34
34
  "dependencies": {
35
35
  "bcrypt": "^5.1.1",
36
+ "elliptic": "^6.5.7",
36
37
  "jose": "^5.2.2",
37
38
  "oauth4webapi": "^2.10.3",
38
39
  "uuid": "^9.0.1",
39
- "@stackframe/stack-sc": "2.5.29"
40
+ "@stackframe/stack-sc": "2.5.31"
40
41
  },
41
42
  "devDependencies": {
42
- "rimraf": "^5.0.5",
43
43
  "@types/bcrypt": "^5.0.2",
44
+ "@types/elliptic": "^6.4.18",
44
45
  "@types/react": "^18.2.66",
45
46
  "@types/uuid": "^9.0.8",
46
47
  "next": "^14.1.0",
47
- "react": "^18.2.0"
48
+ "react": "^18.2.0",
49
+ "rimraf": "^5.0.5"
48
50
  },
49
51
  "scripts": {
50
52
  "build": "tsc",