feat(backend): GET /api/auth/me for role-aware clients

Accepts any of the three token kinds and echoes back the identity behind
it: {kind:"guest", guestId, kcId, gemeindeId} for a Konfi token, or
{kind:"user", userId, email, memberships, isLeitungsteam} for an Authentik
or local Teamer token. Lets the client pick the right screens without
decoding the JWT itself.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-10 08:46:18 +02:00
co-authored by Claude Sonnet 5
parent 912461751a
commit 7a95f4098f
+32 -1
View File
@@ -1,9 +1,12 @@
import { Body, Controller, Post } from '@nestjs/common';
import { Body, Controller, Get, Post, Req, UseGuards } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { GuestAuthService } from './guest-auth.service';
import { TeamAuthService } from './team-auth.service';
import { CreateGuestDto } from './dto/create-guest.dto';
import { TeamLoginDto } from './dto/team-login.dto';
import { RegisterTeamerDto } from './dto/register-teamer.dto';
import { AuthenticatedRequest } from './authenticated-request';
import { GuestJwtPayload } from './guest-auth.service';
@Controller('auth')
export class AuthController {
@@ -12,6 +15,34 @@ export class AuthController {
private readonly teamAuth: TeamAuthService,
) {}
/// Returns the identity + scope behind whichever token was presented, so a
/// client can render a role-aware UI. `kind` is "guest" for a Konfi token,
/// "user" for an Authentik or local Teamer token.
@Get('me')
@UseGuards(AuthGuard(['authentik', 'team', 'guest']))
me(@Req() req: AuthenticatedRequest & { user: unknown }) {
const user = req.user as
| AuthenticatedRequest['user']
| GuestJwtPayload;
if (user && 'guestId' in user) {
return {
kind: 'guest',
guestId: user.guestId,
kcId: user.kcId,
gemeindeId: user.gemeindeId,
};
}
const u = user as NonNullable<AuthenticatedRequest['user']>;
return {
kind: 'user',
userId: u.userId,
email: u.email,
authentikSub: u.authentikSub,
memberships: u.memberships,
isLeitungsteam: u.memberships.some((m) => m.role === 'LEITUNGSTEAM'),
};
}
/// Redeems a KC invite code and registers a new temporary guest/Konfi account.
@Post('guest')
createGuest(@Body() dto: CreateGuestDto) {