@stackframe/stack-shared 2.7.27 → 2.7.29

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,17 @@
1
1
  # @stackframe/stack-shared
2
2
 
3
+ ## 2.7.29
4
+
5
+ ### Patch Changes
6
+
7
+ - Various changes
8
+
9
+ ## 2.7.28
10
+
11
+ ### Patch Changes
12
+
13
+ - Various changes
14
+
3
15
  ## 2.7.27
4
16
 
5
17
  ### Patch Changes
@@ -15,6 +15,7 @@ import { TeamsCrud } from './crud/teams';
15
15
  export type ClientInterfaceOptions = {
16
16
  clientVersion: string;
17
17
  getBaseUrl: () => string;
18
+ extraRequestHeaders: Record<string, string>;
18
19
  projectId: string;
19
20
  prepareRequest?: () => Promise<void>;
20
21
  } & ({
@@ -115,7 +116,7 @@ export declare class StackClientInterface {
115
116
  signUpWithCredential(email: string, password: string, emailVerificationRedirectUrl: string, session: InternalSession): Promise<Result<{
116
117
  accessToken: string;
117
118
  refreshToken: string;
118
- }, KnownErrors["UserEmailAlreadyExists"] | KnownErrors["PasswordRequirementsNotMet"]>>;
119
+ }, KnownErrors["UserWithEmailAlreadyExists"] | KnownErrors["PasswordRequirementsNotMet"]>>;
119
120
  signInWithMagicLink(code: string): Promise<Result<{
120
121
  newUser: boolean;
121
122
  accessToken: string;
@@ -212,6 +212,7 @@ export class StackClientInterface {
212
212
  * the case (I haven't actually tested.)
213
213
  */
214
214
  "X-Stack-Random-Nonce": generateSecureRandomString(),
215
+ ...this.options.extraRequestHeaders,
215
216
  ...options.headers,
216
217
  },
217
218
  /**
@@ -565,7 +566,7 @@ export class StackClientInterface {
565
566
  password,
566
567
  verification_callback_url: emailVerificationRedirectUrl,
567
568
  }),
568
- }, session, [KnownErrors.UserEmailAlreadyExists, KnownErrors.PasswordRequirementsNotMet]);
569
+ }, session, [KnownErrors.UserWithEmailAlreadyExists, KnownErrors.PasswordRequirementsNotMet]);
569
570
  if (res.status === "error") {
570
571
  return Result.error(res.error);
571
572
  }
@@ -4,30 +4,60 @@ export declare const sentEmailReadSchema: import("yup").ObjectSchema<{
4
4
  subject: string;
5
5
  sent_at_millis: number;
6
6
  to: string[] | undefined;
7
- sender_config: {} | null;
7
+ sender_config: {
8
+ host?: string | undefined;
9
+ port?: number | undefined;
10
+ username?: string | undefined;
11
+ sender_name?: string | undefined;
12
+ sender_email?: string | undefined;
13
+ type: "shared" | "standard";
14
+ };
8
15
  error: {} | null | undefined;
9
16
  }, import("yup").AnyObject, {
10
17
  id: undefined;
11
18
  subject: undefined;
12
19
  sent_at_millis: undefined;
13
20
  to: undefined;
14
- sender_config: undefined;
21
+ sender_config: {
22
+ type: undefined;
23
+ host: undefined;
24
+ port: undefined;
25
+ username: undefined;
26
+ password: undefined;
27
+ sender_name: undefined;
28
+ sender_email: undefined;
29
+ };
15
30
  error: undefined;
16
31
  }, "">;
17
32
  export declare const internalEmailsCrud: import("../../crud").CrudSchemaFromOptions<{
18
- clientReadSchema: import("yup").ObjectSchema<{
33
+ adminReadSchema: import("yup").ObjectSchema<{
19
34
  id: string;
20
35
  subject: string;
21
36
  sent_at_millis: number;
22
37
  to: string[] | undefined;
23
- sender_config: {} | null;
38
+ sender_config: {
39
+ host?: string | undefined;
40
+ port?: number | undefined;
41
+ username?: string | undefined;
42
+ sender_name?: string | undefined;
43
+ sender_email?: string | undefined;
44
+ type: "shared" | "standard";
45
+ };
24
46
  error: {} | null | undefined;
25
47
  }, import("yup").AnyObject, {
26
48
  id: undefined;
27
49
  subject: undefined;
28
50
  sent_at_millis: undefined;
29
51
  to: undefined;
30
- sender_config: undefined;
52
+ sender_config: {
53
+ type: undefined;
54
+ host: undefined;
55
+ port: undefined;
56
+ username: undefined;
57
+ password: undefined;
58
+ sender_name: undefined;
59
+ sender_email: undefined;
60
+ };
31
61
  error: undefined;
32
62
  }, "">;
33
63
  }>;
@@ -1,13 +1,14 @@
1
1
  import { createCrud } from "../../crud";
2
2
  import * as fieldSchema from "../../schema-fields";
3
+ import { emailConfigWithoutPasswordSchema } from "./projects";
3
4
  export const sentEmailReadSchema = fieldSchema.yupObject({
4
5
  id: fieldSchema.yupString().defined(),
5
6
  subject: fieldSchema.yupString().defined(),
6
7
  sent_at_millis: fieldSchema.yupNumber().defined(),
7
8
  to: fieldSchema.yupArray(fieldSchema.yupString().defined()),
8
- sender_config: fieldSchema.yupMixed().nullable().defined(),
9
+ sender_config: emailConfigWithoutPasswordSchema.defined(),
9
10
  error: fieldSchema.yupMixed().nullable().optional(),
10
11
  }).defined();
11
12
  export const internalEmailsCrud = createCrud({
12
- clientReadSchema: sentEmailReadSchema,
13
+ adminReadSchema: sentEmailReadSchema,
13
14
  });
@@ -16,6 +16,22 @@ export declare const emailConfigSchema: import("yup").ObjectSchema<{
16
16
  sender_name: undefined;
17
17
  sender_email: undefined;
18
18
  }, "">;
19
+ export declare const emailConfigWithoutPasswordSchema: import("yup").ObjectSchema<{
20
+ type: "shared" | "standard";
21
+ host: string | undefined;
22
+ port: number | undefined;
23
+ username: string | undefined;
24
+ sender_name: string | undefined;
25
+ sender_email: string | undefined;
26
+ }, import("yup").AnyObject, {
27
+ type: undefined;
28
+ host: undefined;
29
+ port: undefined;
30
+ username: undefined;
31
+ password: undefined;
32
+ sender_name: undefined;
33
+ sender_email: undefined;
34
+ }, "">;
19
35
  export declare const projectsCrudAdminReadSchema: import("yup").ObjectSchema<{
20
36
  id: string;
21
37
  display_name: string;
@@ -44,6 +44,7 @@ export const emailConfigSchema = yupObject({
44
44
  type: 'standard',
45
45
  }),
46
46
  });
47
+ export const emailConfigWithoutPasswordSchema = emailConfigSchema.pick(['type', 'host', 'port', 'username', 'sender_name', 'sender_email']);
47
48
  const domainSchema = yupObject({
48
49
  domain: schemaFields.urlSchema.defined()
49
50
  .matches(/^https?:\/\//, 'URL must start with http:// or https://')
@@ -103,4 +103,8 @@ export declare class StackServerInterface extends StackClientInterface {
103
103
  teamId: string;
104
104
  callbackUrl: string;
105
105
  }): Promise<void>;
106
+ updatePassword(options: {
107
+ oldPassword: string;
108
+ newPassword: string;
109
+ }): Promise<KnownErrors["PasswordConfirmationMismatch"] | KnownErrors["PasswordRequirementsNotMet"] | undefined>;
106
110
  }
@@ -311,4 +311,19 @@ export class StackServerInterface extends StackClientInterface {
311
311
  }),
312
312
  }, null);
313
313
  }
314
+ async updatePassword(options) {
315
+ const res = await this.sendServerRequestAndCatchKnownError("/auth/password/update", {
316
+ method: "POST",
317
+ headers: {
318
+ "Content-Type": "application/json"
319
+ },
320
+ body: JSON.stringify({
321
+ old_password: options.oldPassword,
322
+ new_password: options.newPassword,
323
+ }),
324
+ }, null, [KnownErrors.PasswordConfirmationMismatch, KnownErrors.PasswordRequirementsNotMet]);
325
+ if (res.status === "error") {
326
+ return res.error;
327
+ }
328
+ }
314
329
  }
@@ -204,7 +204,7 @@ export declare const KnownErrors: {
204
204
  };
205
205
  InvalidProjectForAccessToken: KnownErrorConstructor<KnownError & KnownErrorBrand<"SESSION_AUTHENTICATION_ERROR"> & {
206
206
  constructorArgs: [statusCode: number, humanReadableMessage: string, details?: Json | undefined];
207
- } & KnownErrorBrand<"INVALID_SESSION_AUTHENTICATION"> & KnownErrorBrand<"INVALID_ACCESS_TOKEN"> & KnownErrorBrand<"INVALID_PROJECT_FOR_ACCESS_TOKEN">, []> & {
207
+ } & KnownErrorBrand<"INVALID_SESSION_AUTHENTICATION"> & KnownErrorBrand<"INVALID_ACCESS_TOKEN"> & KnownErrorBrand<"INVALID_PROJECT_FOR_ACCESS_TOKEN">, [expectedProjectId: string, actualProjectId: string]> & {
208
208
  errorCode: "INVALID_PROJECT_FOR_ACCESS_TOKEN";
209
209
  };
210
210
  RefreshTokenError: KnownErrorConstructor<KnownError & KnownErrorBrand<"REFRESH_TOKEN_ERROR">, [statusCode: number, humanReadableMessage: string, details?: Json | undefined]> & {
@@ -220,7 +220,7 @@ export declare const KnownErrors: {
220
220
  } & KnownErrorBrand<"REFRESH_TOKEN_NOT_FOUND_OR_EXPIRED">, []> & {
221
221
  errorCode: "REFRESH_TOKEN_NOT_FOUND_OR_EXPIRED";
222
222
  };
223
- UserEmailAlreadyExists: KnownErrorConstructor<KnownError & KnownErrorBrand<"USER_EMAIL_ALREADY_EXISTS">, []> & {
223
+ UserWithEmailAlreadyExists: KnownErrorConstructor<KnownError & KnownErrorBrand<"USER_EMAIL_ALREADY_EXISTS">, [email: string]> & {
224
224
  errorCode: "USER_EMAIL_ALREADY_EXISTS";
225
225
  };
226
226
  EmailNotVerified: KnownErrorConstructor<KnownError & KnownErrorBrand<"EMAIL_NOT_VERIFIED">, []> & {
@@ -246,10 +246,14 @@ const AccessTokenExpired = createKnownErrorConstructor(InvalidAccessToken, "ACCE
246
246
  `Access token has expired. Please refresh it and try again.${expiredAt ? ` (The access token expired at ${expiredAt.toISOString()}.)` : ""}`,
247
247
  { expired_at_millis: expiredAt?.getTime() ?? null },
248
248
  ], (json) => [json.expired_at_millis ? new Date(json.expired_at_millis) : undefined]);
249
- const InvalidProjectForAccessToken = createKnownErrorConstructor(InvalidAccessToken, "INVALID_PROJECT_FOR_ACCESS_TOKEN", () => [
249
+ const InvalidProjectForAccessToken = createKnownErrorConstructor(InvalidAccessToken, "INVALID_PROJECT_FOR_ACCESS_TOKEN", (expectedProjectId, actualProjectId) => [
250
250
  401,
251
- "Access token not valid for this project.",
252
- ], () => []);
251
+ `Access token not valid for this project. Expected project ID ${JSON.stringify(expectedProjectId)}, but the token is for project ID ${JSON.stringify(actualProjectId)}.`,
252
+ {
253
+ expected_project_id: expectedProjectId,
254
+ actual_project_id: actualProjectId,
255
+ },
256
+ ], (json) => [json.expected_project_id, json.actual_project_id]);
253
257
  const RefreshTokenError = createKnownErrorConstructor(KnownError, "REFRESH_TOKEN_ERROR", "inherit", "inherit");
254
258
  const RefreshTokenNotFoundOrExpired = createKnownErrorConstructor(RefreshTokenError, "REFRESH_TOKEN_NOT_FOUND_OR_EXPIRED", () => [
255
259
  401,
@@ -263,10 +267,13 @@ const ProviderRejected = createKnownErrorConstructor(RefreshTokenError, "PROVIDE
263
267
  401,
264
268
  "The provider refused to refresh their token. This usually means that the provider used to authenticate the user no longer regards this session as valid, and the user must re-authenticate.",
265
269
  ], () => []);
266
- const UserEmailAlreadyExists = createKnownErrorConstructor(KnownError, "USER_EMAIL_ALREADY_EXISTS", () => [
270
+ const UserWithEmailAlreadyExists = createKnownErrorConstructor(KnownError, "USER_EMAIL_ALREADY_EXISTS", (email) => [
267
271
  409,
268
- "User email already exists.",
269
- ], () => []);
272
+ `A user with email ${JSON.stringify(email)} already exists.`,
273
+ {
274
+ email,
275
+ },
276
+ ], (json) => [json.email]);
270
277
  const EmailNotVerified = createKnownErrorConstructor(KnownError, "EMAIL_NOT_VERIFIED", () => [
271
278
  400,
272
279
  "The email is not verified.",
@@ -590,7 +597,7 @@ export const KnownErrors = {
590
597
  RefreshTokenError,
591
598
  ProviderRejected,
592
599
  RefreshTokenNotFoundOrExpired,
593
- UserEmailAlreadyExists,
600
+ UserWithEmailAlreadyExists,
594
601
  EmailNotVerified,
595
602
  UserIdDoesNotExist,
596
603
  UserNotFound,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stackframe/stack-shared",
3
- "version": "2.7.27",
3
+ "version": "2.7.29",
4
4
  "main": "./dist/index.js",
5
5
  "types": "./dist/index.d.ts",
6
6
  "type": "module",