Skip to content

Implements the authentication and authorization layer for the backend API. - #22

Merged
specfor merged 8 commits into
mainfrom
feat/authentication
Jul 25, 2026
Merged

Implements the authentication and authorization layer for the backend API.#22
specfor merged 8 commits into
mainfrom
feat/authentication

Conversation

@RanudulaW

Copy link
Copy Markdown
Collaborator

Changes

  • Added JWT-based authentication with login and refresh token endpoints.
  • Integrated automatic database migrations during application startup.
  • Added initial data seeding during server initialization.
  • Implemented JWT authentication middleware to protect private routes.
  • Extended JWT claims to include entity_id, role_id, and user permissions.
  • Added ExtractClaims middleware to provide a strongly typed authentication context.
  • Implemented RequirePermission middleware for role-based access control (RBAC).
  • Added tenant-aware authorization support by using the authenticated user's entity information.
  • Updated authentication request models to support JSON, form, and query parameter binding.
  • Added integration tests covering authentication and authorization flows.

Copilot AI review requested due to automatic review settings July 24, 2026 12:50

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a first-pass authentication/authorization layer to the backend API (JWT auth + refresh, RBAC middleware, tenant scoping), alongside database bootstrapping (embedded migrations + initial seeding). It also includes some frontend scaffolding/theme wiring updates that appear orthogonal to the backend auth work.

Changes:

  • Added JWT login/refresh endpoints plus middleware for extracting claims and enforcing permissions on protected routes.
  • Introduced embedded DB migrations and a startup seeding step for an initial super-admin account.
  • Updated the frontend app shell (MUI theme registry + a temporary “dev start” scaffold) and adjusted the Home page test accordingly.

Reviewed changes

Copilot reviewed 37 out of 45 changed files in this pull request and generated 12 comments.

Show a summary per file
File Description
frontend/src/theme/ThemeRegistry.tsx Adds an App Router–compatible MUI theme registry wrapper.
frontend/src/components/DevStartScaffold.tsx Introduces a temporary landing scaffold for frontend development.
frontend/src/app/page.tsx Replaces starter page content with the dev scaffold component.
frontend/src/app/page.test.tsx Updates the Home page test assertions to match the new scaffold content.
frontend/src/app/layout.tsx Refactors global layout to delegate MUI setup to ThemeRegistry.
frontend/src/app/globals.css Simplifies global styles to remove old background/foreground theming.
frontend/package-lock.json Updates lockfile metadata (platform libc entries removed).
frontend/next.config.ts Adds a Turbopack root configuration for the frontend package.
backend-api/tests/api/role_test.go Adds a validation-focused test for role creation.
backend-api/tests/api/rbac_test.go Adds RBAC tests for forbidden/allowed/super-admin permission cases.
backend-api/tests/api/auth_test.go Adds a login success test using a mock sqlc querier.
backend-api/sqlc/sqlc.yaml Adjusts sqlc paths/output location for schema/queries generation.
backend-api/sqlc/schema/001_multi_tenancy.sql Adds initial multi-tenant schema definitions for sqlc parsing.
backend-api/sqlc/queries/users.sql Adds user-related queries including tenant-scoped listing and role updates.
backend-api/sqlc/queries/roles.sql Adds role creation and tenant-scoped role listing queries.
backend-api/sqlc/queries/auth.sql Adds auth queries for users and refresh token lifecycle.
backend-api/Makefile Improves cross-platform build/clean targets and adds new utility targets.
backend-api/internal/router/router.go Mounts auth endpoints, configures JWT middleware, and protects routes.
backend-api/internal/repository/repository.go Introduces a tenant-aware repository wrapper for entity scoping.
backend-api/internal/middleware/rbac.go Adds middleware to enforce a required permission.
backend-api/internal/middleware/jwt.go Adds AuthContext extraction from JWT claims and permission helpers.
backend-api/internal/handler/user.go Implements create/list/update role endpoints for users.
backend-api/internal/handler/role.go Implements create/list endpoints for roles.
backend-api/internal/handler/health.go Adds explicit JSON error handling for the health response.
backend-api/internal/handler/handler.go Adds sqlc querier wiring and a helper to construct a tenant repo.
backend-api/internal/handler/auth.go Implements login/refresh endpoints and a protected /auth/me endpoint.
backend-api/internal/db/sqlcdb/users.sql.go Generated sqlc code for user queries.
backend-api/internal/db/sqlcdb/roles.sql.go Generated sqlc code for role queries.
backend-api/internal/db/sqlcdb/querier.go Generated sqlc interface aggregating query methods.
backend-api/internal/db/sqlcdb/models.go Generated sqlc models for entities/users/roles/refresh tokens.
backend-api/internal/db/sqlcdb/db.go Generated sqlc DBTX wrapper and transaction support.
backend-api/internal/db/sqlcdb/auth.sql.go Generated sqlc code for auth/refresh-token queries.
backend-api/internal/db/seed.go Adds initial super-admin seeding logic.
backend-api/internal/db/seed_test.go Adds tests for seeding idempotency and creation behavior.
backend-api/internal/db/migrations/000001_multi_tenancy.up.sql Adds initial DB migration for entities/roles/users/refresh_tokens.
backend-api/internal/db/migrations/000001_multi_tenancy.down.sql Adds rollback for the initial migration.
backend-api/internal/db/migrate.go Adds embedded-migration runner using golang-migrate.
backend-api/internal/config/config.go Adds initial account config fields and defaults.
backend-api/internal/config/config_test.go Adds tests for config loading defaults and validation behavior.
backend-api/go.sum Updates dependency checksums for new auth/migrate dependencies.
backend-api/go.mod Updates Go version and adds dependencies for JWT, migrate, echo-jwt, etc.
backend-api/coverage Adds a coverage artifact file (likely accidental).
backend-api/cmd/server/main.go Runs migrations + seeding at startup and improves shutdown error check.
backend-api/.golangci.yml Updates golangci-lint config format and enabled linters/comments.
backend-api/.env.example Documents new env vars for initial accounts / auto-seeding.
Files not reviewed (7)
  • backend-api/internal/db/sqlcdb/auth.sql.go: Generated file
  • backend-api/internal/db/sqlcdb/db.go: Generated file
  • backend-api/internal/db/sqlcdb/models.go: Generated file
  • backend-api/internal/db/sqlcdb/querier.go: Generated file
  • backend-api/internal/db/sqlcdb/roles.sql.go: Generated file
  • backend-api/internal/db/sqlcdb/users.sql.go: Generated file
  • frontend/package-lock.json: Generated file
