bfcfe83199cc3944f8b26869e3a4905b5b9e9b08
W8 closes the B3 plan↔code gap (the biggest blocker from Review v3).
New services:
- AuthService: password login/register/refresh/getCurrentUser with audit
- InvitationService: create (SHA-256 hashed token), accept, revoke, list
- AccessRequestService: submit (rate-limited 3/user), approve, deny, list
New controllers:
- AuthController: POST /api/auth/{login,register,refresh}, GET /api/auth/{me,config}
- InvitationController: POST /api/invitations, POST /api/invitations/accept, DELETE/GET
- AccessRequestController: POST /api/access-requests, POST /{id}/{approve,deny}, GET
- AdminAuditController: GET /api/admin/login-events (paginated, admin-only)
New filter:
- OrgContextResolver: reads X-Org-Id/X-Org-Type headers, validates membership,
sets OrgContext thread-local (cleared in finally block)
New DTOs: LoginRequest, RegisterRequest, RefreshRequest, UserResponse,
AuthConfigResponse, CreateInvitationRequest, CreateAccessRequestRequest,
ReviewAccessRequestRequest
Updated:
- PlateAuthAutoConfiguration: @Import list now includes all 7 new classes
- SecurityConfig: OrgContextResolver bean + filter chain; access-requests
permitAll scoped to POST only (approve/deny now require auth)
mvn -pl plate-auth-starter compile PASSES.
plate-auth
Reusable authentication + multi-tenancy library for Spring Boot 4 + NextAuth v5.
Two artifacts, one contract
| Artifact | Registry | Purpose |
|---|---|---|
de.platesoft:plate-auth-starter |
Gitea Maven | Spring Boot auto-config: JWT, OAuth, memberships, invitations, access requests |
@platesoft/auth |
Gitea npm | NextAuth v5 config factory, HMAC exchange, proxy helpers, React hooks |
The wire contract between them is an HMAC-SHA256 signed exchange envelope + JWT bearer tokens.
Quick start (5 lines)
Backend (Spring Boot 4)
<dependency>
<groupId>de.platesoft</groupId>
<artifactId>plate-auth-starter</artifactId>
<version>0.1.0</version>
</dependency>
plate:
auth:
jwt:
secret: ${PLATE_AUTH_JWT_SECRET} # ≥32 chars
exchange:
secret: ${PLATE_AUTH_EXCHANGE_SECRET} # ≥32 chars, shared with frontend
Frontend (Next.js 15 + NextAuth v5)
pnpm add @platesoft/auth@0.1.0 --registry=https://git.plate-software.de/api/packages/pplate/npm/
// app/api/auth/[...nextauth]/route.ts
import NextAuth from 'next-auth';
import { createAuthConfig } from '@platesoft/auth/config';
const config = createAuthConfig({
providers: { google: { clientId: process.env.GOOGLE_CLIENT_ID!, clientSecret: process.env.GOOGLE_CLIENT_SECRET! } },
exchange: { backendUrl: process.env.NEXT_PUBLIC_BACKEND_URL!, secret: process.env.NEXTAUTH_EXCHANGE_SECRET! },
});
export const { handlers, auth, signIn, signOut } = NextAuth(config);
export const { GET, POST } = handlers;
SPI Extension Points
| Interface | Default | Purpose |
|---|---|---|
OrgValidator |
PermissiveOrgValidator (WARN per call) |
Validate (org_type, org_id) exists |
OrgDisplayNameResolver |
Returns type:id |
Pretty-print org |
InvitationMailer |
Logs accept URL | Send invite emails |
AccessRequestMailer |
Logs notifications | Notify on access requests |
OnboardingHook |
No-op | First sign-in hook |
Override any bean with @ConditionalOnMissingBean — register your own to replace.
Documentation
Full docs live in the plate-auth wiki.
License
Apache-2.0 — see LICENSE.
Description
Languages
Java
95.5%
TypeScript
4.5%