Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
DEBUG=surface:*
SELF_RPC_HOST=http://localhost:4000
JWT_SECRET=sup4h.secr1t.jwt.🔑

WORKOS_API_KEY=your-work-os-api-key
WORKOS_CLIENT_ID=your-workos-client-id
WORKOS_REDIRECT_URI=http://localhost:4000/auth/callback
15 changes: 9 additions & 6 deletions .github/workflows/deploy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ jobs:
name: "Test"
runs-on: ubuntu-latest
env:
JWT_SECRET: "test.fake.secret"
WORKOS_API_KEY: "test.workos.api.key"
WORKOS_CLIENT_ID: "test.client.id"
WORKOS_REDIRECT_URI: "http://localhost:3000/auth/callback"
NODE_ENV: "test"
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v1
Expand All @@ -36,7 +39,7 @@ jobs:
- name: "Push to AR"
run: |
docker build . \
-f Dockerfile.node \
-f Dockerfile.bun \
-t ${{ secrets.GCP_AR_PATH }}/app:${GITHUB_SHA::6} \
-t ${{ secrets.GCP_AR_PATH }}/app:latest
docker push ${{ secrets.GCP_AR_PATH }}/app:${GITHUB_SHA::6}
Expand All @@ -55,14 +58,14 @@ jobs:

- name: "Deploy"
run: |
echo "***DO NOT USE*** THESE VALUES IN PRODUCTION!"
echo "USE SECRETS MANAGER FOR JWT SIGNING KEY, OR A THIRD PARTY PROVIDER LIKE HASHICORP."
echo "DEBUG: surface:*" >> env.yaml
echo "SELF_RPC_HOST: https://surface-demo-app-5v6fvk5ela-uw.a.run.app/" >> env.yaml
echo "JWT_SECRET: sup4h.secr1t.jwt.🔑" >> env.yaml
echo "SELF_RPC_HOST: https://surface.makeitstable.com/" >> env.yaml
echo "NODE_ENV: production" >> env.yaml
echo "WORKOS_REDIRECT_URI: https://surface.makeitstable.com/auth/callback" >> env.yaml
gcloud run deploy surface-demo-app \
--image "${{ secrets.GCP_AR_PATH }}/app:${GITHUB_SHA::6}" \
--env-vars-file env.yaml \
--set-secrets="WORKOS_API_KEY=WORKOS_API_KEY:latest,WORKOS_CLIENT_ID=WORKOS_CLIENT_ID:latest" \
--service-account ${{ secrets.GCP_APP_SERVICE_ACCOUNT }} \
--region us-west1 \
--allow-unauthenticated
4 changes: 2 additions & 2 deletions Dockerfile.bun
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ FROM base as dev
CMD ["bun", "run", "dev:docker"]

FROM base as prod
RUN bunx tsr generate
CMD ["bun", "surface.server.bun.ts"]
RUN bun run build
CMD ["bun", "surface.server.bun.ts"]
Binary file modified bun.lockb
Binary file not shown.
3 changes: 2 additions & 1 deletion docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ services:
- DEBUG=surface:*
- JWT_SECRET=foo.bar.baz
- SELF_RPC_HOST=http://dev:4000

env_file:
- .env
ports:
- "4000:4000"

Expand Down
24 changes: 23 additions & 1 deletion handlers/error.handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@ import { SurfaceContext } from "../surface.app.ctx";

export class PingError extends Error {}

export class AuthError extends Error {
constructor(
message: string,
public readonly code: string = "AUTH_FAILED",
) {
super(message);
}
}

export const errorHandler = (err: unknown, c: SurfaceContext): Response => {
const { error } = c.var.logger;
const { text, json } = c;
Expand All @@ -10,7 +19,20 @@ export const errorHandler = (err: unknown, c: SurfaceContext): Response => {
error(`some kind of error happened: ${err}`);
return text("oh noes", 418);
}

if (err instanceof AuthError) {
error(`Authentication error: ${err.message}`, err);
return json(
{
error: "Authentication failed",
code: err.code,
message: err.message,
},
401,
);
}

// unknown error
error(`unhandled service error type: ${err}`, err);
return json({}, 500);
return json({ error: "Internal server error" }, 500);
};
Loading