140 lines
5.1 KiB
TypeScript
140 lines
5.1 KiB
TypeScript
import { Body, Controller, Get, HttpException, HttpStatus, Inject, Param, Post, Query, Req, UseGuards } from '@nestjs/common';
|
|
import * as admin from 'firebase-admin';
|
|
import { AdminGuard } from 'src/jwt-auth/admin-auth.guard';
|
|
import { AuthGuard } from 'src/jwt-auth/auth.guard';
|
|
import { LocalhostGuard } from 'src/jwt-auth/localhost.guard';
|
|
import { UserRole, UsersResponse } from 'src/models/main.model';
|
|
import { AuthService } from './auth.service';
|
|
|
|
@Controller('auth')
|
|
export class AuthController {
|
|
constructor(
|
|
@Inject('FIREBASE_ADMIN')
|
|
private readonly firebaseAdmin: typeof admin,
|
|
private readonly authService: AuthService,
|
|
) {}
|
|
@Post('verify-email')
|
|
async verifyEmail(@Body('oobCode') oobCode: string, @Body('email') email: string) {
|
|
if (!oobCode || !email) {
|
|
throw new HttpException('oobCode and email are required', HttpStatus.BAD_REQUEST);
|
|
}
|
|
|
|
try {
|
|
// Step 1: Get the user by email address
|
|
const userRecord = await this.firebaseAdmin.auth().getUserByEmail(email);
|
|
|
|
if (userRecord.emailVerified) {
|
|
// Even if already verified, we'll still return a valid token
|
|
const customToken = await this.firebaseAdmin.auth().createCustomToken(userRecord.uid);
|
|
return {
|
|
message: 'Email is already verified',
|
|
token: customToken,
|
|
};
|
|
}
|
|
|
|
// Step 2: Update the user status to set emailVerified to true
|
|
await this.firebaseAdmin.auth().updateUser(userRecord.uid, {
|
|
emailVerified: true,
|
|
});
|
|
|
|
// Step 3: Generate a custom Firebase token for the user
|
|
// This token can be used on the client side to authenticate with Firebase
|
|
const customToken = await this.firebaseAdmin.auth().createCustomToken(userRecord.uid);
|
|
|
|
return {
|
|
message: 'Email successfully verified',
|
|
token: customToken,
|
|
};
|
|
} catch (error) {
|
|
throw new HttpException(error.message || 'Failed to verify email', HttpStatus.BAD_REQUEST);
|
|
}
|
|
}
|
|
@Post(':uid/role')
|
|
@UseGuards(AuthGuard, AdminGuard) // Only admins can change roles
|
|
async setUserRole(@Param('uid') uid: string, @Body('role') role: UserRole): Promise<{ success: boolean }> {
|
|
await this.authService.setUserRole(uid, role);
|
|
return { success: true };
|
|
}
|
|
|
|
@Get('me/role')
|
|
@UseGuards(AuthGuard)
|
|
async getMyRole(@Req() req: any): Promise<{ role: UserRole | null }> {
|
|
console.log('->', req.user);
|
|
console.log('-->', req.user.uid);
|
|
const uid = req.user.uid; // From FirebaseAuthGuard
|
|
const role = await this.authService.getUserRole(uid);
|
|
return { role };
|
|
}
|
|
|
|
@Get(':uid/role')
|
|
@UseGuards(AuthGuard)
|
|
async getUserRole(@Param('uid') uid: string): Promise<{ role: UserRole | null }> {
|
|
const role = await this.authService.getUserRole(uid);
|
|
return { role };
|
|
}
|
|
|
|
@Get('role/:role')
|
|
@UseGuards(AuthGuard, AdminGuard) // Only admins can list users by role
|
|
async getUsersByRole(@Param('role') role: UserRole): Promise<{ users: any[] }> {
|
|
const users = await this.authService.getUsersByRole(role);
|
|
// Map to simpler objects to avoid circular references
|
|
const simplifiedUsers = users.map(user => ({
|
|
uid: user.uid,
|
|
email: user.email,
|
|
displayName: user.displayName,
|
|
}));
|
|
return { users: simplifiedUsers };
|
|
}
|
|
|
|
/**
|
|
* Ruft alle Firebase-Benutzer mit ihren Rollen ab
|
|
* @param maxResults Maximale Anzahl an zurückzugebenden Benutzern (optional, Standard: 1000)
|
|
* @param pageToken Token für die Paginierung (optional)
|
|
* @returns Eine Liste von Benutzern mit ihren Rollen und Metadaten
|
|
*/
|
|
@Get()
|
|
@UseGuards(AuthGuard, AdminGuard) // Only admins can list all users
|
|
async getAllUsers(@Query('maxResults') maxResults?: number, @Query('pageToken') pageToken?: string): Promise<UsersResponse> {
|
|
const result = await this.authService.getAllUsers(maxResults ? parseInt(maxResults.toString(), 10) : undefined, pageToken);
|
|
|
|
return {
|
|
users: result.users,
|
|
totalCount: result.users.length,
|
|
...(result.pageToken && { pageToken: result.pageToken }),
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Endpoint zum direkten Einstellen einer Rolle für Debug-Zwecke
|
|
* WARNUNG: Dieser Endpoint sollte in der Produktion entfernt oder stark gesichert werden
|
|
*/
|
|
@Post('set-role')
|
|
@UseGuards(AuthGuard, LocalhostGuard)
|
|
async setUserRoleOnLocalhost(@Req() req: any, @Body('role') role: UserRole): Promise<{ success: boolean; message: string }> {
|
|
try {
|
|
const uid = req.user.uid;
|
|
|
|
// Aktuelle Rolle protokollieren
|
|
const currentUser = await this.authService.getUserRole(uid);
|
|
console.log(`Changing role for user ${uid} from ${currentUser} to ${role}`);
|
|
|
|
// Neue Rolle setzen
|
|
await this.authService.setUserRole(uid, role);
|
|
|
|
// Rolle erneut prüfen, um zu bestätigen
|
|
const newRole = await this.authService.getUserRole(uid);
|
|
|
|
return {
|
|
success: true,
|
|
message: `Rolle für Benutzer ${uid} von ${currentUser} zu ${newRole} geändert`,
|
|
};
|
|
} catch (error) {
|
|
console.error('Fehler beim Setzen der Rolle:', error);
|
|
return {
|
|
success: false,
|
|
message: `Fehler: ${error.message}`,
|
|
};
|
|
}
|
|
}
|
|
}
|