@stackframe/stack-shared 2.4.9 → 2.4.12

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,25 @@
1
1
  # @stackframe/stack-shared
2
2
 
3
+ ## 2.4.12
4
+
5
+ ### Patch Changes
6
+
7
+ - Improved client styling, added login form, added spotify oauth
8
+
9
+ ## 2.4.11
10
+
11
+ ### Patch Changes
12
+
13
+ - Added email editor
14
+
15
+ ## 2.4.10
16
+
17
+ ### Patch Changes
18
+
19
+ - Bug fixes
20
+ - Updated dependencies
21
+ - @stackframe/stack-sc@1.5.5
22
+
3
23
  ## 2.4.9
4
24
 
5
25
  ### Patch Changes
@@ -47,10 +47,10 @@ export type ClientInterfaceOptions = {
47
47
  projectOwnerTokens: TokenStore;
48
48
  refreshProjectOwnerTokens: () => Promise<void>;
49
49
  });
50
- export type SharedProvider = "shared-github" | "shared-google" | "shared-facebook" | "shared-microsoft";
51
- export declare const sharedProviders: readonly ["shared-github", "shared-google", "shared-facebook", "shared-microsoft"];
52
- export type StandardProvider = "github" | "facebook" | "google" | "microsoft";
53
- export declare const standardProviders: readonly ["github", "facebook", "google", "microsoft"];
50
+ export type SharedProvider = "shared-github" | "shared-google" | "shared-facebook" | "shared-microsoft" | "shared-spotify";
51
+ export declare const sharedProviders: readonly ["shared-github", "shared-google", "shared-facebook", "shared-microsoft", "shared-spotify"];
52
+ export type StandardProvider = "github" | "facebook" | "google" | "microsoft" | "spotify";
53
+ export declare const standardProviders: readonly ["github", "facebook", "google", "microsoft", "spotify"];
54
54
  export declare function toStandardProvider(provider: SharedProvider | StandardProvider): StandardProvider;
55
55
  export declare function toSharedProvider(provider: SharedProvider | StandardProvider): SharedProvider;
56
56
  export type ReadonlyTokenStore = ReadonlyAsyncStore<TokenObject>;
@@ -10,12 +10,14 @@ export const sharedProviders = [
10
10
  "shared-google",
11
11
  "shared-facebook",
12
12
  "shared-microsoft",
13
+ "shared-spotify",
13
14
  ];
14
15
  export const standardProviders = [
15
16
  "github",
16
17
  "facebook",
17
18
  "google",
18
19
  "microsoft",
20
+ "spotify",
19
21
  ];
20
22
  export function toStandardProvider(provider) {
21
23
  return provider.replace("shared-", "");
@@ -183,7 +185,18 @@ export class StackClientInterface {
183
185
  cache: "no-store",
184
186
  },
185
187
  };
186
- const rawRes = await fetch(url, params);
188
+ let rawRes;
189
+ try {
190
+ rawRes = await fetch(url, params);
191
+ }
192
+ catch (e) {
193
+ if (e instanceof TypeError) {
194
+ // Network error, retry
195
+ console.log("Stack detected a network error, retrying.", e);
196
+ return Result.error(e);
197
+ }
198
+ throw e;
199
+ }
187
200
  const processedRes = await this._processResponse(rawRes);
