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
2 changes: 2 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.git
**/node_modules
2 changes: 2 additions & 0 deletions .github/workflows/lambda-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ jobs:
with:
node-version: '20'

- name: Build shared lambda-auth package
run: npm ci --prefix shared/lambda-auth && npm run build --prefix shared/lambda-auth
- name: Install dependencies
working-directory: ${{ matrix.lambda }}
run: npm ci --legacy-peer-deps
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/lambda-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ jobs:
node-version: '20'
- name: Setup database schema
run: psql postgres://branch_dev:password@localhost:5432/branch_db -f apps/backend/db/db_setup.sql
- name: Build shared lambda-auth package
run: npm ci --prefix shared/lambda-auth && npm run build --prefix shared/lambda-auth
- name: Install dependencies
working-directory: ${{ matrix.lambda }}
run: npm ci --legacy-peer-deps
Expand Down
3 changes: 0 additions & 3 deletions .gitmodules

This file was deleted.

24 changes: 14 additions & 10 deletions apps/backend/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ services:
# Users Service
users:
build:
context: ./lambdas/users
dockerfile: Dockerfile
context: ../..
dockerfile: apps/backend/lambdas/users/Dockerfile
container_name: branch-users
restart: unless-stopped
environment:
Expand All @@ -36,6 +36,8 @@ services:
DB_USER: ${DB_USER:-branch_dev}
DB_PASSWORD: ${DB_PASSWORD:-password}
DB_NAME: ${DB_NAME:-branch_db}
COGNITO_USER_POOL_ID: ${COGNITO_USER_POOL_ID}
COGNITO_CLIENT_ID: ${COGNITO_CLIENT_ID}
ports:
- '3001:3000'
depends_on:
Expand All @@ -45,8 +47,8 @@ services:
# Projects Service
projects:
build:
context: ./lambdas/projects
dockerfile: Dockerfile
context: ../..
dockerfile: apps/backend/lambdas/projects/Dockerfile
container_name: branch-projects
restart: unless-stopped
environment:
Expand All @@ -55,6 +57,8 @@ services:
DB_USER: ${DB_USER:-branch_dev}
DB_PASSWORD: ${DB_PASSWORD:-password}
DB_NAME: ${DB_NAME:-branch_db}
COGNITO_USER_POOL_ID: ${COGNITO_USER_POOL_ID}
COGNITO_CLIENT_ID: ${COGNITO_CLIENT_ID}
ports:
- '3002:3000'
depends_on:
Expand All @@ -64,8 +68,8 @@ services:
# Donors Service
donors:
build:
context: ./lambdas/donors
dockerfile: Dockerfile
context: ../..
dockerfile: apps/backend/lambdas/donors/Dockerfile
container_name: branch-donors
restart: unless-stopped
environment:
Expand All @@ -85,8 +89,8 @@ services:
# Expenditures Service
expenditures:
build:
context: ./lambdas/expenditures
dockerfile: Dockerfile
context: ../..
dockerfile: apps/backend/lambdas/expenditures/Dockerfile
container_name: branch-expenditures
restart: unless-stopped
environment:
Expand All @@ -106,8 +110,8 @@ services:
# Reports Service
reports:
build:
context: ./lambdas/reports
dockerfile: Dockerfile
context: ../..
dockerfile: apps/backend/lambdas/reports/Dockerfile
container_name: branch-reports
restart: unless-stopped
environment:
Expand Down
20 changes: 8 additions & 12 deletions apps/backend/lambdas/donors/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,22 +1,18 @@
FROM node:20-alpine

WORKDIR /app

# Copy package files
COPY package*.json ./
WORKDIR /shared/lambda-auth
COPY shared/lambda-auth/package.json shared/lambda-auth/tsconfig.json ./
COPY shared/lambda-auth/src ./src/
RUN npm install && npm run build

# Install dependencies
RUN npm install

# Copy source files
COPY . .
WORKDIR /app
COPY apps/backend/lambdas/donors/package*.json ./
RUN npm install --no-package-lock
COPY apps/backend/lambdas/donors/ .

