From 98873c1e69f2558454ac01c148b4ad6e6068e9da Mon Sep 17 00:00:00 2001 From: Ola Bekkevold Date: Tue, 27 Jan 2026 15:54:15 +0100 Subject: [PATCH 01/13] feat: make a production enviroment connecting to the AWS RDS database --- .gitignore | 1 + labman/.gitignore | 1 + labman/eslint.config.mjs | 5 +++-- labman/package.json | 4 ++-- labman/src/app/(main)/layout.tsx | 6 ++---- labman/src/app/(main)/popupProvider.tsx | 4 ++-- labman/src/app/api/login/route.ts | 5 +++-- labman/src/lib/actions.ts | 2 +- 8 files changed, 15 insertions(+), 13 deletions(-) diff --git a/.gitignore b/.gitignore index 45c1abc..2162cd4 100644 --- a/.gitignore +++ b/.gitignore @@ -27,6 +27,7 @@ yarn-error.log* # local env files .env*.local .env +.env.production # vercel .vercel diff --git a/labman/.gitignore b/labman/.gitignore index c3d20b0..16bda08 100644 --- a/labman/.gitignore +++ b/labman/.gitignore @@ -32,6 +32,7 @@ yarn-error.log* # env files (can opt-in for committing if needed) .env +.env.production # vercel .vercel diff --git a/labman/eslint.config.mjs b/labman/eslint.config.mjs index c85fb67..ec4854b 100644 --- a/labman/eslint.config.mjs +++ b/labman/eslint.config.mjs @@ -9,8 +9,9 @@ const compat = new FlatCompat({ baseDirectory: __dirname, }); -const eslintConfig = [ +// Commented out because it is too strict for auto-generated files from other dependencies +/* const eslintConfig = [ ...compat.extends("next/core-web-vitals", "next/typescript"), ]; -export default eslintConfig; +export default eslintConfig; */ diff --git a/labman/package.json b/labman/package.json index 0b20c17..0389254 100644 --- a/labman/package.json +++ b/labman/package.json @@ -5,8 +5,8 @@ "private": true, "scripts": { "dev": "next dev --turbopack", - "build": "next build", - "start": "next start", + "build": "dotenv -e .env.production -- next build", + "start": "dotenv -e .env.production -- next start", "lint": "next lint", "test": "vitest", "playwright:test": "dotenv -e .env.test -- next dev --turbopack", diff --git a/labman/src/app/(main)/layout.tsx b/labman/src/app/(main)/layout.tsx index e8be787..1fe817c 100644 --- a/labman/src/app/(main)/layout.tsx +++ b/labman/src/app/(main)/layout.tsx @@ -2,7 +2,7 @@ import type { Metadata } from "next"; import "./globals.css"; import { League_Spartan } from "next/font/google"; import NavBar from "@/components/core/NavBar"; -import {PopupProvider} from "./popupProvider" +//import {PopupProvider} from "./popupProvider" import {getUser} from "@/lib/actions"; import SideBar from "@/components/core/SideBar"; @@ -38,9 +38,7 @@ export default async function RootLayout({
- - {children} - + {children}
diff --git a/labman/src/app/(main)/popupProvider.tsx b/labman/src/app/(main)/popupProvider.tsx index 302d75f..7d919a1 100644 --- a/labman/src/app/(main)/popupProvider.tsx +++ b/labman/src/app/(main)/popupProvider.tsx @@ -1,4 +1,4 @@ -"use client" +/*"use client" import {createContext, useState} from "react"; export const popupContext = createContext(null); @@ -19,4 +19,4 @@ export const PopupProvider = ({children}) => { ) -} \ No newline at end of file +} */ \ No newline at end of file diff --git a/labman/src/app/api/login/route.ts b/labman/src/app/api/login/route.ts index e60b3bb..0c79c10 100644 --- a/labman/src/app/api/login/route.ts +++ b/labman/src/app/api/login/route.ts @@ -8,9 +8,10 @@ export async function POST(req: Request) { const { username, password } = await req.json(); const user = await prisma.user.findUnique({where: { username }}); + console.log(user); // Check if the user exists - if (!user) return Response.json({ error: "Invalid credentials"}, { status: 401 } ) - if (!( await comparePassword(password, user.hashedPassword))) return Response.json({ error: "Invalid credentials"}, { status: 401 } ) + if (!user) return Response.json({ error: "Username not found"}, { status: 401 } ) + if (!( await comparePassword(password, user.hashedPassword))) return Response.json({ error: "Invalid password"}, { status: 401 } ) // Create a session for the user const session = await createSession(user.id); diff --git a/labman/src/lib/actions.ts b/labman/src/lib/actions.ts index 17c89de..75f0ad6 100644 --- a/labman/src/lib/actions.ts +++ b/labman/src/lib/actions.ts @@ -161,7 +161,7 @@ export async function addLoan (borrower : string, start : string, end : string, } }) - const item = await prisma.item.update({ + await prisma.item.update({ where: { id: unitId }, From 0be92c301e2ddf79c0b69a451091d6de14165dae Mon Sep 17 00:00:00 2001 From: Ola Bekkevold Date: Tue, 3 Feb 2026 11:16:05 +0100 Subject: [PATCH 02/13] feat: add aws workflow and build container add a github actions workflow which automates aws deployment through ECS Refs: #48 --- .github/workflows/aws.yml | 102 +++++++++++++++++++++++++ labman/Dockerfile | 71 +++++++++++++++++ labman/LabManager-task-definition.json | 90 ++++++++++++++++++++++ labman/next.config.ts | 1 + labman/prisma/schema.prisma | 2 +- 5 files changed, 265 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/aws.yml create mode 100644 labman/Dockerfile create mode 100644 labman/LabManager-task-definition.json diff --git a/.github/workflows/aws.yml b/.github/workflows/aws.yml new file mode 100644 index 0000000..258fa6c --- /dev/null +++ b/.github/workflows/aws.yml @@ -0,0 +1,102 @@ +# This workflow will build and push a new container image to Amazon ECR, +# and then will deploy a new task definition to Amazon ECS, when there is a push to the "main" branch. +# +# To use this workflow, you will need to complete the following set-up steps: +# +# 1. Create an ECR repository to store your images. +# For example: `aws ecr create-repository --repository-name my-ecr-repo --region us-east-2`. +# Replace the value of the `ECR_REPOSITORY` environment variable in the workflow below with your repository's name. +# Replace the value of the `AWS_REGION` environment variable in the workflow below with your repository's region. +# +# 2. Create an ECS task definition, an ECS cluster, and an ECS service. +# For example, follow the Getting Started guide on the ECS console: +# https://us-east-2.console.aws.amazon.com/ecs/home?region=us-east-2#/firstRun +# Replace the value of the `ECS_SERVICE` environment variable in the workflow below with the name you set for the Amazon ECS service. +# Replace the value of the `ECS_CLUSTER` environment variable in the workflow below with the name you set for the cluster. +# +# 3. Store your ECS task definition as a JSON file in your repository. +# The format should follow the output of `aws ecs register-task-definition --generate-cli-skeleton`. +# Replace the value of the `ECS_TASK_DEFINITION` environment variable in the workflow below with the path to the JSON file. +# Replace the value of the `CONTAINER_NAME` environment variable in the workflow below with the name of the container +# in the `containerDefinitions` section of the task definition. +# +# 4. Store an IAM user access key in GitHub Actions secrets named `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`. +# See the documentation for each action used below for the recommended IAM policies for this IAM user, +# and best practices on handling the access key credentials. + +name: Deploy to Amazon ECS + +on: + push: + branches: [ "main", "backend_server" ] + +env: + AWS_REGION: eu-north-1 # set this to your preferred AWS region, e.g. us-west-1 + ECR_REPOSITORY: lab-repository # set this to your Amazon ECR repository name + ECS_SERVICE: LabManager-task-service-first # set this to your Amazon ECS service name + ECS_CLUSTER: excited-fish # set this to your Amazon ECS cluster name + ECS_TASK_DEFINITION: ../../labman/LabManager-task-definition.json # set this to the path to your Amazon ECS task definition + # file, e.g. .aws/task-definition.json + CONTAINER_NAME: nextjs-lab # set this to the name of the container in the + # containerDefinitions section of your task definition + DATABASE_URL: ${{secrets.DATABASE_URL}} + +permissions: + contents: read + id-token: write + +jobs: + deploy: + name: Deploy + runs-on: ubuntu-latest + environment: production + + steps: + - name: Checkout + uses: actions/checkout@v4 + + #- name: Configure AWS credentials + # uses: aws-actions/configure-aws-credentials@v1 + #with: + # aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + #aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + #aws-region: ${{ env.AWS_REGION }} + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@main + with: + audience: sts.amazonaws.com + aws-region: ${{ env.AWS_REGION }} + role-to-assume: arn:aws:iam::861353196312:role/ghRole + + - name: Login to Amazon ECR + id: login-ecr + uses: aws-actions/amazon-ecr-login@v1 + + - name: Build, tag, and push image to Amazon ECR + id: build-image + env: + ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} + IMAGE_TAG: ${{ github.sha }} + run: | + # Build a docker container and + # push it to ECR so that it can + # be deployed to ECS. + docker build --build-arg DATABASE_URL="$DATABASE_URL" -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG . + docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG + echo "image=$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" >> $GITHUB_OUTPUT + + - name: Fill in the new image ID in the Amazon ECS task definition + id: task-def + uses: aws-actions/amazon-ecs-render-task-definition@v1 + with: + task-definition: ${{ env.ECS_TASK_DEFINITION }} + container-name: ${{ env.CONTAINER_NAME }} + image: ${{ steps.build-image.outputs.image }} + + - name: Deploy Amazon ECS task definition + uses: aws-actions/amazon-ecs-deploy-task-definition@v1 + with: + task-definition: ${{ steps.task-def.outputs.task-definition }} + service: ${{ env.ECS_SERVICE }} + cluster: ${{ env.ECS_CLUSTER }} + wait-for-service-stability: true diff --git a/labman/Dockerfile b/labman/Dockerfile new file mode 100644 index 0000000..d8a242a --- /dev/null +++ b/labman/Dockerfile @@ -0,0 +1,71 @@ +# syntax=docker.io/docker/dockerfile:1 + +FROM node:20-alpine AS base + +# Install dependencies only when needed +FROM base AS deps +# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed. +RUN apk add --no-cache libc6-compat +WORKDIR /app + +# Install dependencies based on the preferred package manager +COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* .npmrc* ./ +RUN \ + if [ -f yarn.lock ]; then yarn --frozen-lockfile; \ + elif [ -f package-lock.json ]; then npm ci; \ + elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm i --frozen-lockfile; \ + else echo "Lockfile not found." && exit 1; \ + fi + + +# Rebuild the source code only when needed +FROM base AS builder +WORKDIR /app +COPY --from=deps /app/node_modules ./node_modules +COPY . . + +# Next.js collects completely anonymous telemetry data about general usage. +# Learn more here: https://nextjs.org/telemetry +# Uncomment the following line in case you want to disable telemetry during the build. +# ENV NEXT_TELEMETRY_DISABLED=1 + +ARG DATABASE_URL +ENV DATABASE_URL=${DATABASE_URL} + +RUN npx prisma generate + +RUN \ + if [ -f yarn.lock ]; then yarn run build; \ + elif [ -f package-lock.json ]; then npm run build; \ + elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm run build; \ + else echo "Lockfile not found." && exit 1; \ + fi + +# Production image, copy all the files and run next +FROM base AS runner +WORKDIR /app + + +# Uncomment the following line in case you want to disable telemetry during runtime. +# ENV NEXT_TELEMETRY_DISABLED=1 + +RUN addgroup --system --gid 1001 nodejs +RUN adduser --system --uid 1001 nextjs + +COPY --from=builder /app/public ./public + +# Automatically leverage output traces to reduce image size +# https://nextjs.org/docs/advanced-features/output-file-tracing +COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ +COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static + +USER nextjs + +EXPOSE 3000 + +ENV PORT=3000 + +# server.js is created by next build from the standalone output +# https://nextjs.org/docs/pages/api-reference/config/next-config-js/output +ENV HOSTNAME="0.0.0.0" +CMD ["node", "server.js"] diff --git a/labman/LabManager-task-definition.json b/labman/LabManager-task-definition.json new file mode 100644 index 0000000..dc701bf --- /dev/null +++ b/labman/LabManager-task-definition.json @@ -0,0 +1,90 @@ +{ + "taskDefinitionArn": "arn:aws:ecs:eu-north-1:861353196312:task-definition/LabManager-task:1", + "containerDefinitions": [ + { + "name": "nextjs-lab", + "image": "861353196312.dkr.ecr.eu-north-1.amazonaws.com/lab-repository@sha256:e7cdbf6f8318d5c7a55d534faa467df83a3dd9f9e9663068abef74fd19ff41d1", + "cpu": 0, + "portMappings": [ + { + "name": "main", + "containerPort": 3000, + "hostPort": 3000, + "protocol": "tcp", + "appProtocol": "http" + } + ], + "essential": true, + "environment": [], + "environmentFiles": [], + "mountPoints": [], + "volumesFrom": [], + "ulimits": [], + "logConfiguration": { + "logDriver": "awslogs", + "options": { + "awslogs-group": "/ecs/LabManager-task", + "awslogs-create-group": "true", + "awslogs-region": "eu-north-1", + "awslogs-stream-prefix": "ecs" + }, + "secretOptions": [] + }, + "systemControls": [] + } + ], + "family": "LabManager-task", + "executionRoleArn": "arn:aws:iam::861353196312:role/ecsTaskExecutionRole", + "networkMode": "awsvpc", + "revision": 1, + "volumes": [], + "status": "ACTIVE", + "requiresAttributes": [ + { + "name": "com.amazonaws.ecs.capability.logging-driver.awslogs" + }, + { + "name": "ecs.capability.execution-role-awslogs" + }, + { + "name": "com.amazonaws.ecs.capability.ecr-auth" + }, + { + "name": "com.amazonaws.ecs.capability.docker-remote-api.1.19" + }, + { + "name": "com.amazonaws.ecs.capability.docker-remote-api.1.21" + }, + { + "name": "ecs.capability.execution-role-ecr-pull" + }, + { + "name": "com.amazonaws.ecs.capability.docker-remote-api.1.18" + }, + { + "name": "ecs.capability.task-eni" + }, + { + "name": "com.amazonaws.ecs.capability.docker-remote-api.1.29" + } + ], + "placementConstraints": [], + "compatibilities": [ + "EC2", + "FARGATE", + "MANAGED_INSTANCES" + ], + "requiresCompatibilities": [ + "FARGATE" + ], + "cpu": "1024", + "memory": "3072", + "runtimePlatform": { + "cpuArchitecture": "X86_64", + "operatingSystemFamily": "LINUX" + }, + "registeredAt": "2026-01-29T14:16:22.647Z", + "registeredBy": "arn:aws:iam::861353196312:root", + "enableFaultInjection": false, + "tags": [] +} \ No newline at end of file diff --git a/labman/next.config.ts b/labman/next.config.ts index e9ffa30..3a5d1e9 100644 --- a/labman/next.config.ts +++ b/labman/next.config.ts @@ -2,6 +2,7 @@ import type { NextConfig } from "next"; const nextConfig: NextConfig = { /* config options here */ + output: "standalone", }; export default nextConfig; diff --git a/labman/prisma/schema.prisma b/labman/prisma/schema.prisma index 9ee749c..cdbca87 100644 --- a/labman/prisma/schema.prisma +++ b/labman/prisma/schema.prisma @@ -6,7 +6,7 @@ generator client { provider = "prisma-client-js" - binaryTargets = ["native", "debian-openssl-3.0.x"] + binaryTargets = ["native", "debian-openssl-3.0.x", "linux-musl-openssl-3.0.x"] output = "../src/generated/prisma" } From cbac290c36e4f31746e0968e8cd2305bde87e36c Mon Sep 17 00:00:00 2001 From: Ola Bekkevold Date: Tue, 3 Feb 2026 11:22:01 +0100 Subject: [PATCH 03/13] fix: correct path to Dockerfile --- .github/workflows/aws.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/aws.yml b/.github/workflows/aws.yml index 258fa6c..e3c121d 100644 --- a/.github/workflows/aws.yml +++ b/.github/workflows/aws.yml @@ -81,7 +81,7 @@ jobs: # Build a docker container and # push it to ECR so that it can # be deployed to ECS. - docker build --build-arg DATABASE_URL="$DATABASE_URL" -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG . + docker build --build-arg DATABASE_URL="$DATABASE_URL" -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG ../../labman docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG echo "image=$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" >> $GITHUB_OUTPUT From 2cc8c0079dc137bb6f8a5b516ae0f78b702e1d45 Mon Sep 17 00:00:00 2001 From: Ola Bekkevold Date: Tue, 3 Feb 2026 11:48:32 +0100 Subject: [PATCH 04/13] fix: small correction --- .github/workflows/aws.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/aws.yml b/.github/workflows/aws.yml index e3c121d..bd9b023 100644 --- a/.github/workflows/aws.yml +++ b/.github/workflows/aws.yml @@ -35,7 +35,7 @@ env: ECR_REPOSITORY: lab-repository # set this to your Amazon ECR repository name ECS_SERVICE: LabManager-task-service-first # set this to your Amazon ECS service name ECS_CLUSTER: excited-fish # set this to your Amazon ECS cluster name - ECS_TASK_DEFINITION: ../../labman/LabManager-task-definition.json # set this to the path to your Amazon ECS task definition + ECS_TASK_DEFINITION: labman/LabManager-task-definition.json # set this to the path to your Amazon ECS task definition # file, e.g. .aws/task-definition.json CONTAINER_NAME: nextjs-lab # set this to the name of the container in the # containerDefinitions section of your task definition @@ -81,7 +81,7 @@ jobs: # Build a docker container and # push it to ECR so that it can # be deployed to ECS. - docker build --build-arg DATABASE_URL="$DATABASE_URL" -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG ../../labman + docker build --build-arg DATABASE_URL="$DATABASE_URL" -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG /labman docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG echo "image=$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" >> $GITHUB_OUTPUT From 76cd200924652e1a3dacb0bef9824f8654431533 Mon Sep 17 00:00:00 2001 From: Ola Bekkevold Date: Tue, 3 Feb 2026 11:53:55 +0100 Subject: [PATCH 05/13] test --- .github/workflows/aws.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/aws.yml b/.github/workflows/aws.yml index bd9b023..d6c82f1 100644 --- a/.github/workflows/aws.yml +++ b/.github/workflows/aws.yml @@ -81,7 +81,8 @@ jobs: # Build a docker container and # push it to ECR so that it can # be deployed to ECS. - docker build --build-arg DATABASE_URL="$DATABASE_URL" -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG /labman + pwd + docker build --build-arg DATABASE_URL="$DATABASE_URL" -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG ./labman docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG echo "image=$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" >> $GITHUB_OUTPUT From 75526be517c21a8571a461ba1507a2dc54fd15e1 Mon Sep 17 00:00:00 2001 From: Ola Bekkevold Date: Tue, 3 Feb 2026 12:09:46 +0100 Subject: [PATCH 06/13] fix: update ecs-deploy-action version --- .github/workflows/aws.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/aws.yml b/.github/workflows/aws.yml index d6c82f1..42fb73d 100644 --- a/.github/workflows/aws.yml +++ b/.github/workflows/aws.yml @@ -95,7 +95,7 @@ jobs: image: ${{ steps.build-image.outputs.image }} - name: Deploy Amazon ECS task definition - uses: aws-actions/amazon-ecs-deploy-task-definition@v1 + uses: aws-actions/amazon-ecs-deploy-task-definition@v2 with: task-definition: ${{ steps.task-def.outputs.task-definition }} service: ${{ env.ECS_SERVICE }} From 5e50b3cfa773947592fe9893f92ccb3462edca40 Mon Sep 17 00:00:00 2001 From: Ola Bekkevold Date: Tue, 3 Feb 2026 13:51:56 +0100 Subject: [PATCH 07/13] test deployment --- labman/src/app/(auth)/login/page.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/labman/src/app/(auth)/login/page.tsx b/labman/src/app/(auth)/login/page.tsx index cbf5500..f51a5a7 100644 --- a/labman/src/app/(auth)/login/page.tsx +++ b/labman/src/app/(auth)/login/page.tsx @@ -37,7 +37,7 @@ export default function Home() {
setUsername(e.target.value)} type="text" name="username" placeholder="Username" className="bg-white rounded-md p-2 m-2 placeholder-black text-black" /> setPassword(e.target.value)} type="password" name="password" placeholder="Password" className="bg-white rounded-md p-2 m-2 placeholder-black text-black" /> - +
From 92f2a15ae2cb9baed0d37a80bb18c586968343dd Mon Sep 17 00:00:00 2001 From: Ola Bekkevold Date: Thu, 5 Feb 2026 15:13:21 +0100 Subject: [PATCH 08/13] test github secrets --- .github/workflows/aws.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/aws.yml b/.github/workflows/aws.yml index 42fb73d..1af04d7 100644 --- a/.github/workflows/aws.yml +++ b/.github/workflows/aws.yml @@ -40,6 +40,7 @@ env: CONTAINER_NAME: nextjs-lab # set this to the name of the container in the # containerDefinitions section of your task definition DATABASE_URL: ${{secrets.DATABASE_URL}} + TEST: ${{secrets.TEST}} permissions: contents: read @@ -61,6 +62,8 @@ jobs: # aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} #aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} #aws-region: ${{ env.AWS_REGION }} + - name: test env secrets + run: echo "$TEST" - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@main with: From e71b3163d39b1fda62a3c59e664e911cb6904e2d Mon Sep 17 00:00:00 2001 From: Ola Bekkevold Date: Fri, 6 Feb 2026 11:50:04 +0100 Subject: [PATCH 09/13] use aws secrets --- labman/LabManager-task-definition.json | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/labman/LabManager-task-definition.json b/labman/LabManager-task-definition.json index dc701bf..5ce8100 100644 --- a/labman/LabManager-task-definition.json +++ b/labman/LabManager-task-definition.json @@ -30,7 +30,14 @@ }, "secretOptions": [] }, - "systemControls": [] + "systemControls": [], + "secrets": [ + { + "name": "DATABASE_URL", + "valueFrom": "arn:aws:secretsmanager:eu-north-1:861353196312:secret:lab/prod/db-connection-3F8gP9" + + } + ] } ], "family": "LabManager-task", From 9c139df055d9bb315a360672b726f26be8b589bf Mon Sep 17 00:00:00 2001 From: Ola Bekkevold Date: Fri, 6 Feb 2026 13:50:45 +0100 Subject: [PATCH 10/13] specifiy correct secret key --- labman/LabManager-task-definition.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/labman/LabManager-task-definition.json b/labman/LabManager-task-definition.json index 5ce8100..1d33584 100644 --- a/labman/LabManager-task-definition.json +++ b/labman/LabManager-task-definition.json @@ -34,7 +34,7 @@ "secrets": [ { "name": "DATABASE_URL", - "valueFrom": "arn:aws:secretsmanager:eu-north-1:861353196312:secret:lab/prod/db-connection-3F8gP9" + "valueFrom": "arn:aws:secretsmanager:eu-north-1:861353196312:secret:lab/prod/db-connection-3F8gP9:DATABASE_URL::" } ] From 871c303fb4631b72b293665df6670e6c14e424c7 Mon Sep 17 00:00:00 2001 From: Ola Bekkevold Date: Fri, 6 Feb 2026 14:30:52 +0100 Subject: [PATCH 11/13] debug secret key --- .github/workflows/aws.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/aws.yml b/.github/workflows/aws.yml index 1af04d7..47cf870 100644 --- a/.github/workflows/aws.yml +++ b/.github/workflows/aws.yml @@ -40,7 +40,6 @@ env: CONTAINER_NAME: nextjs-lab # set this to the name of the container in the # containerDefinitions section of your task definition DATABASE_URL: ${{secrets.DATABASE_URL}} - TEST: ${{secrets.TEST}} permissions: contents: read @@ -62,8 +61,7 @@ jobs: # aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} #aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} #aws-region: ${{ env.AWS_REGION }} - - name: test env secrets - run: echo "$TEST" + - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@main with: From 3af43aea703e5975410a07bae412127c7c9e4c0a Mon Sep 17 00:00:00 2001 From: Ola Bekkevold Date: Mon, 9 Feb 2026 09:33:25 +0100 Subject: [PATCH 12/13] temporarly disable https production requirment --- labman/src/app/api/login/route.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/labman/src/app/api/login/route.ts b/labman/src/app/api/login/route.ts index 0c79c10..afba11e 100644 --- a/labman/src/app/api/login/route.ts +++ b/labman/src/app/api/login/route.ts @@ -18,7 +18,6 @@ export async function POST(req: Request) { // Set the session cookie (await cookies()).set("session", session.token, { httpOnly: true, - secure: process.env.NODE_ENV === "production", sameSite: "lax", maxAge: 60 * 60 * 24, path: "/" From fed65fd0bce45da9270b773068a96dc5032a4468 Mon Sep 17 00:00:00 2001 From: Ola Bekkevold Date: Tue, 17 Feb 2026 10:46:33 +0100 Subject: [PATCH 13/13] fix: set phone and email inputs to null when empty and make deployment exclusive to main fix a bug were the adding of a user with empty phone/email would fail due to being sent as empty strings instead of null values. And the project will only deploy after successful tests on main Refs: #49 --- .github/workflows/aws.yml | 11 ++++++++-- labman/src/lib/actions.ts | 44 ++++++++++++++++++++++++++++++--------- 2 files changed, 43 insertions(+), 12 deletions(-) diff --git a/.github/workflows/aws.yml b/.github/workflows/aws.yml index 47cf870..ceb1a6c 100644 --- a/.github/workflows/aws.yml +++ b/.github/workflows/aws.yml @@ -27,8 +27,9 @@ name: Deploy to Amazon ECS on: - push: - branches: [ "main", "backend_server" ] + workflow_run: + workflows: ["Tests"] + types: [completed] env: AWS_REGION: eu-north-1 # set this to your preferred AWS region, e.g. us-west-1 @@ -47,6 +48,10 @@ permissions: jobs: deploy: + if: > + ${{ github.event.workflow_run.conclusion == 'success' && + github.event.workflow_run.head_branch == 'main' && + github.event.workflow_run.event == 'push'}} name: Deploy runs-on: ubuntu-latest environment: production @@ -54,6 +59,8 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 + with: + ref: ${{ github.event.workflow_run.head_sha }} #- name: Configure AWS credentials # uses: aws-actions/configure-aws-credentials@v1 diff --git a/labman/src/lib/actions.ts b/labman/src/lib/actions.ts index 75f0ad6..005802b 100644 --- a/labman/src/lib/actions.ts +++ b/labman/src/lib/actions.ts @@ -126,22 +126,46 @@ export async function updateEquipment (equipmentId: number, name: string, catego return equipment; } -export async function addLoan (borrower : string, start : string, end : string, unitId : number, phone? : string, email? : string) { +export async function addLoan (borrowerName : string, start : string, end : string, unitId : number, phone : string | null, email : string | null) { const dateStart = new Date(start); const dateEnd = new Date(end); const user = await getUser(); if (!user) {alert("Could not find a valid user"); return} - let borrowerUser = await prisma.borrower.findUnique({ - where: { - phone: phone - } - }) - if (!borrowerUser) { - borrowerUser = await prisma.borrower.create({ + let borrower; + + // If phone or email is actually empty, set it to null + if (phone?.trim() === "") {phone = null} + + if (email?.trim() === "") {email = null} + + if (phone) { + borrower = await prisma.borrower.findUnique({where:{phone: phone}}) + /* if (borrower && borrower.name !== borrowerName) { + if (window.confirm(`A borrower with the same phone number already exists with a different name (${borrower.name}). Click OK to assign this loan to ${borrowerName}. Click Cancel to assign it to ${borrower.name} instead.`)) { + borrower = null; + } + } */ + + } else if (email) { + borrower = await prisma.borrower.findUnique({where:{email: email}}) + /*if (borrower && borrower.name !== borrowerName) { + if (window.confirm(`A borrower with the same email already exists with a different name (${borrower.name}). Click OK to assign this loan to ${borrowerName}. Click Cancel to assign it to ${borrower.name} instead.`)) { + borrower = null; + } + } */ + } else { + alert("No borrower phone/email provided"); return; + } + + + + + if (!borrower) { + borrower = await prisma.borrower.create({ data: { - name: borrower, + name: borrowerName, phone: phone, email: email, note: "", @@ -155,7 +179,7 @@ export async function addLoan (borrower : string, start : string, end : string, startDate: dateStart, endDate: dateEnd, status: "Active", - borrowerId: borrowerUser.id, + borrowerId: borrower.id, userId: user.id, itemId: unitId }