Skip to content
Merged
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
2 changes: 1 addition & 1 deletion .github/actions/deploy-service/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ runs:
docker ps -a --filter "publish=$PUBLISH_PORT" --format "{{.ID}}" | xargs -r docker rm

echo "Starting new Docker container..."
docker run -d --name $TARGET_APP -p $PUBLISH_PORT:8080 --restart unless-stopped --env-file .env ${{ inputs.aws_ecr_uri }}/$TARGET_APP:$DEPLOY_TAG
docker run -d --name $TARGET_APP -p $PUBLISH_PORT:8080 --restart unless-stopped --env-file .env -e SENTRY_RELEASE=$TARGET_APP@$DEPLOY_TAG ${{ inputs.aws_ecr_uri }}/$TARGET_APP:$DEPLOY_TAG

echo "Cleaning up old Docker images..."
docker images --format '{{.Repository}} {{.Tag}}' | \
Expand Down
11 changes: 11 additions & 0 deletions apps/auth/app.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
// Auth service using Express
import './instrument.js';
import * as Sentry from '@sentry/node';
import { config } from 'dotenv';
const dotenvResult = config();

Check warning on line 5 in apps/auth/app.ts

View workflow job for this annotation

GitHub Actions / lint-and-typecheck

'dotenvResult' is assigned a value but never used

import { auth } from '@wxyc/authentication';
import { toNodeHandler } from 'better-auth/node';
import cors from 'cors';
import express from 'express';
import type { Request, Response, NextFunction } from 'express';

const port = process.env.AUTH_PORT || '8080';

Expand Down Expand Up @@ -51,7 +54,7 @@
}

const userId = userResult[0].id;
const tokenPrefix = `${type}:`;

Check warning on line 57 in apps/auth/app.ts

View workflow job for this annotation

GitHub Actions / lint-and-typecheck

Invalid type "string | ParsedQs | (string | ParsedQs)[]" of template literal expression

Check warning on line 57 in apps/auth/app.ts

View workflow job for this annotation

GitHub Actions / lint-and-typecheck

'type' may use Object's default stringification format ('[object Object]') when stringified
const result = await db
.select()
.from(verification)
Expand All @@ -60,7 +63,7 @@
.limit(1);

if (result.length === 0) {
return res.status(404).json({ error: `No ${type} token found for this user` });

Check warning on line 66 in apps/auth/app.ts

View workflow job for this annotation

GitHub Actions / lint-and-typecheck

Invalid type "string | ParsedQs | (string | ParsedQs)[]" of template literal expression

Check warning on line 66 in apps/auth/app.ts

View workflow job for this annotation

GitHub Actions / lint-and-typecheck

'type' may use Object's default stringification format ('[object Object]') when stringified
}

// Extract the actual token from the identifier (e.g., "reset-password:abc123" -> "abc123")
Expand All @@ -81,7 +84,7 @@
// Expire a user's session for testing session timeout
app.post('/auth/test/expire-session', async (req, res) => {
try {
const { userId } = req.body;

Check warning on line 87 in apps/auth/app.ts

View workflow job for this annotation

GitHub Actions / lint-and-typecheck

Unsafe assignment of an `any` value
if (!userId || typeof userId !== 'string') {
return res.status(400).json({ error: 'userId is required in request body' });
}
Expand Down Expand Up @@ -119,7 +122,7 @@
const response = await fetch(`${authServiceUrl}/auth/ok`);

// Forward the status and body from the /auth/ok response
const data = await response.json(); // Assuming /auth/ok returns JSON

Check warning on line 125 in apps/auth/app.ts

View workflow job for this annotation

GitHub Actions / lint-and-typecheck

Unsafe assignment of an `any` value
res.status(response.status).json(data);
} catch (error) {
console.error('Error proxying /healthcheck to /auth/ok:', error);
Expand All @@ -128,6 +131,14 @@
}
});

Sentry.setupExpressErrorHandler(app);

// Fallback error handler
app.use((err: any, req: Request, res: Response, next: NextFunction) => {

Check warning on line 137 in apps/auth/app.ts

View workflow job for this annotation

GitHub Actions / lint-and-typecheck

'next' is defined but never used. Allowed unused args must match /^_/u

Check warning on line 137 in apps/auth/app.ts

View workflow job for this annotation

GitHub Actions / lint-and-typecheck

Unexpected any. Specify a different type
const message = err instanceof Error ? err.message : String(err);
res.status(500).json({ error: message });
});

// Create default user if needed
const createDefaultUser = async () => {
if (process.env.CREATE_DEFAULT_USER !== 'TRUE') return;
Expand Down Expand Up @@ -201,7 +212,7 @@
},
});

