Prepend mailbox ID to generated email addresses

This commit is contained in:
Konstantin Wohlwend 2024-12-21 12:19:24 -08:00
parent 534fef5d62
commit ac0d657243
17 changed files with 107 additions and 99 deletions

View File

@ -2,11 +2,12 @@ import { InternalProjectsCrud } from "@stackframe/stack-shared/dist/interface/cr
import { encodeBase64 } from "@stackframe/stack-shared/dist/utils/bytes";
import { generateSecureRandomString } from "@stackframe/stack-shared/dist/utils/crypto";
import { StackAssertionError, throwErr } from "@stackframe/stack-shared/dist/utils/errors";
import { filterUndefined } from "@stackframe/stack-shared/dist/utils/objects";
import { filterUndefined, omit } from "@stackframe/stack-shared/dist/utils/objects";
import { nicify } from "@stackframe/stack-shared/dist/utils/strings";
import * as jose from "jose";
import { randomUUID } from "node:crypto";
import { expect } from "vitest";
import { Context, Mailbox, NiceRequestInit, NiceResponse, STACK_BACKEND_BASE_URL, STACK_INTERNAL_PROJECT_ADMIN_KEY, STACK_INTERNAL_PROJECT_CLIENT_KEY, STACK_INTERNAL_PROJECT_ID, STACK_INTERNAL_PROJECT_SERVER_KEY, createMailbox, localRedirectUrl, niceFetch, updateCookiesFromResponse } from "../helpers";
import { Context, INBUCKET_API_URL, Mailbox, MailboxMessage, NiceRequestInit, NiceResponse, STACK_BACKEND_BASE_URL, STACK_INTERNAL_PROJECT_ADMIN_KEY, STACK_INTERNAL_PROJECT_CLIENT_KEY, STACK_INTERNAL_PROJECT_ID, STACK_INTERNAL_PROJECT_SERVER_KEY, generatedEmailSuffix, localRedirectUrl, niceFetch, updateCookiesFromResponse } from "../helpers";
type BackendContext = {
readonly projectKeys: ProjectKeys,
@ -15,12 +16,14 @@ type BackendContext = {
readonly refreshToken?: string,
readonly accessToken?: string,
} | null,
readonly generatedMailboxNamesCount: number,
};
export const backendContext = new Context<BackendContext, Partial<BackendContext>>(
() => ({
projectKeys: InternalProjectKeys,
mailbox: createMailbox(),
mailbox: createMailbox(`default-mailbox--${randomUUID()}${generatedEmailSuffix}`),
generatedMailboxNamesCount: 0,
userAuth: null,
}),
(acc, update) => {
@ -31,6 +34,34 @@ export const backendContext = new Context<BackendContext, Partial<BackendContext
},
);
export function createMailbox(email?: string): Mailbox {
if (email === undefined) {
backendContext.set({ generatedMailboxNamesCount: backendContext.value.generatedMailboxNamesCount + 1 });
email = `mailbox-${backendContext.value.generatedMailboxNamesCount}--${randomUUID()}${generatedEmailSuffix}`;
}
if (!email.includes("@")) throw new StackAssertionError(`Invalid mailbox email: ${email}`);
const mailboxName = email.split("@")[0];
const fullMessageCache = new Map<string, any>();
return {
emailAddress: email,
async fetchMessages({ noBody } = {}) {
const res = await niceFetch(new URL(`/api/v1/mailbox/${encodeURIComponent(mailboxName)}`, INBUCKET_API_URL));
return await Promise.all((res.body as any[]).map(async (message) => {
let fullMessage: any;
if (fullMessageCache.has(message.id)) {
fullMessage = fullMessageCache.get(message.id);
} else {
const fullMessageRes = await niceFetch(new URL(`/api/v1/mailbox/${encodeURIComponent(mailboxName)}/${message.id}`, INBUCKET_API_URL));
fullMessage = fullMessageRes.body;
fullMessageCache.set(message.id, fullMessage);
}
const messagePart = noBody ? omit(fullMessage, ["body", "attachments"]) : fullMessage;
return new MailboxMessage(messagePart);
}));
},
};
}
export type ProjectKeys = "no-project" | {
projectId: string,
publishableClientKey?: string,
@ -121,6 +152,7 @@ export namespace Auth {
const accessToken = backendContext.value.userAuth?.accessToken;
if (accessToken) {
const aud = jose.decodeJwt(accessToken).aud;
console.log(accessToken, jose.decodeJwt(accessToken));
const jwks = jose.createRemoteJWKSet(new URL(`api/v1/projects/${aud}/.well-known/jwks.json`, STACK_BACKEND_BASE_URL));
const { payload } = await jose.jwtVerify(accessToken, jwks);
expect(payload).toEqual({
@ -475,9 +507,9 @@ export namespace Auth {
},
"timeout": 60000,
"user": {
"displayName": "<stripped UUID>@stack-generated.example.com",
"displayName": "default-mailbox--<stripped UUID>@stack-generated.example.com",
"id": "<stripped encoded UUID>",
"name": "<stripped UUID>@stack-generated.example.com",
"name": "default-mailbox--<stripped UUID>@stack-generated.example.com",
},
},
},

View File

@ -42,14 +42,14 @@ describe("with grant_type === 'authorization_code'", async () => {
"id": "<stripped UUID>",
"oauth_providers": [
{
"account_id": "<stripped UUID>@stack-generated.example.com",
"email": "<stripped UUID>@stack-generated.example.com",
"account_id": "default-mailbox--<stripped UUID>@stack-generated.example.com",
"email": "default-mailbox--<stripped UUID>@stack-generated.example.com",
"id": "spotify",
},
],
"otp_auth_enabled": false,
"passkey_auth_enabled": false,
"primary_email": "<stripped UUID>@stack-generated.example.com",
"primary_email": "default-mailbox--<stripped UUID>@stack-generated.example.com",
"primary_email_verified": false,
"profile_image_url": null,
"requires_totp_mfa": false,

View File

@ -8,7 +8,7 @@ it("should send a sign-in code per e-mail", async ({ expect }) => {
MailboxMessage {
"from": "Stack Dashboard <noreply@example.com>",
"subject": "Sign in to Stack Dashboard",
"to": ["<<stripped UUID>@stack-generated.example.com>"],
"to": ["<default-mailbox--<stripped UUID>@stack-generated.example.com>"],
<some fields may have been hidden>,
},
]

View File

@ -26,7 +26,7 @@ async function getResetCode() {
MailboxMessage {
"from": "Stack Dashboard <noreply@example.com>",
"subject": "Reset your password at Stack Dashboard",
"to": ["<<stripped UUID>@stack-generated.example.com>"],
"to": ["<default-mailbox--<stripped UUID>@stack-generated.example.com>"],
<some fields may have been hidden>,
}
`);

View File

@ -25,13 +25,13 @@ it("should send a password reset code per e-mail", async ({ expect }) => {
MailboxMessage {
"from": "Stack Dashboard <noreply@example.com>",
"subject": "Verify your email at Stack Dashboard",
"to": ["<<stripped UUID>@stack-generated.example.com>"],
"to": ["<default-mailbox--<stripped UUID>@stack-generated.example.com>"],
<some fields may have been hidden>,
},
MailboxMessage {
"from": "Stack Dashboard <noreply@example.com>",
"subject": "Reset your password at Stack Dashboard",
"to": ["<<stripped UUID>@stack-generated.example.com>"],
"to": ["<default-mailbox--<stripped UUID>@stack-generated.example.com>"],
<some fields may have been hidden>,
},
]

View File

@ -31,7 +31,7 @@ it("should allow signing in to existing accounts", async ({ expect }) => {
"oauth_providers": [],
"otp_auth_enabled": false,
"passkey_auth_enabled": false,
"primary_email": "<stripped UUID>@stack-generated.example.com",
"primary_email": "default-mailbox--<stripped UUID>@stack-generated.example.com",
"primary_email_verified": false,
"profile_image_url": null,
"requires_totp_mfa": false,

View File

@ -21,7 +21,7 @@ it("should sign up new users", async ({ expect }) => {
MailboxMessage {
"from": "Stack Dashboard <noreply@example.com>",
"subject": "Verify your email at Stack Dashboard",
"to": ["<<stripped UUID>@stack-generated.example.com>"],
"to": ["<default-mailbox--<stripped UUID>@stack-generated.example.com>"],
<some fields may have been hidden>,
},
]
@ -40,7 +40,7 @@ it("should sign up new users", async ({ expect }) => {
"oauth_providers": [],
"otp_auth_enabled": false,
"passkey_auth_enabled": false,
"primary_email": "<stripped UUID>@stack-generated.example.com",
"primary_email": "default-mailbox--<stripped UUID>@stack-generated.example.com",
"primary_email_verified": false,
"profile_image_url": null,
"requires_totp_mfa": false,

View File

@ -1,5 +1,5 @@
import { createMailbox, it } from "../../../../../helpers";
import { Auth, ContactChannels, Project, backendContext, niceBackendFetch } from "../../../../backend-helpers";
import { it } from "../../../../../helpers";
import { Auth, ContactChannels, Project, backendContext, createMailbox, niceBackendFetch } from "../../../../backend-helpers";
it("create contact channel on the client", async ({ expect }) => {
await Project.createAndSwitch({ config: { magic_link_enabled: true } });
@ -47,7 +47,7 @@ it("create contact channel on the client", async ({ expect }) => {
"type": "email",
"used_for_auth": true,
"user_id": "<stripped UUID>",
"value": "<stripped UUID>@stack-generated.example.com",
"value": "default-mailbox--<stripped UUID>@stack-generated.example.com",
},
{
"id": "<stripped UUID>",
@ -144,7 +144,7 @@ it("create contact channel on the server", async ({ expect }) => {
"type": "email",
"used_for_auth": true,
"user_id": "<stripped UUID>",
"value": "<stripped UUID>@stack-generated.example.com",
"value": "default-mailbox--<stripped UUID>@stack-generated.example.com",
},
{
"id": "<stripped UUID>",
@ -246,7 +246,7 @@ it("lists current user's contact channels on the client", async ({ expect }) =>
"type": "email",
"used_for_auth": true,
"user_id": "<stripped UUID>",
"value": "<stripped UUID>@stack-generated.example.com",
"value": "default-mailbox--<stripped UUID>@stack-generated.example.com",
},
],
},
@ -343,7 +343,7 @@ it("creates a new account when login with a contact channel that is not used for
"type": "email",
"used_for_auth": false,
"user_id": "<stripped UUID>",
"value": "<stripped UUID>@stack-generated.example.com",
"value": "mailbox-1--<stripped UUID>@stack-generated.example.com",
}
`);
@ -368,7 +368,7 @@ it("creates a new account when login with a contact channel that is not used for
"type": "email",
"used_for_auth": true,
"user_id": "<stripped UUID>",
"value": "<stripped UUID>@stack-generated.example.com",
"value": "mailbox-1--<stripped UUID>@stack-generated.example.com",
},
],
},
@ -408,7 +408,7 @@ it("should update contact channel used for auth to true even if that contact cha
"type": "email",
"used_for_auth": false,
"user_id": "<stripped UUID>",
"value": "<stripped UUID>@stack-generated.example.com",
"value": "mailbox-1--<stripped UUID>@stack-generated.example.com",
}
`);
@ -434,7 +434,7 @@ it("should update contact channel used for auth to true even if that contact cha
"type": "email",
"used_for_auth": true,
"user_id": "<stripped UUID>",
"value": "<stripped UUID>@stack-generated.example.com",
"value": "mailbox-1--<stripped UUID>@stack-generated.example.com",
}
`);
});
@ -470,7 +470,7 @@ it("updates contact channel used for auth", async ({ expect }) => {
"type": "email",
"used_for_auth": false,
"user_id": "<stripped UUID>",
"value": "<stripped UUID>@stack-generated.example.com",
"value": "mailbox-1--<stripped UUID>@stack-generated.example.com",
}
`);
@ -496,7 +496,7 @@ it("updates contact channel used for auth", async ({ expect }) => {
"type": "email",
"used_for_auth": true,
"user_id": "<stripped UUID>",
"value": "<stripped UUID>@stack-generated.example.com",
"value": "mailbox-1--<stripped UUID>@stack-generated.example.com",
}
`);
});
@ -539,7 +539,7 @@ it("updates contact channel primary status", async ({ expect }) => {
"type": "email",
"used_for_auth": false,
"user_id": "<stripped UUID>",
"value": "<stripped UUID>@stack-generated.example.com",
"value": "mailbox-1--<stripped UUID>@stack-generated.example.com",
},
"headers": Headers { <some fields may have been hidden> },
}
@ -563,7 +563,7 @@ it("updates contact channel primary status", async ({ expect }) => {
"oauth_providers": [],
"otp_auth_enabled": true,
"passkey_auth_enabled": false,
"primary_email": "<stripped UUID>@stack-generated.example.com",
"primary_email": "mailbox-1--<stripped UUID>@stack-generated.example.com",
"primary_email_verified": false,
"profile_image_url": null,
"requires_totp_mfa": false,
@ -598,7 +598,7 @@ it("sets a primary contact channel to non-primary", async ({ expect }) => {
"type": "email",
"used_for_auth": true,
"user_id": "<stripped UUID>",
"value": "<stripped UUID>@stack-generated.example.com",
"value": "default-mailbox--<stripped UUID>@stack-generated.example.com",
},
"headers": Headers { <some fields may have been hidden> },
}

View File

@ -45,13 +45,13 @@ it("should send a verification code per e-mail", async ({ expect }) => {
MailboxMessage {
"from": "Stack Dashboard <noreply@example.com>",
"subject": "Verify your email at Stack Dashboard",
"to": ["<<stripped UUID>@stack-generated.example.com>"],
"to": ["<default-mailbox--<stripped UUID>@stack-generated.example.com>"],
<some fields may have been hidden>,
},
MailboxMessage {
"from": "Stack Dashboard <noreply@example.com>",
"subject": "Verify your email at Stack Dashboard",
"to": ["<<stripped UUID>@stack-generated.example.com>"],
"to": ["<default-mailbox--<stripped UUID>@stack-generated.example.com>"],
<some fields may have been hidden>,
},
]

View File

@ -40,13 +40,13 @@ it("should send a verification code per e-mail", async ({ expect }) => {
MailboxMessage {
"from": "Stack Dashboard <noreply@example.com>",
"subject": "Verify your email at Stack Dashboard",
"to": ["<<stripped UUID>@stack-generated.example.com>"],
"to": ["<default-mailbox--<stripped UUID>@stack-generated.example.com>"],
<some fields may have been hidden>,
},
MailboxMessage {
"from": "Stack Dashboard <noreply@example.com>",
"subject": "Verify your email at Stack Dashboard",
"to": ["<<stripped UUID>@stack-generated.example.com>"],
"to": ["<default-mailbox--<stripped UUID>@stack-generated.example.com>"],
<some fields may have been hidden>,
},
]

View File

@ -1,6 +1,6 @@
import { isBase64Url } from "@stackframe/stack-shared/dist/utils/bytes";
import { createMailbox, it } from "../../../../helpers";
import { Auth, InternalProjectKeys, Project, backendContext, niceBackendFetch } from "../../../backend-helpers";
import { it } from "../../../../helpers";
import { Auth, InternalProjectKeys, Project, backendContext, createMailbox, niceBackendFetch } from "../../../backend-helpers";
it("should not have have access to the project without project keys", async ({ expect }) => {

View File

@ -1,5 +1,5 @@
import { createMailbox, it } from "../../../../helpers";
import { Auth, Team, backendContext, niceBackendFetch } from "../../../backend-helpers";
import { it } from "../../../../helpers";
import { Auth, Team, backendContext, createMailbox, niceBackendFetch } from "../../../backend-helpers";
it("requires $invite_members permission to send invitation", async ({ expect }) => {
await Auth.Otp.signIn();

View File

@ -1,5 +1,5 @@
import { createMailbox, it } from "../../../../helpers";
import { Auth, Team, backendContext, niceBackendFetch } from "../../../backend-helpers";
import { it } from "../../../../helpers";
import { Auth, Team, backendContext, createMailbox, niceBackendFetch } from "../../../backend-helpers";
async function signInAndCreateTeam() {
const { userId: userId1 } = await Auth.Otp.signIn();

View File

@ -1,5 +1,5 @@
import { createMailbox, it } from "../../../../helpers";
import { ApiKey, Auth, InternalProjectKeys, Project, Team, backendContext, niceBackendFetch } from "../../../backend-helpers";
import { it } from "../../../../helpers";
import { ApiKey, Auth, InternalProjectKeys, Project, Team, backendContext, createMailbox, niceBackendFetch } from "../../../backend-helpers";
it("is not allowed to add user to team on client", async ({ expect }) => {
@ -78,7 +78,7 @@ it("creates a team and allows managing users on the server", async ({ expect })
"oauth_providers": [],
"otp_auth_enabled": true,
"passkey_auth_enabled": false,
"primary_email": "<stripped UUID>@stack-generated.example.com",
"primary_email": "default-mailbox--<stripped UUID>@stack-generated.example.com",
"primary_email_auth_enabled": true,
"primary_email_verified": true,
"profile_image_url": null,
@ -99,7 +99,7 @@ it("creates a team and allows managing users on the server", async ({ expect })
"oauth_providers": [],
"otp_auth_enabled": true,
"passkey_auth_enabled": false,
"primary_email": "<stripped UUID>@stack-generated.example.com",
"primary_email": "mailbox-1--<stripped UUID>@stack-generated.example.com",
"primary_email_auth_enabled": true,
"primary_email_verified": true,
"profile_image_url": null,
@ -151,7 +151,7 @@ it("creates a team and allows managing users on the server", async ({ expect })
"oauth_providers": [],
"otp_auth_enabled": true,
"passkey_auth_enabled": false,
"primary_email": "<stripped UUID>@stack-generated.example.com",
"primary_email": "default-mailbox--<stripped UUID>@stack-generated.example.com",
"primary_email_auth_enabled": true,
"primary_email_verified": true,
"profile_image_url": null,

View File

@ -1,5 +1,5 @@
import { createMailbox, it } from "../../../../helpers";
import { ApiKey, Auth, Project, Team, backendContext, niceBackendFetch } from "../../../backend-helpers";
import { it } from "../../../../helpers";
import { ApiKey, Auth, Project, Team, backendContext, createMailbox, niceBackendFetch } from "../../../backend-helpers";
it("is not allowed to list all the teams in a project on the client", async ({ expect }) => {
@ -674,7 +674,7 @@ it("enables create team on sign up", async ({ expect }) => {
"client_metadata": null,
"client_read_only_metadata": null,
"created_at_millis": <stripped field 'created_at_millis'>,
"display_name": "<stripped UUID>@stack-generated.example.com's Team",
"display_name": "mailbox-1--<stripped UUID>@stack-generated.example.com's Team",
"id": "<stripped UUID>",
"profile_image_url": null,
"server_metadata": null,

View File

@ -1,7 +1,7 @@
import { generateSecureRandomString } from "@stackframe/stack-shared/dist/utils/crypto";
import { describe } from "vitest";
import { createMailbox, it } from "../../../../helpers";
import { Auth, InternalProjectKeys, Project, backendContext, niceBackendFetch } from "../../../backend-helpers";
import { it } from "../../../../helpers";
import { Auth, InternalProjectKeys, Project, backendContext, createMailbox, niceBackendFetch } from "../../../backend-helpers";
describe("without project access", () => {
backendContext.set({
@ -86,7 +86,7 @@ describe("with client access", () => {
"oauth_providers": [],
"otp_auth_enabled": true,
"passkey_auth_enabled": false,
"primary_email": "<stripped UUID>@stack-generated.example.com",
"primary_email": "default-mailbox--<stripped UUID>@stack-generated.example.com",
"primary_email_verified": true,
"profile_image_url": null,
"requires_totp_mfa": false,
@ -118,7 +118,7 @@ describe("with client access", () => {
"oauth_providers": [],
"otp_auth_enabled": true,
"passkey_auth_enabled": false,
"primary_email": "<stripped UUID>@stack-generated.example.com",
"primary_email": "default-mailbox--<stripped UUID>@stack-generated.example.com",
"primary_email_verified": true,
"profile_image_url": null,
"requires_totp_mfa": false,
@ -195,7 +195,7 @@ describe("with client access", () => {
"oauth_providers": [],
"otp_auth_enabled": true,
"passkey_auth_enabled": false,
"primary_email": "<stripped UUID>@stack-generated.example.com",
"primary_email": "default-mailbox--<stripped UUID>@stack-generated.example.com",
"primary_email_verified": true,
"profile_image_url": null,
"requires_totp_mfa": false,
@ -226,7 +226,7 @@ describe("with client access", () => {
"oauth_providers": [],
"otp_auth_enabled": true,
"passkey_auth_enabled": false,
"primary_email": "<stripped UUID>@stack-generated.example.com",
"primary_email": "default-mailbox--<stripped UUID>@stack-generated.example.com",
"primary_email_verified": true,
"profile_image_url": null,
"requires_totp_mfa": false,
@ -367,7 +367,7 @@ describe("with client access", () => {
"oauth_providers": [],
"otp_auth_enabled": true,
"passkey_auth_enabled": false,
"primary_email": "<stripped UUID>@stack-generated.example.com",
"primary_email": "default-mailbox--<stripped UUID>@stack-generated.example.com",
"primary_email_verified": true,
"profile_image_url": null,
"requires_totp_mfa": false,
@ -398,7 +398,7 @@ describe("with client access", () => {
"oauth_providers": [],
"otp_auth_enabled": true,
"passkey_auth_enabled": false,
"primary_email": "<stripped UUID>@stack-generated.example.com",
"primary_email": "default-mailbox--<stripped UUID>@stack-generated.example.com",
"primary_email_verified": true,
"profile_image_url": null,
"requires_totp_mfa": false,
@ -527,7 +527,7 @@ describe("with client access", () => {
"oauth_providers": [],
"otp_auth_enabled": true,
"passkey_auth_enabled": false,
"primary_email": "<stripped UUID>@stack-generated.example.com",
"primary_email": "default-mailbox--<stripped UUID>@stack-generated.example.com",
"primary_email_verified": true,
"profile_image_url": null,
"requires_totp_mfa": false,
@ -636,7 +636,7 @@ describe("with server access", () => {
"oauth_providers": [],
"otp_auth_enabled": true,
"passkey_auth_enabled": false,
"primary_email": "<stripped UUID>@stack-generated.example.com",
"primary_email": "default-mailbox--<stripped UUID>@stack-generated.example.com",
"primary_email_auth_enabled": true,
"primary_email_verified": true,
"profile_image_url": null,
@ -674,7 +674,7 @@ describe("with server access", () => {
"oauth_providers": [],
"otp_auth_enabled": true,
"passkey_auth_enabled": false,
"primary_email": "<stripped UUID>@stack-generated.example.com",
"primary_email": "default-mailbox--<stripped UUID>@stack-generated.example.com",
"primary_email_auth_enabled": true,
"primary_email_verified": true,
"profile_image_url": null,
@ -728,7 +728,7 @@ describe("with server access", () => {
"oauth_providers": [],
"otp_auth_enabled": true,
"passkey_auth_enabled": false,
"primary_email": "<stripped UUID>@stack-generated.example.com",
"primary_email": "default-mailbox--<stripped UUID>@stack-generated.example.com",
"primary_email_auth_enabled": true,
"primary_email_verified": true,
"profile_image_url": null,
@ -799,7 +799,7 @@ describe("with server access", () => {
"oauth_providers": [],
"otp_auth_enabled": true,
"passkey_auth_enabled": false,
"primary_email": "<stripped UUID>@stack-generated.example.com",
"primary_email": "default-mailbox--<stripped UUID>@stack-generated.example.com",
"primary_email_auth_enabled": true,
"primary_email_verified": true,
"profile_image_url": null,
@ -875,7 +875,7 @@ describe("with server access", () => {
"oauth_providers": [],
"otp_auth_enabled": false,
"passkey_auth_enabled": false,
"primary_email": "<stripped UUID>@stack-generated.example.com",
"primary_email": "default-mailbox--<stripped UUID>@stack-generated.example.com",
"primary_email_auth_enabled": true,
"primary_email_verified": false,
"profile_image_url": null,
@ -956,7 +956,7 @@ describe("with server access", () => {
"oauth_providers": [],
"otp_auth_enabled": false,
"passkey_auth_enabled": false,
"primary_email": "<stripped UUID>@stack-generated.example.com",
"primary_email": "default-mailbox--<stripped UUID>@stack-generated.example.com",
"primary_email_auth_enabled": true,
"primary_email_verified": false,
"profile_image_url": null,
@ -1008,7 +1008,7 @@ describe("with server access", () => {
"oauth_providers": [],
"otp_auth_enabled": false,
"passkey_auth_enabled": false,
"primary_email": "<stripped UUID>@stack-generated.example.com",
"primary_email": "default-mailbox--<stripped UUID>@stack-generated.example.com",
"primary_email_auth_enabled": true,
"primary_email_verified": false,
"profile_image_url": null,
@ -1114,7 +1114,7 @@ describe("with server access", () => {
"oauth_providers": [],
"otp_auth_enabled": false,
"passkey_auth_enabled": false,
"primary_email": "<stripped UUID>@stack-generated.example.com",
"primary_email": "default-mailbox--<stripped UUID>@stack-generated.example.com",
"primary_email_auth_enabled": true,
"primary_email_verified": false,
"profile_image_url": null,
@ -1172,7 +1172,7 @@ describe("with server access", () => {
"oauth_providers": [],
"otp_auth_enabled": false,
"passkey_auth_enabled": false,
"primary_email": "<stripped UUID>@stack-generated.example.com",
"primary_email": "default-mailbox--<stripped UUID>@stack-generated.example.com",
"primary_email_auth_enabled": false,
"primary_email_verified": false,
"profile_image_url": null,
@ -1209,7 +1209,7 @@ describe("with server access", () => {
"oauth_providers": [],
"otp_auth_enabled": false,
"passkey_auth_enabled": false,
"primary_email": "<stripped UUID>@stack-generated.example.com",
"primary_email": "default-mailbox--<stripped UUID>@stack-generated.example.com",
"primary_email_auth_enabled": true,
"primary_email_verified": false,
"profile_image_url": null,
@ -1261,7 +1261,7 @@ describe("with server access", () => {
"oauth_providers": [],
"otp_auth_enabled": false,
"passkey_auth_enabled": false,
"primary_email": "<stripped UUID>@stack-generated.example.com",
"primary_email": "default-mailbox--<stripped UUID>@stack-generated.example.com",
"primary_email_auth_enabled": true,
"primary_email_verified": false,
"profile_image_url": null,
@ -1295,7 +1295,7 @@ describe("with server access", () => {
"oauth_providers": [],
"otp_auth_enabled": false,
"passkey_auth_enabled": false,
"primary_email": "<stripped UUID>@stack-generated.example.com",
"primary_email": "default-mailbox--<stripped UUID>@stack-generated.example.com",
"primary_email_auth_enabled": false,
"primary_email_verified": false,
"profile_image_url": null,
@ -1353,7 +1353,7 @@ describe("with server access", () => {
"oauth_providers": [],
"otp_auth_enabled": true,
"passkey_auth_enabled": false,
"primary_email": "<stripped UUID>@stack-generated.example.com",
"primary_email": "default-mailbox--<stripped UUID>@stack-generated.example.com",
"primary_email_auth_enabled": true,
"primary_email_verified": true,
"profile_image_url": null,
@ -1383,7 +1383,7 @@ describe("with server access", () => {
"oauth_providers": [],
"otp_auth_enabled": true,
"passkey_auth_enabled": false,
"primary_email": "<stripped UUID>@stack-generated.example.com",
"primary_email": "default-mailbox--<stripped UUID>@stack-generated.example.com",
"primary_email_auth_enabled": true,
"primary_email_verified": true,
"profile_image_url": null,
@ -1422,7 +1422,7 @@ describe("with server access", () => {
"oauth_providers": [],
"otp_auth_enabled": true,
"passkey_auth_enabled": false,
"primary_email": "<stripped UUID>@stack-generated.example.com",
"primary_email": "default-mailbox--<stripped UUID>@stack-generated.example.com",
"primary_email_auth_enabled": true,
"primary_email_verified": true,
"profile_image_url": null,
@ -1461,7 +1461,7 @@ describe("with server access", () => {
"oauth_providers": [],
"otp_auth_enabled": true,
"passkey_auth_enabled": false,
"primary_email": "<stripped UUID>@stack-generated.example.com",
"primary_email": "default-mailbox--<stripped UUID>@stack-generated.example.com",
"primary_email_auth_enabled": true,
"primary_email_verified": true,
"profile_image_url": null,
@ -1549,7 +1549,7 @@ describe("with server access", () => {
"oauth_providers": [],
"otp_auth_enabled": true,
"passkey_auth_enabled": false,
"primary_email": "<stripped UUID>@stack-generated.example.com",
"primary_email": "default-mailbox--<stripped UUID>@stack-generated.example.com",
"primary_email_auth_enabled": true,
"primary_email_verified": true,
"profile_image_url": null,

View File

@ -1,9 +1,8 @@
import { generateSecureRandomString } from "@stackframe/stack-shared/dist/utils/crypto";
import { StackAssertionError } from "@stackframe/stack-shared/dist/utils/errors";
import { filterUndefined, omit } from "@stackframe/stack-shared/dist/utils/objects";
import { filterUndefined } from "@stackframe/stack-shared/dist/utils/objects";
import { Nicifiable } from "@stackframe/stack-shared/dist/utils/strings";
import { AsyncLocalStorage } from "node:async_hooks";
import { randomUUID } from "node:crypto";
// eslint-disable-next-line no-restricted-imports
import { afterEach, beforeEach, test as vitestTest } from "vitest";
@ -194,7 +193,7 @@ export async function niceFetch(url: string | URL, options?: NiceRequestInit): P
export const localRedirectUrl = "http://stack-test.localhost/some-callback-url";
export const localRedirectUrlRegex = /http:\/\/stack-test\.localhost\/some-callback-url([?#][A-Za-z0-9\-._~:\/?#\[\]@!$&\'()*+,;=]*)?/g;
const generatedEmailSuffix = "@stack-generated.example.com";
export const generatedEmailSuffix = "@stack-generated.example.com";
export const generatedEmailRegex = /[a-zA-Z0-9_.+\-]+@stack-generated\.example\.com/;
export type Mailbox = { emailAddress: string, fetchMessages: (options?: { noBody?: boolean }) => Promise<MailboxMessage[]> };
@ -231,29 +230,6 @@ export class MailboxMessage {
};
}
export function createMailbox(): Mailbox {
const mailboxName = randomUUID();
const fullMessageCache = new Map<string, any>();
return {
emailAddress: `${mailboxName}${generatedEmailSuffix}`,
async fetchMessages({ noBody } = {}) {
const res = await niceFetch(new URL(`/api/v1/mailbox/${encodeURIComponent(mailboxName)}`, INBUCKET_API_URL));
return await Promise.all((res.body as any[]).map(async (message) => {
let fullMessage: any;
if (fullMessageCache.has(message.id)) {
fullMessage = fullMessageCache.get(message.id);
} else {
const fullMessageRes = await niceFetch(new URL(`/api/v1/mailbox/${encodeURIComponent(mailboxName)}/${message.id}`, INBUCKET_API_URL));
fullMessage = fullMessageRes.body;
fullMessageCache.set(message.id, fullMessage);
}
const messagePart = noBody ? omit(fullMessage, ["body", "attachments"]) : fullMessage;
return new MailboxMessage(messagePart);
}));
},
};
}
export const STACK_DASHBOARD_BASE_URL = getEnvVar("STACK_DASHBOARD_BASE_URL");
export const STACK_BACKEND_BASE_URL = getEnvVar("STACK_BACKEND_BASE_URL");
export const STACK_INTERNAL_PROJECT_ID = getEnvVar("STACK_INTERNAL_PROJECT_ID");