src/auth/auth.controller.ts
auth
Methods |
|
| Public Async changePass |
changePass()
|
Decorators :
@Post('pass/change')
|
|
Defined in src/auth/auth.controller.ts:75
|
|
Returns :
unknown
|
| Public Async confirmCode | ||||||||
confirmCode(undefined: CodesDto, resp: FastifyReply)
|
||||||||
Decorators :
@Get('/confirm/:code')
|
||||||||
|
Defined in src/auth/auth.controller.ts:81
|
||||||||
|
Parameters :
Returns :
unknown
|
| Public Async disable2fa | |||||||||
disable2fa(req: FastifyRequest, twofactorDto: TwoFactorDisableDto)
|
|||||||||
Decorators :
@Post('/2fa/disable')
|
|||||||||
|
Defined in src/auth/auth.controller.ts:138
|
|||||||||
|
Parameters :
Returns :
unknown
|
| Public Async discordCb | ||||||
discordCb(query: literal type)
|
||||||
Decorators :
@Get('/callback/discord')
|
||||||
|
Defined in src/auth/auth.controller.ts:177
|
||||||
|
Parameters :
Returns :
unknown
|
| Public Async enable2fa | |||||||||
enable2fa(req: FastifyRequest, twofactorDto: TwoFactorEnableDto)
|
|||||||||
Decorators :
@Post('/2fa/enable')
|
|||||||||
|
Defined in src/auth/auth.controller.ts:115
|
|||||||||
|
Parameters :
Returns :
unknown
|
| Public Async githubCb | ||||||
githubCb(query: literal type)
|
||||||
Decorators :
@Get('/callback/github')
|
||||||
|
Defined in src/auth/auth.controller.ts:183
|
||||||
|
Parameters :
Returns :
unknown
|
| Public Async init2fa | ||||||
init2fa(req: FastifyRequest)
|
||||||
Decorators :
@Get('/2fa/init')
|
||||||
|
Defined in src/auth/auth.controller.ts:110
|
||||||
|
Parameters :
Returns :
unknown
|
| Public Async initResetPass | ||||||
initResetPass(dto: InitResetPassDto)
|
||||||
Decorators :
@Public()
|
||||||
|
Defined in src/auth/auth.controller.ts:228
|
||||||
|
Parameters :
Returns :
unknown
|
| Public Async login | |||||||||
login(loginDto: LoginDto, request: FastifyRequest)
|
|||||||||
Decorators :
@RateLimit({for: 'Fastify', keyPrefix: 'login', points: 4, duration: 10, blockDuration: 60, errorMessage: 'You can only login 4 times every 10 seconds. Try again in 1 minute.'})
|
|||||||||
|
Defined in src/auth/auth.controller.ts:65
|
|||||||||
|
Parameters :
Returns :
unknown
|
| Public Async loginVia2fa | |||||||||
loginVia2fa(twofactorDto: TwoFactorLoginDto, request: FastifyRequest)
|
|||||||||
Decorators :
@Post('/2fa/login')
|
|||||||||
|
Defined in src/auth/auth.controller.ts:158
|
|||||||||
|
Parameters :
Returns :
unknown
|
| Public Async resendConfEmail | |||||
resendConfEmail(undefined: InitResetPassDto)
|
|||||
Decorators :
@RateLimit({for: 'Fastify', keyPrefix: 'resend-verification', points: 2, duration: 300, errorMessage: 'You can only resend two verification emails every 5 minutes.'})
|
|||||
|
Defined in src/auth/auth.controller.ts:254
|
|||||
|
Parameters :
Returns :
unknown
|
| Public Async resetPas | ||||||
resetPas(dto: ResetPassDto)
|
||||||
Decorators :
@Public()
|
||||||
|
Defined in src/auth/auth.controller.ts:237
|
||||||
|
Parameters :
Returns :
unknown
|
| Public Async setOauthPass | |||||||||
setOauthPass(dto: SetOauthPassDto, request: FastifyRequest)
|
|||||||||
Decorators :
@Post('/oauth/setpass')
|
|||||||||
|
Defined in src/auth/auth.controller.ts:189
|
|||||||||
|
Parameters :
Returns :
unknown
|
import {
Body,
Controller,
Post,
ValidationPipe,
Param,
Get,
Inject,
forwardRef,
Req,
Logger,
Query,
UnauthorizedException,
Res,
} from '@nestjs/common';
import { AuthService } from './auth.service';
import LoginDto from './dto/login.dto';
import { Public } from '../common/decorators/public.decorator';
import { Captcha } from '../common/decorators/captcha.decorator';
import { CodesService } from '../codes/codes.service';
import { InvalidCodeException } from '../exceptions/invalid-code.exception';
import { UtilsService } from '../utils/utils.service';
import { UsersService } from '../users/users.service';
import { FastifyReply, FastifyRequest } from 'fastify';
import {
TwoFactorDisableDto,
TwoFactorEnableDto,
TwoFactorLoginDto,
} from './dto/2fa.dto';
import { InvalidDataException } from '../exceptions/invalid-data.exception';
import { CodesDto } from './dto/codes.dto';
import { DiscordService } from './discord/discord.service';
import { GenericRespEnum } from '../utils/enums/responses.enum';
import { SetOauthPassDto } from './dto/setpass.dto';
import { InitResetPassDto, ResetPassDto } from './dto/resetpass.dto';
import { GithubService } from './github/github.service';
import { OauthCode } from '../../types';
import { RateLimit } from 'nestjs-rate-limiter';
@Controller('auth')
export class AuthController {
private readonly logger = new Logger(AuthController.name);
constructor(
private readonly authService: AuthService,
private readonly codesService: CodesService,
private readonly utilsService: UtilsService,
@Inject(forwardRef(() => UsersService))
private readonly usersService: UsersService,
@Inject(forwardRef(() => DiscordService))
private readonly discordService: DiscordService,
private readonly githubService: GithubService,
) {}
@RateLimit({
for: 'Fastify',
keyPrefix: 'login',
points: 4,
duration: 10,
blockDuration: 60,
errorMessage:
'You can only login 4 times every 10 seconds. Try again in 1 minute.',
})
@Post('login')
@Captcha()
@Public()
public async login(
@Body(new ValidationPipe({ whitelist: true, forbidNonWhitelisted: true }))
loginDto: LoginDto,
@Req() request: FastifyRequest,
) {
const agent = request.headers['user-agent'];
this.logger.debug('UA', agent);
return await this.authService.validateUser(loginDto, agent);
}
@Post('pass/change')
public async changePass() {
return 'yo';
}
@Get('/confirm/:code')
@Public()
public async confirmCode(
@Param(new ValidationPipe()) { code }: CodesDto,
@Res() resp: FastifyReply,
) {
const meta = await this.codesService.fetchCode(code);
switch (meta.type) {
case 'EMAIL_CONFIRM_INIT':
await this.usersService.confirmUserEmail(meta.user, meta.code);
return resp
.status(301)
.redirect('https://dash.file.glass/login?confirmed=true');
case 'EMAIL_CONFIRM_UPDATE':
await this.usersService.setFieldData(meta.user, 'email', meta.excess);
const decrypted = this.utilsService.decrypt(meta.excess!);
await this.usersService.setFieldData(
meta.user,
'email_hash',
this.utilsService.sha(decrypted),
);
await this.codesService.setCodeUsed(meta.code);
return resp
.status(301)
.redirect('https://dash.file.glass/login?changed=true');
default:
throw new InvalidCodeException(false);
}
}
@Get('/2fa/init')
public async init2fa(@Req() req: FastifyRequest) {
return await this.authService.initiallyCreate2faToken(req.user);
}
@Post('/2fa/enable')
public async enable2fa(
@Req() req: FastifyRequest,
@Body(new ValidationPipe({ whitelist: true, forbidNonWhitelisted: true }))
twofactorDto: TwoFactorEnableDto,
) {
if (
!(await this.authService.isPasswordCorrectForUser(
req.user,
twofactorDto.password,
))
) {
throw new InvalidDataException('PASS');
}
if (await this.authService.is2faCodeValid(req.user, twofactorDto.code)) {
await this.authService.toggle2fa(req.user, true);
return GenericRespEnum.TWOFACTOR_ON;
} else {
throw new InvalidDataException('TWOFACTOR');
}
}
@Post('/2fa/disable')
public async disable2fa(
@Req() req: FastifyRequest,
@Body(new ValidationPipe({ whitelist: true, forbidNonWhitelisted: true }))
twofactorDto: TwoFactorDisableDto,
) {
if (
!(await this.authService.isPasswordCorrectForUser(
req.user,
twofactorDto.password,
))
) {
throw new InvalidDataException('PASS');
} else {
await this.authService.toggle2fa(req.user, false);
return GenericRespEnum.TWOFACTOR_OFF;
}
}
@Post('/2fa/login')
@Public()
public async loginVia2fa(
@Body(new ValidationPipe({ whitelist: true, forbidNonWhitelisted: true }))
twofactorDto: TwoFactorLoginDto,
@Req() request: FastifyRequest,
) {
const codeData = await this.codesService.fetchCode(twofactorDto.code);
if (
await this.authService.is2faCodeValid(codeData.user, twofactorDto.token)
) {
await this.codesService.setCodeUsed(codeData.code);
return await this.authService.forceLogUserIn(codeData.user);
} else {
throw new InvalidDataException('TWOFACTOR');
}
}
@Get('/callback/discord')
@Public()
public async discordCb(@Query() query: { code: string }) {
return await this.discordService.onAuth(query.code);
}
@Get('/callback/github')
@Public()
public async githubCb(@Query() query: { code: string }) {
return await this.githubService.onAuth(query.code);
}
@Post('/oauth/setpass')
@Public()
public async setOauthPass(
@Body(new ValidationPipe({ whitelist: true, forbidNonWhitelisted: true }))
dto: SetOauthPassDto,
@Req() request: FastifyRequest,
) {
const code = await this.codesService.fetchCode(dto.code);
const [tok, tokType, userId, type] = JSON.parse(code.excess) as [
string,
string,
string,
OauthCode,
];
this.logger.debug(
'Fetched code:',
code.code,
'token',
tok,
'toktype',
tokType,
);
if (dto.id !== userId) {
throw new UnauthorizedException();
}
switch (type) {
case 'discord':
return await this.authService.handleDiscordOauthPassW(
dto,
userId,
tok,
tokType,
);
case 'github':
return await this.authService.handleGithubOauthPassW(dto, userId, tok);
}
}
@Public()
@Post('/reset/pass')
public async initResetPass(
@Body(new ValidationPipe({ whitelist: true, forbidNonWhitelisted: true }))
dto: InitResetPassDto,
) {
return await this.authService.initResetPass(dto);
}
@Public()
@Post('/reset/pass/set')
public async resetPas(
@Body(new ValidationPipe({ whitelist: true, forbidNonWhitelisted: true }))
dto: ResetPassDto,
) {
return await this.authService.resetPass(dto);
}
@RateLimit({
for: 'Fastify',
keyPrefix: 'resend-verification',
points: 2,
duration: 300,
errorMessage:
'You can only resend two verification emails every 5 minutes.',
})
@Public()
@Post('/confirmation/resend')
public async resendConfEmail(
@Body(new ValidationPipe()) { email }: InitResetPassDto,
) {
const user = await this.usersService.getUser(
this.utilsService.sha(email),
'email_hash',
);
if (user?.snowflake && user?.emailVerified === false) {
const username = await this.usersService.getUsername(user.snowflake);
await this.usersService.sendEmailConfirmation(
email,
user.snowflake,
username,
);
}
return GenericRespEnum.EMAIL_CONF_SENT;
}
}