188
201
  if (processedRes.status === "error") {
189
202
  // If the access token is expired, reset it and retry
@@ -23,7 +23,7 @@ export declare const currentUserCrud: {
23
23
  primaryEmail: undefined;
24
24
  primaryEmailVerified: undefined;
25
25
  displayName: undefined;
26
- clientMetadata: {};
26
+ clientMetadata: undefined;
27
27
  selectedTeamId: undefined;
28
28
  profileImageUrl: undefined;
29
29
  signedUpAtMillis: undefined;
@@ -31,7 +31,7 @@ export declare const currentUserCrud: {
31
31
  hasPassword: undefined;
32
32
  authWithEmail: undefined;
33
33
  oauthProviders: undefined;
34
- serverMetadata: {};
34
+ serverMetadata: undefined;
35
35
  }, "">;
36
36
  updateSchema: yup.ObjectSchema<{
37
37
  displayName: string | undefined;
@@ -70,7 +70,7 @@ export declare const currentUserCrud: {
70
70
  primaryEmail: undefined;
71
71
  primaryEmailVerified: undefined;
72
72
  displayName: undefined;
73
- clientMetadata: {};
73
+ clientMetadata: undefined;
74
74
  selectedTeamId: undefined;
75
75
  profileImageUrl: undefined;
76
76
  signedUpAtMillis: undefined;
@@ -78,7 +78,7 @@ export declare const currentUserCrud: {
78
78
  hasPassword: undefined;
79
79
  authWithEmail: undefined;
80
80
  oauthProviders: undefined;
81
- serverMetadata: {};
81
+ serverMetadata: undefined;
82
82
  }, "">;
83
83
  updateSchema: yup.ObjectSchema<{
84
84
  displayName: string | undefined;
@@ -120,7 +120,7 @@ export declare const currentUserCrud: {
120
120
  primaryEmail: undefined;
121
121
  primaryEmailVerified: undefined;
122
122
  displayName: undefined;
123
- clientMetadata: {};
123
+ clientMetadata: undefined;
124
124
  selectedTeamId: undefined;
125
125
  profileImageUrl: undefined;
126
126
  signedUpAtMillis: undefined;
@@ -128,7 +128,7 @@ export declare const currentUserCrud: {
128
128
  hasPassword: undefined;
129
129
  authWithEmail: undefined;
130
130
  oauthProviders: undefined;
131
- serverMetadata: {};
131
+ serverMetadata: undefined;
132
132
  }, "">;
133
133
  updateSchema: yup.ObjectSchema<{
134
134
  displayName: string | undefined;
@@ -0,0 +1,119 @@
1
+ import { CrudTypeOf } from "../../crud";
2
+ import * as yup from "yup";
3
+ export declare const emailTemplateServerReadSchema: yup.ObjectSchema<{
4
+ type: NonNullable<"EMAIL_VERIFICATION" | "PASSWORD_RESET" | "MAGIC_LINK" | undefined>;
5
+ subject: string;
6
+ content: {};
7
+ }, yup.AnyObject, {
8
+ type: undefined;
9
+ subject: undefined;
10
+ content: undefined;
11
+ }, "">;
12
+ export declare const emailTemplateCrudServerUpdateSchema: yup.ObjectSchema<{
13
+ content: {};
14
+ subject: string;
15
+ }, yup.AnyObject, {
16
+ content: undefined;
17
+ subject: undefined;
18
+ }, "">;
19
+ export declare const emailTemplateCrud: {
20
+ client: {
21
+ createSchema: undefined;
22
+ readSchema: undefined;
23
+ updateSchema: undefined;
24
+ deleteSchema: undefined;
25
+ };
26
+ server: {
27
+ createSchema: undefined;
28
+ readSchema: yup.ObjectSchema<{
29
+ type: NonNullable<"EMAIL_VERIFICATION" | "PASSWORD_RESET" | "MAGIC_LINK" | undefined>;
30
+ subject: string;
31
+ content: {};
32
+ }, yup.AnyObject, {
33
+ type: undefined;
34
+ subject: undefined;
35
+ content: undefined;
36
+ }, "">;
37
+ updateSchema: yup.ObjectSchema<{
38
+ content: {};
39
+ subject: string;
40
+ }, yup.AnyObject, {
41
+ content: undefined;
42
+ subject: undefined;
43
+ }, "">;
44
+ deleteSchema: yup.MixedSchema<{} | undefined, yup.AnyObject, undefined, "">;
45
+ };
46
+ admin: {
47
+ createSchema: undefined;
48
+ readSchema: yup.ObjectSchema<{
49
+ type: NonNullable<"EMAIL_VERIFICATION" | "PASSWORD_RESET" | "MAGIC_LINK" | undefined>;
50
+ subject: string;
51
+ content: {};
52
+ }, yup.AnyObject, {
53
+ type: undefined;
54
+ subject: undefined;
55
+ content: undefined;
56
+ }, "">;
57
+ updateSchema: yup.ObjectSchema<{
58
+ content: {};
59
+ subject: string;
60
+ }, yup.AnyObject, {
61
+ content: undefined;
62
+ subject: undefined;
63
+ }, "">;
64
+ deleteSchema: yup.MixedSchema<{} | undefined, yup.AnyObject, undefined, "">;
65
+ };
66
+ hasCreate: boolean;
67
+ hasRead: boolean;
68
+ hasUpdate: boolean;
69
+ hasDelete: boolean;
70
+ };
71
+ export type EmailTemplateCrud = CrudTypeOf<typeof emailTemplateCrud>;
72
+ export declare const listEmailTemplatesReadSchema: yup.ArraySchema<{
73
+ type: NonNullable<"EMAIL_VERIFICATION" | "PASSWORD_RESET" | "MAGIC_LINK" | undefined>;
74
+ default: NonNullable<boolean | undefined>;
75
+ subject: string;
76
+ content: {};
77
+ }[], yup.AnyObject, "", "">;
78
+ export declare const emailTemplateCrudServerCreateSchema: yup.ObjectSchema<{
79
+ type: NonNullable<"EMAIL_VERIFICATION" | "PASSWORD_RESET" | "MAGIC_LINK" | undefined>;
80
+ content: {};
81
+ }, yup.AnyObject, {
82
+ type: undefined;
83
+ content: undefined;
84
+ }, "">;
85
+ export declare const listEmailTemplatesCrud: {
86
+ client: {
87
+ createSchema: undefined;
88
+ readSchema: undefined;
89
+ updateSchema: undefined;
90
+ deleteSchema: undefined;
91
+ };
92
+ server: {
93
+ createSchema: undefined;
94
+ readSchema: yup.ArraySchema<{
95
+ type: NonNullable<"EMAIL_VERIFICATION" | "PASSWORD_RESET" | "MAGIC_LINK" | undefined>;
96
+ default: NonNullable<boolean | undefined>;
97
+ subject: string;
98
+ content: {};
99
+ }[], yup.AnyObject, "", "">;
100
+ updateSchema: undefined;
101
+ deleteSchema: undefined;
102
+ };
103
+ admin: {
104
+ createSchema: undefined;
105
+ readSchema: yup.ArraySchema<{
106
+ type: NonNullable<"EMAIL_VERIFICATION" | "PASSWORD_RESET" | "MAGIC_LINK" | undefined>;
107
+ default: NonNullable<boolean | undefined>;
108
+ subject: string;
109
+ content: {};
110
+ }[], yup.AnyObject, "", "">;
111
+ updateSchema: undefined;
112
+ deleteSchema: undefined;
113
+ };
114
+ hasCreate: boolean;
115
+ hasRead: boolean;
116
+ hasUpdate: boolean;
117
+ hasDelete: boolean;
118
+ };
119
+ export type ListEmailTemplatesCrud = CrudTypeOf<typeof listEmailTemplatesCrud>;
@@ -0,0 +1,29 @@
1
+ import { createCrud } from "../../crud";
2
+ import * as yup from "yup";
3
+ import { emailTemplateTypes } from "../serverInterface";
4
+ import { yupJson } from "../../utils/yup";
5
+ export const emailTemplateServerReadSchema = yup.object({
6
+ type: yup.string().oneOf(emailTemplateTypes).required(),
7
+ subject: yup.string().required(),
8
+ content: yupJson.required(),
9
+ }).required();
10
+ export const emailTemplateCrudServerUpdateSchema = yup.object({
11
+ content: yupJson.required(),
12
+ subject: yup.string().required(),
13
+ }).required();
14
+ const serverDeleteSchema = yup.mixed();
15
+ export const emailTemplateCrud = createCrud({
16
+ serverReadSchema: emailTemplateServerReadSchema,
17
+ serverUpdateSchema: emailTemplateCrudServerUpdateSchema,
18
+ serverDeleteSchema,
19
+ });
20
+ export const listEmailTemplatesReadSchema = yup.array().of(emailTemplateServerReadSchema.concat(yup.object({
21
+ default: yup.boolean().required(),
22
+ }))).required();
23
+ export const emailTemplateCrudServerCreateSchema = yup.object({
24
+ type: yup.string().oneOf(emailTemplateTypes).required(),
25
+ content: yupJson.required(),
26
+ }).required();
27
+ export const listEmailTemplatesCrud = createCrud({
28
+ serverReadSchema: listEmailTemplatesReadSchema,
29
+ });
@@ -36,7 +36,7 @@ export declare const usersCrudServerReadSchema: yup.ObjectSchema<{
36
36
  primaryEmail: undefined;
37
37
  primaryEmailVerified: undefined;
38
38
  displayName: undefined;
39
- clientMetadata: {};
39
+ clientMetadata: undefined;
40
40
  selectedTeamId: undefined;
41
41
  profileImageUrl: undefined;
42
42
  signedUpAtMillis: undefined;
@@ -44,7 +44,7 @@ export declare const usersCrudServerReadSchema: yup.ObjectSchema<{
44
44
  hasPassword: undefined;
45
45
  authWithEmail: undefined;
46
46
  oauthProviders: undefined;
47
- serverMetadata: {};
47
+ serverMetadata: undefined;
48
48
  }, "">;
49
49
  export declare const usersCrud: {
50
50
  client: {
@@ -76,7 +76,7 @@ export declare const usersCrud: {
76
76
  primaryEmail: undefined;
77
77
  primaryEmailVerified: undefined;
78
78
  displayName: undefined;
79
- clientMetadata: {};
79
+ clientMetadata: undefined;
80
80
  selectedTeamId: undefined;
81
81
  profileImageUrl: undefined;
82
82
  signedUpAtMillis: undefined;
@@ -84,7 +84,7 @@ export declare const usersCrud: {
84
84
  hasPassword: undefined;
85
85
  authWithEmail: undefined;
86
86
  oauthProviders: undefined;
87
- serverMetadata: {};
87
+ serverMetadata: undefined;
88
88
  }, "">;
89
89
  updateSchema: yup.ObjectSchema<{
90
90
  displayName: string | undefined;
@@ -102,7 +102,9 @@ export declare const usersCrud: {
102
102
  selectedTeamId: undefined;
103
103
  }, "">;
104
104
  deleteSchema: yup.MixedSchema<{} | undefined, yup.AnyObject, undefined, "">;
105
- };
105
+ }; /**
106
+ * not used anymore, for backwards compatibility
107
+ */
106
108
  admin: {
107
109
  createSchema: undefined;
108
110
  readSchema: yup.ObjectSchema<{
@@ -126,7 +128,7 @@ export declare const usersCrud: {
126
128
  primaryEmail: undefined;
127
129
  primaryEmailVerified: undefined;
128
130
  displayName: undefined;
129
- clientMetadata: {};
131
+ clientMetadata: undefined;
130
132
  selectedTeamId: undefined;
131
133
  profileImageUrl: undefined;
132
134
  signedUpAtMillis: undefined;
@@ -134,7 +136,7 @@ export declare const usersCrud: {
134
136
  hasPassword: undefined;
135
137
  authWithEmail: undefined;
136
138
  oauthProviders: undefined;
137
- serverMetadata: {};
139
+ serverMetadata: undefined;
138
140
  }, "">;
139
141
  updateSchema: yup.ObjectSchema<{
140
142
  displayName: string | undefined;
@@ -1,5 +1,6 @@
1
1
  import { createCrud } from "../../crud";
2
2
  import * as yup from "yup";
3
+ import { yupJson } from "../../utils/yup";
3
4
  export const usersCrudServerUpdateSchema = yup.object({
4
5
  displayName: yup.string().optional(),
5
6
  clientMetadata: yup.object().optional(),
@@ -14,7 +15,7 @@ export const usersCrudServerReadSchema = yup.object({
14
15
  primaryEmail: yup.string().nullable().defined(),
15
16
  primaryEmailVerified: yup.boolean().required(),
16
17
  displayName: yup.string().nullable().defined(),
17
- clientMetadata: yup.object().nullable().defined().transform((value) => JSON.parse(JSON.stringify(value))),
18
+ clientMetadata: yupJson,
18
19
  selectedTeamId: yup.string().nullable().defined(),
19
20
  profileImageUrl: yup.string().nullable().defined(),
20
21
  signedUpAtMillis: yup.number().required(),
@@ -25,7 +26,7 @@ export const usersCrudServerReadSchema = yup.object({
25
26
  hasPassword: yup.boolean().required(),
26
27
  authWithEmail: yup.boolean().required(),
27
28
  oauthProviders: yup.array(yup.string().required()).required(),
28
- serverMetadata: yup.object().nullable().defined().transform((value) => JSON.parse(JSON.stringify(value))),
29
+ serverMetadata: yupJson,
29
30
  }).required();
30
31
  const serverDeleteSchema = yup.mixed();
31
32
  export const usersCrud = createCrud({
@@ -1,6 +1,7 @@
1
1
  import { ClientInterfaceOptions, UserJson, TokenStore, StackClientInterface, ReadonlyTokenStore, OrglikeJson, UserUpdateJson, PermissionDefinitionJson, PermissionDefinitionScopeJson as PermissionDefinitionScopeJson, TeamMemberJson } from "./clientInterface";
2
2
  import { Result } from "../utils/results";
3
3
  import { ReadonlyJson } from "../utils/json";
4
+ import { EmailTemplateCrud, ListEmailTemplatesCrud } from "./crud/email-templates";
4
5
  export type ServerUserJson = UserJson & {
5
6
  serverMetadata: ReadonlyJson;
6
7
  };
@@ -29,6 +30,8 @@ export type ServerAuthApplicationOptions = (ClientInterfaceOptions & ({
29
30
  } | {
30
31
  readonly projectOwnerTokens: ReadonlyTokenStore;
31
32
  }));
33
+ export declare const emailTemplateTypes: readonly ["EMAIL_VERIFICATION", "PASSWORD_RESET", "MAGIC_LINK"];
34
+ export type EmailTemplateType = typeof emailTemplateTypes[number];
32
35
  export declare class StackServerInterface extends StackClientInterface {
33
36
  options: ServerAuthApplicationOptions;
34
37
  constructor(options: ServerAuthApplicationOptions);
@@ -74,4 +77,7 @@ export declare class StackServerInterface extends StackClientInterface {
74
77
  grantTeamUserPermission(teamId: string, userId: string, permissionId: string, type: 'global' | 'team'): Promise<void>;
75
78
  revokeTeamUserPermission(teamId: string, userId: string, permissionId: string, type: 'global' | 'team'): Promise<void>;
76
79
  deleteServerUser(userId: string): Promise<void>;
80
+ listEmailTemplates(): Promise<ListEmailTemplatesCrud['Server']['Read']>;
81
+ updateEmailTemplate(type: EmailTemplateType, data: EmailTemplateCrud['Server']['Update']): Promise<void>;
82
+ resetEmailTemplate(type: EmailTemplateType): Promise<void>;
77
83
  }
@@ -1,5 +1,6 @@
1
1
  import { StackClientInterface, } from "./clientInterface";
2
2
  import { Result } from "../utils/results";
3
+ export const emailTemplateTypes = ['EMAIL_VERIFICATION', 'PASSWORD_RESET', 'MAGIC_LINK'];
3
4
  export class StackServerInterface extends StackClientInterface {
4
5
  options;
5
6
  constructor(options) {
@@ -163,4 +164,20 @@ export class StackServerInterface extends StackClientInterface {
163
164
  body: JSON.stringify({}),
164
165
  }, null);
165
166
  }
167
+ async listEmailTemplates() {
168
+ const response = await this.sendServerRequest(`/email-templates?server=true`, {}, null);
169
+ return await response.json();
170
+ }
171
+ async updateEmailTemplate(type, data) {
172
+ await this.sendServerRequest(`/email-templates/${type}?server=true`, {
173
+ method: "PUT",
174
+ headers: {
175
+ "content-type": "application/json",
176
+ },
177
+ body: JSON.stringify(data),
178
+ }, null);
179
+ }
180
+ async resetEmailTemplate(type) {
181
+ await this.sendServerRequest(`/email-templates/${type}?server=true`, { method: "DELETE" }, null);
182
+ }
166
183
  }
@@ -239,5 +239,8 @@ export declare const KnownErrors: {
239
239
  TeamNotFound: KnownErrorConstructor<KnownError & KnownErrorBrand<"TEAM_NOT_FOUND">, [teamId: string]> & {
240
240
  errorCode: "TEAM_NOT_FOUND";
241
241
  };
242
+ EmailTemplateAlreadyExists: KnownErrorConstructor<KnownError & KnownErrorBrand<"EMAIL_TEMPLATE_ALREADY_EXISTS">, []> & {
243
+ errorCode: "EMAIL_TEMPLATE_ALREADY_EXISTS";
244
+ };
242
245
  };
243
246
  export {};
@@ -337,6 +337,10 @@ const TeamNotFound = createKnownErrorConstructor(KnownError, "TEAM_NOT_FOUND", (
337
337
  teamId,
338
338
  },
339
339
  ], (json) => [json.details.teamId]);
340
+ const EmailTemplateAlreadyExists = createKnownErrorConstructor(KnownError, "EMAIL_TEMPLATE_ALREADY_EXISTS", () => [
341
+ 400,
342
+ "Email template already exists.",
343
+ ], () => []);
340
344
  export const KnownErrors = {
341
345
  UnsupportedError,
342
346
  BodyParsingError,
@@ -403,6 +407,7 @@ export const KnownErrors = {
403
407
  PermissionNotFound,
404
408
  PermissionScopeMismatch,
405
409
  TeamNotFound,
410
+ EmailTemplateAlreadyExists,
406
411
  };
407
412
  // ensure that all known error codes are unique
408
413
  const knownErrorCodes = new Set();
@@ -0,0 +1,2 @@
1
+ import * as yup from "yup";
2
+ export declare const yupJson: yup.MixedSchema<{} | null, yup.AnyObject, undefined, "">;
@@ -0,0 +1,2 @@
1
+ import * as yup from "yup";
2
+ export const yupJson = yup.mixed().nullable().defined().transform((value) => JSON.parse(JSON.stringify(value)));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stackframe/stack-shared",
3
- "version": "2.4.9",
3
+ "version": "2.4.12",
4
4
  "main": "./dist/index.js",
5
5
  "types": "./dist/index.d.ts",
6
6
  "files": [
@@ -26,7 +26,7 @@
26
26
  "jose": "^5.2.2",
27
27
  "oauth4webapi": "^2.10.3",
28
28
  "uuid": "^9.0.1",
29
- "@stackframe/stack-sc": "1.5.4"
29
+ "@stackframe/stack-sc": "1.5.5"
30
30
  },
31
31
  "devDependencies": {
32
32
  "@types/bcrypt": "^5.0.2",