# Expose port
EXPOSE 3000

# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost:3000/donors/health || exit 1

# Start the dev server
CMD ["npm", "run", "dev"]
94 changes: 6 additions & 88 deletions apps/backend/lambdas/donors/auth.ts
Original file line number Diff line number Diff line change
@@ -1,92 +1,10 @@
import { CognitoJwtVerifier } from 'aws-jwt-verify';
import { authenticateRequest as _authenticateRequest } from '@branch/lambda-auth';
import db from './db';

const COGNITO_USER_POOL_ID = process.env.COGNITO_USER_POOL_ID!;
const COGNITO_CLIENT_ID = process.env.COGNITO_APP_CLIENT_ID!;
export * from '@branch/lambda-auth';

// Create verifier instance lazily (only when needed)
let verifier: any = null;

function getVerifier() {
if (!verifier) {
if (!COGNITO_USER_POOL_ID) {
throw new Error('COGNITO_USER_POOL_ID environment variable is not set');
}
verifier = CognitoJwtVerifier.create({
userPoolId: COGNITO_USER_POOL_ID,
tokenUse: 'access',
clientId: COGNITO_CLIENT_ID,
});
}
return verifier;
}

export interface AuthenticatedUser {
cognitoSub: string;
userId?: number;
email: string;
isAdmin?: boolean;
cognitoGroups?: string[];
}

export interface AuthContext {
user?: AuthenticatedUser;
isAuthenticated: boolean;
export async function authenticateRequest(
event: any,
): Promise<import('@branch/lambda-auth').AuthContext> {
return _authenticateRequest(db, event);
}

/**
* Encode a JWT token
*/
function extractToken(event: any): string | null {
const authHeader = event.headers?.authorization || event.headers?.Authorization;

if (!authHeader) {
return null;
}

const parts = authHeader.split(' ');
if (parts.length === 2 && parts[0].toLowerCase() === 'bearer') {
return parts[1];
}

return authHeader;
}

export async function authenticateRequest(event: any): Promise<AuthContext> {
const token = extractToken(event);

if (!token) {
return { isAuthenticated: false };
}

try {
const payload = await getVerifier().verify(token);

const dbUser = await db
.selectFrom('branch.users')
.where('cognito_sub', '=', payload.sub)
.selectAll()
.executeTakeFirst();

if (!dbUser) {
return { isAuthenticated: false };
}

const user: AuthenticatedUser = {
cognitoSub: payload.sub,
email: payload.email,
userId: dbUser.user_id,
isAdmin: dbUser.is_admin || false,
cognitoGroups: payload['cognito:groups'] || [],
};

if (user.cognitoGroups?.includes('Admins')) {
user.isAdmin = true;
}

return { user, isAuthenticated: true };
} catch (error) {
console.error('Authentication error:', error);
return { isAuthenticated: false };
}
}
15 changes: 15 additions & 0 deletions apps/backend/lambdas/donors/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions apps/backend/lambdas/donors/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"typescript": "^5.4.5"
},
"dependencies": {
"@branch/lambda-auth": "file:../../../../shared/lambda-auth",
"aws-jwt-verify": "^5.1.1",
"jest": "^30.2.0",
"kysely": "^0.28.8",
Expand Down
20 changes: 8 additions & 12 deletions apps/backend/lambdas/expenditures/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,22 +1,18 @@
FROM node:20-alpine

WORKDIR /app

# Copy package files
COPY package*.json ./
WORKDIR /shared/lambda-auth
COPY shared/lambda-auth/package.json shared/lambda-auth/tsconfig.json ./
COPY shared/lambda-auth/src ./src/
RUN npm install && npm run build

# Install dependencies
RUN npm install

# Copy source files
COPY . .
WORKDIR /app
COPY apps/backend/lambdas/expenditures/package*.json ./
RUN npm install --no-package-lock
COPY apps/backend/lambdas/expenditures/ .

# Expose port
EXPOSE 3000

# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost:3000/expenditures/health || exit 1

# Start the dev server
CMD ["npm", "run", "dev"]
Loading
Loading