Skip to content

Commit 94a3edd

Browse files
authored
Svix concurrency workaround (stack-auth#167)
1 parent a86788d commit 94a3edd

11 files changed

Lines changed: 65 additions & 17 deletions

File tree

.github/workflows/e2e-api-tests.yaml

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818

1919
strategy:
2020
matrix:
21-
node-version: [20.x]
21+
node-version: [20.x, 22.x]
2222

2323
steps:
2424
- uses: actions/checkout@v3
@@ -36,17 +36,35 @@ jobs:
3636
- name: Install dependencies
3737
run: pnpm install --frozen-lockfile
3838

39-
- name: Create .env.test.local file for stack-backend
39+
- name: Create .env.test.local file for apps/backend
4040
run: cp apps/backend/.env.development apps/backend/.env.test.local
4141

42-
- name: Create .env.test.local file for stack-dashboard
42+
- name: Create .env.test.local file for apps/dashboard
4343
run: cp apps/dashboard/.env.development apps/dashboard/.env.test.local
44+
45+
- name: Create .env.test.local file for apps/e2e
46+
run: cp apps/e2e/.env.development apps/e2e/.env.test.local
4447

45-
- name: Build stack-backend
46-
run: pnpm build:backend
48+
- name: Create .env.test.local file for examples/cjs-test
49+
run: cp examples/cjs-test/.env.development examples/cjs-test/.env.test.local
50+
51+
- name: Create .env.test.local file for examples/demo
52+
run: cp examples/demo/.env.development examples/demo/.env.test.local
4753

48-
- name: Build stack-dashboard
49-
run: pnpm build:dashboard
54+
- name: Create .env.test.local file for examples/docs-examples
55+
run: cp examples/docs-examples/.env.development examples/docs-examples/.env.test.local
56+
57+
- name: Create .env.test.local file for examples/e-commerce
58+
run: cp examples/e-commerce/.env.development examples/e-commerce/.env.test.local
59+
60+
- name: Create .env.test.local file for examples/middleware
61+
run: cp examples/middleware/.env.development examples/middleware/.env.test.local
62+
63+
- name: Create .env.test.local file for examples/partial-prerendering
64+
run: cp examples/partial-prerendering/.env.development examples/partial-prerendering/.env.test.local
65+
66+
- name: Build
67+
run: pnpm build
5068

5169
- name: Start Docker Compose
5270
run: docker compose -f dependencies.compose.yaml up -d
@@ -57,6 +75,9 @@ jobs:
5775
- name: Wait on Inbucket
5876
run: npx wait-on tcp:localhost:2500
5977

78+
- name: Wait on Svix
79+
run: npx wait-on tcp:localhost:8113
80+
6081
- name: Initialize database
6182
run: pnpm run prisma -- migrate reset --force
6283

.github/workflows/lint-and-build.yaml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616

1717
strategy:
1818
matrix:
19-
node-version: [18.x, 20.x]
19+
node-version: [20.x, 22.x]
2020

2121
steps:
2222
- uses: actions/checkout@v3
@@ -66,3 +66,6 @@ jobs:
6666

6767
- name: Lint
6868
run: pnpm lint
69+
70+
- name: Typecheck
71+
run: pnpm typecheck

apps/backend/src/lib/webhooks.tsx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,16 @@ async function sendWebhooks(options: {
1414
const server = getEnvVariable("STACK_SVIX_SERVER_URL", "") || undefined;
1515
const svix = new Svix(apiKey, { serverUrl: server });
1616

17-
await svix.application.getOrCreate({ uid: options.projectId, name: options.projectId });
17+
try {
18+
await svix.application.getOrCreate({ uid: options.projectId, name: options.projectId });
19+
} catch (e: any) {
20+
if (e.message.includes("409")) {
21+
// This is a Svix bug; they are working on fixing it
22+
// TODO next-release: remove this
23+
console.warn("[no action required] Svix bug: 409 error when creating application. Remove this warning when Svix fixes this.");
24+
}
25+
console.warn("Error creating application in Svix", e);
26+
}
1827
await svix.message.create(options.projectId, {
1928
eventType: options.type,
2029
payload: {
@@ -41,4 +50,4 @@ export const sendUserUpdatedWebhook = createWebhookSender(userUpdatedWebhookEven
4150
export const sendUserDeletedWebhook = createWebhookSender(userDeletedWebhookEvent);
4251
export const sendTeamCreatedWebhook = createWebhookSender(teamCreatedWebhookEvent);
4352
export const sendTeamUpdatedWebhook = createWebhookSender(teamUpdatedWebhookEvent);
44-
export const sendTeamDeletedWebhook = createWebhookSender(teamDeletedWebhookEvent);
53+
export const sendTeamDeletedWebhook = createWebhookSender(teamDeletedWebhookEvent);

apps/e2e/tests/general/lint.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,5 @@ describe.todo("`pnpm run lint`", () => {
1010
});
1111
});
1212
expect(error, `Expected no error to be thrown!\n\n\n\nstdout: ${stdout}\n\n\n\nstderr: ${stderr}`).toBeNull();
13-
}, 60_000);
13+
}, 120_000);
1414
});

apps/e2e/tests/general/typecheck.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,5 @@ describe.todo("`pnpm run typecheck`", () => {
1010
});
1111
});
1212
expect(error, `Expected no error to be thrown!\n\n\n\nstdout: ${stdout}\n\n\n\nstderr: ${stderr}`).toBeNull();
13-
}, 60_000);
13+
}, 120_000);
1414
});
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
declare const Handler: (props: any) => JSX.Element;
2+
export default Handler;

examples/cjs-test/app/handler/[...stack]/page.tsx renamed to examples/cjs-test/app/handler/[...stack]/page.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import { StackHandler } from "@stackframe/stack";
1+
const { StackHandler } = require("@stackframe/stack");
22
const { stackServerApp } = require("../../../stack");
33

4-
function Handler(props: any) {
4+
function Handler(props) {
55
return <StackHandler fullPage app={stackServerApp} {...props} />;
66
}
77

examples/cjs-test/app/page.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
declare const Home: (props: any) => JSX.Element;
2+
export default Home;
Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,25 @@
11
import { encodeBase32 } from "./bytes";
2+
import { StackAssertionError } from "./errors";
23
import { globalVar } from "./globals";
34

5+
export function generateRandomValues(array: Uint8Array) {
6+
if (!globalVar.crypto) {
7+
throw new StackAssertionError("Crypto API is not available in this environment. Are you using an old browser?");
8+
}
9+
if (!globalVar.crypto.getRandomValues) {
10+
throw new StackAssertionError("crypto.getRandomValues is not available in this environment. Are you using an old browser?");
11+
}
12+
return globalVar.crypto.getRandomValues(array);
13+
}
14+
415
/**
516
* Generates a secure alphanumeric string using the system's cryptographically secure
617
* random number generator.
718
*/
819
export function generateSecureRandomString(minBitsOfEntropy: number = 224) {
920
const base32CharactersCount = Math.ceil(minBitsOfEntropy / 5);
1021
const bytesCount = Math.ceil(base32CharactersCount * 5 / 8);
11-
const randomBytes = globalVar.crypto.getRandomValues(new Uint8Array(bytesCount));
22+
const randomBytes = generateRandomValues(new Uint8Array(bytesCount));
1223
const str = encodeBase32(randomBytes);
1324
return str.slice(str.length - base32CharactersCount).toLowerCase();
1425
}

0 commit comments

Comments
 (0)