organizationId = newOrganization.id;

Check warning on line 215 in apps/auth/app.ts

View workflow job for this annotation

GitHub Actions / lint-and-typecheck

Unsafe assignment of an `any` value
}

if (!organizationId) {
Expand Down
8 changes: 8 additions & 0 deletions apps/auth/instrument.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import * as Sentry from '@sentry/node';

Sentry.init({
dsn: process.env.SENTRY_DSN,
release: process.env.SENTRY_RELEASE,
environment: process.env.NODE_ENV || 'development',
tracesSampleRate: 1.0,
});
3 changes: 2 additions & 1 deletion apps/auth/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@
"author": "Jackson Meade",
"license": "MIT",
"dependencies": {
"@wxyc/database": "^1.0.0",
"@sentry/node": "^10.40.0",
"@wxyc/authentication": "^1.0.0",
"@wxyc/database": "^1.0.0",
"better-auth": "^1.3.23",
"cors": "^2.8.5",
"dotenv": "^17.2.1",
Expand Down
2 changes: 1 addition & 1 deletion apps/auth/tsup.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export default defineConfig((options) => ({
target: 'node20',
clean: true,
sourcemap: true,
external: ['@wxyc/database', 'better-auth', 'drizzle-orm', 'express', 'cors', 'postgres'],
external: ['@wxyc/database', 'better-auth', 'drizzle-orm', 'express', 'cors', 'postgres', '@sentry/node'],
env: {
NODE_ENV: process.env.NODE_ENV || 'development',
},
Expand Down
10 changes: 9 additions & 1 deletion apps/backend/app.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import './instrument.js';
import * as Sentry from '@sentry/node';
import express from 'express';
import cors from 'cors';
import swaggerUi from 'swagger-ui-express';
Expand All @@ -13,6 +15,7 @@ import { request_line_route } from './routes/requestLine.route.js';
import { showMemberMiddleware } from './middleware/checkShowMember.js';
import { activeShow } from './middleware/checkActiveShow.js';
import errorHandler from './middleware/errorHandler.js';
import { requestIdMiddleware } from './middleware/requestId.js';
import { requirePermissions } from '@wxyc/authentication';

const port = process.env.PORT || 8080;
Expand All @@ -23,12 +26,16 @@ app.set('trust proxy', true);
//Interpret parse json into js objects
app.use(express.json());

// Cross-service request correlation
app.use(requestIdMiddleware);

//CORS
app.use(
cors({
origin: process.env.FRONTEND_SOURCE || '*',
methods: ['GET', 'POST', 'DELETE', 'PATCH'],
allowedHeaders: ['Content-Type', 'Authorization'],
allowedHeaders: ['Content-Type', 'Authorization', 'X-Request-Id'],
exposedHeaders: ['X-Request-Id'],
credentials: true,
})
);
Expand Down Expand Up @@ -69,6 +76,7 @@ app.get('/healthcheck', async (req, res) => {
res.json({ message: 'Healthy!' });
});

Sentry.setupExpressErrorHandler(app);
app.use(errorHandler);

const server = app.listen(port, () => {
Expand Down
8 changes: 8 additions & 0 deletions apps/backend/instrument.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import * as Sentry from '@sentry/node';

Sentry.init({
dsn: process.env.SENTRY_DSN,
release: process.env.SENTRY_RELEASE,
environment: process.env.NODE_ENV || 'development',
tracesSampleRate: 1.0,
});
11 changes: 11 additions & 0 deletions apps/backend/middleware/requestId.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import * as Sentry from '@sentry/node';
import type { Request, Response, NextFunction } from 'express';

export function requestIdMiddleware(req: Request, res: Response, next: NextFunction) {
const requestId = req.get('X-Request-Id') || crypto.randomUUID();

res.setHeader('X-Request-Id', requestId);
Sentry.getCurrentScope().setTag('request_id', requestId);

next();
}
1 change: 1 addition & 0 deletions apps/backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"author": "AyBruno",
"license": "MIT",
"dependencies": {
"@sentry/node": "^10.40.0",
"@wxyc/authentication": "*",
"@wxyc/database": "*",
"async-mutex": "^0.5.0",
Expand Down
2 changes: 2 additions & 0 deletions apps/backend/tsup.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ export default defineConfig((options) => ({
format: ['esm'],
outDir: 'dist',
clean: true,
sourcemap: true,
external: ['@sentry/node'],
onSuccess: options.watch ? 'node ./dist/app.js' : undefined,
minify: !options.watch,

Expand Down
Loading