Comments suppressed due to low confidence (1)

backend-api/Makefile:108

  • make help still advertises race detection for make test, but the test target only runs coverage now. This can mislead developers relying on the help output.
	@echo Usage:
	@echo   make run        - start the development server
	@echo   make test       - run all tests with race detection
	@echo   make test-v     - run tests with verbose output
	@echo   make lint       - run golangci-lint

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

export default function ThemeRegistry({
children,
}: {
children: React.ReactNode;
return c.JSON(http.StatusUnauthorized, echo.Map{"error": "invalid token claims"}) //nolint:wrapcheck
}

userID := claims["sub"].(string)
Comment on lines +21 to +22
Email string `json:"email" form:"email"`
Password string `json:"password" form:"password"`
@@ -0,0 +1,35 @@
CREATE TABLE entities (
@@ -0,0 +1,35 @@
CREATE TABLE entities (
Comment thread backend-api/coverage
@@ -0,0 +1 @@
mode: atomic
if err := c.Bind(&req); err != nil {
return c.JSON(http.StatusBadRequest, echo.Map{"error": "invalid request format"}) //nolint:wrapcheck
}

Comment on lines +14 to +17
-- name: UpdateUserRole :exec
UPDATE users
SET role_id = $2, updated_at = NOW()
WHERE id = $1 AND entity_id = $3;
Comment thread frontend/src/app/page.tsx
Comment on lines +1 to +4
import DevStartScaffold from "@/components/DevStartScaffold";

export default function Home() {
return (
<div className="flex flex-col flex-1 items-center justify-center bg-zinc-50 font-sans dark:bg-black">
<main className="flex flex-1 w-full max-w-3xl flex-col items-center justify-between py-32 px-16 bg-white dark:bg-black sm:items-start">
<Image
className="dark:invert"
src="/next.svg"
alt="Next.js logo"
width={100}
height={20}
priority
/>
<div className="flex flex-col items-center gap-6 text-center sm:items-start sm:text-left">
<h1 className="max-w-xs text-3xl font-semibold leading-10 tracking-tight text-black dark:text-zinc-50">
To get started, edit the page.tsx file.
</h1>
<p className="max-w-md text-lg leading-8 text-zinc-600 dark:text-zinc-400">
Looking for a starting point or more instructions? Head over to{" "}
<a
href="https://vercel.com/templates?framework=next.js&utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
className="font-medium text-zinc-950 dark:text-zinc-50"
>
Templates
</a>{" "}
or the{" "}
<a
href="https://nextjs.org/learn?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
className="font-medium text-zinc-950 dark:text-zinc-50"
>
Learning
</a>{" "}
center.
</p>
</div>
<div className="flex flex-col gap-4 text-base font-medium sm:flex-row">
<a
className="flex h-12 w-full items-center justify-center gap-2 rounded-full bg-foreground px-5 text-background transition-colors hover:bg-[#383838] dark:hover:bg-[#ccc] md:w-[158px]"
href="https://vercel.com/new?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
<Image
className="dark:invert"
src="/vercel.svg"
alt="Vercel logomark"
width={16}
height={16}
/>
Deploy Now
</a>
<a
className="flex h-12 w-full items-center justify-center rounded-full border border-solid border-black/[.08] px-5 transition-colors hover:border-transparent hover:bg-black/[.04] dark:border-white/[.145] dark:hover:bg-[#1a1a1a] md:w-[158px]"
href="https://nextjs.org/docs?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
Documentation
</a>
</div>
</main>
</div>
);
return <DevStartScaffold />;
InitialUserEmail: getEnv("INITIAL_USER_EMAIL", "user@civiclens.org"),
InitialUserPassword: getEnv("INITIAL_USER_PASSWORD", "UserPass123!"),
}

@specfor
specfor merged commit 5cd1132 into main Jul 25, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants