mirror of
https://github.com/stack-auth/stack.git
synced 2026-06-04 21:04:37 +08:00
Merge branch 'dev' into promptless/document-developer-tools
Some checks failed
DB migration compat / Check if migrations changed (push) Has been cancelled
DB migration compat / Back-compat — Current branch migrations with ${{ needs.check-migrations-changed.outputs.base_branch }} branch code (push) Has been cancelled
DB migration compat / Forward-compat — Current branch code with ${{ needs.check-migrations-changed.outputs.base_branch }} branch migrations (push) Has been cancelled
DB migration compat / No migration changes (skipped) (push) Has been cancelled
Some checks failed
DB migration compat / Check if migrations changed (push) Has been cancelled
DB migration compat / Back-compat — Current branch migrations with ${{ needs.check-migrations-changed.outputs.base_branch }} branch code (push) Has been cancelled
DB migration compat / Forward-compat — Current branch code with ${{ needs.check-migrations-changed.outputs.base_branch }} branch migrations (push) Has been cancelled
DB migration compat / No migration changes (skipped) (push) Has been cancelled
This commit is contained in:
commit
a5d9a4c656
@ -181,6 +181,22 @@ export async function updateManagedEmailDomainWebhookStatus(options: {
|
||||
return mapRow(rows[0]!);
|
||||
}
|
||||
|
||||
export async function demoteOtherAppliedManagedEmailDomains(options: {
|
||||
tenancyId: string,
|
||||
keepId: string,
|
||||
}): Promise<void> {
|
||||
await globalPrismaClient.$queryRaw(Prisma.sql`
|
||||
UPDATE "ManagedEmailDomain"
|
||||
SET
|
||||
"status" = 'VERIFIED'::"ManagedEmailDomainStatus",
|
||||
"appliedAt" = NULL,
|
||||
"updatedAt" = CURRENT_TIMESTAMP
|
||||
WHERE "tenancyId" = ${options.tenancyId}
|
||||
AND "id" <> ${options.keepId}
|
||||
AND "status" = 'APPLIED'::"ManagedEmailDomainStatus"
|
||||
`);
|
||||
}
|
||||
|
||||
export async function markManagedEmailDomainApplied(id: string): Promise<ManagedEmailDomain> {
|
||||
const rows = await globalPrismaClient.$queryRaw<ManagedEmailDomainRow[]>(Prisma.sql`
|
||||
UPDATE "ManagedEmailDomain"
|
||||
|
||||
@ -3,6 +3,7 @@ import {
|
||||
ManagedEmailDomain,
|
||||
ManagedEmailDomainStatus,
|
||||
createManagedEmailDomain,
|
||||
demoteOtherAppliedManagedEmailDomains,
|
||||
getManagedEmailDomainByResendDomainId,
|
||||
getManagedEmailDomainByTenancyAndSubdomain,
|
||||
listManagedEmailDomainsForTenancy,
|
||||
@ -12,6 +13,7 @@ import {
|
||||
import { Tenancy } from "@/lib/tenancies";
|
||||
import { getNodeEnvironment, getEnvVariable } from "@stackframe/stack-shared/dist/utils/env";
|
||||
import { StackAssertionError, StatusError } from "@stackframe/stack-shared/dist/utils/errors";
|
||||
import { runAsynchronously, wait } from "@stackframe/stack-shared/dist/utils/promises";
|
||||
|
||||
type ResendDomainRecord = {
|
||||
record: string,
|
||||
@ -543,7 +545,16 @@ export async function setupManagedEmailProvider(options: { subdomain: string, se
|
||||
senderLocalPart: options.senderLocalPart,
|
||||
resendDomainId: `managed_mock_${options.tenancy.id}_${normalizedSubdomain}`.replace(/[^a-zA-Z0-9_-]/g, "_"),
|
||||
nameServerRecords: ["ns1.dnsimple.com", "ns2.dnsimple.com"],
|
||||
status: "verified",
|
||||
status: "pending_verification",
|
||||
});
|
||||
runAsynchronously(async () => {
|
||||
await wait(1000);
|
||||
await updateManagedEmailDomainWebhookStatus({
|
||||
resendDomainId: row.resendDomainId,
|
||||
providerStatusRaw: "verified",
|
||||
status: "verified",
|
||||
lastError: null,
|
||||
});
|
||||
});
|
||||
return managedDomainToSetupResult(row);
|
||||
}
|
||||
@ -631,6 +642,10 @@ export async function applyManagedEmailProvider(options: {
|
||||
senderLocalPart: domain.senderLocalPart,
|
||||
});
|
||||
|
||||
await demoteOtherAppliedManagedEmailDomains({
|
||||
tenancyId: options.tenancy.id,
|
||||
keepId: domain.id,
|
||||
});
|
||||
await markManagedEmailDomainApplied(domain.id);
|
||||
return { status: "applied" };
|
||||
}
|
||||
|
||||
3
apps/dashboard/public/assets/resend-icon-black.svg
Normal file
3
apps/dashboard/public/assets/resend-icon-black.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="1800" height="1800" viewBox="0 0 1800 1800" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M1000.46 450C1174.77 450 1278.43 553.669 1278.43 691.282C1278.43 828.896 1174.77 932.563 1000.46 932.563H912.382L1350 1350H1040.82L707.794 1033.48C683.944 1011.47 672.936 985.781 672.935 963.765C672.935 932.572 694.959 905.049 737.161 893.122L908.712 847.244C973.85 829.812 1018.81 779.353 1018.81 713.298C1018.8 632.567 952.745 585.78 871.095 585.78H450V450H1000.46Z" fill="black"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 504 B |
3
apps/dashboard/public/assets/resend-icon-white.svg
Normal file
3
apps/dashboard/public/assets/resend-icon-white.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="1800" height="1800" viewBox="0 0 1800 1800" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M1000.46 450C1174.77 450 1278.43 553.669 1278.43 691.282C1278.43 828.896 1174.77 932.563 1000.46 932.563H912.382L1350 1350H1040.82L707.794 1033.48C683.944 1011.47 672.936 985.781 672.935 963.765C672.935 932.572 694.959 905.049 737.161 893.122L908.712 847.244C973.85 829.812 1018.81 779.353 1018.81 713.298C1018.8 632.567 952.745 585.78 871.095 585.78H450V450H1000.46Z" fill="#FDFDFD"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 506 B |
File diff suppressed because it is too large
Load Diff
@ -1,3 +1,4 @@
|
||||
import { wait } from "@stackframe/stack-shared/dist/utils/promises";
|
||||
import { describe } from "vitest";
|
||||
import { it } from "../../../../../helpers";
|
||||
import { Project, niceBackendFetch } from "../../../../backend-helpers";
|
||||
@ -48,7 +49,12 @@ describe("managed email onboarding internal endpoints", () => {
|
||||
|
||||
expect(setupResponse.status).toBe(200);
|
||||
expect(setupResponse.body.domain_id).toBeDefined();
|
||||
expect(setupResponse.body.status).toBe("verified");
|
||||
expect(setupResponse.body.status).toBe("pending_verification");
|
||||
|
||||
// Mock onboarding asynchronously flips status to "verified" ~1s after setup
|
||||
// (mirroring the real Resend webhook flow). Wait for the transition before
|
||||
// asserting verified state.
|
||||
await wait(1500);
|
||||
|
||||
const listResponse = await niceBackendFetch("/api/v1/internal/emails/managed-onboarding/list", {
|
||||
method: "GET",
|
||||
|
||||
Loading…
Reference in New Issue
Block a user