AI Implementation feature(857): Authenticated Shell: Header, Quick Tabs and Change Password (#14)

This commit was merged in pull request #14.
This commit is contained in:
2026-07-21 22:26:47 +00:00
parent 8dc8cee769
commit b6dbfcc511
46 changed files with 2705 additions and 211 deletions
+45 -1
View File
@@ -13,7 +13,12 @@ import { Request, Response } from 'express';
import { ConfigService } from '@nestjs/config';
import { ZodValidationPipe } from '../../common/pipes/zod-validation.pipe';
import { Public } from '../../common/decorators/public.decorator';
import { LoginDtoSchema, RefreshDtoSchema, RegisterDtoSchema } from './dto/auth.dto';
import {
ChangePasswordDtoSchema,
LoginDtoSchema,
RefreshDtoSchema,
RegisterDtoSchema,
} from './dto/auth.dto';
import { AuthService } from './auth.service';
import { CsrfMiddleware } from '../../common/middleware/csrf.middleware';
import { setRefreshCookie, clearRefreshCookie } from './cookie';
@@ -101,6 +106,45 @@ export class AuthController {
clearRefreshCookie(res);
}
@Get('me')
@ApiOperation({ summary: 'Current authenticated user profile (id, username, role, rank, points)' })
@ApiResponse({ status: 200, description: 'Returns the current user projection.' })
async me(@Req() req: Request): Promise<{
id: string;
username: string;
role: 'admin' | 'player';
rank: number | null;
points: number;
}> {
const user = req.user as { sub: string } | undefined;
const userId = user?.sub;
if (!userId) {
throw new (await import('@nestjs/common')).UnauthorizedException('Not authenticated');
}
return this.auth.getMe(userId);
}
@Post('change-password')
@HttpCode(HttpStatus.NO_CONTENT)
@ApiOperation({ summary: 'Change the current user password (requires old password)' })
@ApiBody({
schema: {
example: { oldPassword: 'Sup3rSecret!Pass', newPassword: 'NewSecret!Pass1', confirmNewPassword: 'NewSecret!Pass1' },
},
})
async changePassword(
@Req() req: Request,
@Body(new ZodValidationPipe(ChangePasswordDtoSchema))
body: { oldPassword: string; newPassword: string; confirmNewPassword: string },
): Promise<void> {
const user = req.user as { sub: string } | undefined;
const userId = user?.sub;
if (!userId) {
throw new (await import('@nestjs/common')).UnauthorizedException('Not authenticated');
}
await this.auth.changePassword(userId, body);
}
@Public()
@Get('csrf')
@ApiOperation({ summary: 'Issue a CSRF token (sets csrf cookie, returns token)' })