Fixed/cleaned auth validation. Added 404 response when registrations are disabled.
This commit is contained in:
@ -4,7 +4,7 @@ import { config } from './config';
|
|||||||
@Controller('asset')
|
@Controller('asset')
|
||||||
export class ConfigController {
|
export class ConfigController {
|
||||||
@Get('config')
|
@Get('config')
|
||||||
async login(
|
async config(
|
||||||
@Request() req,
|
@Request() req,
|
||||||
) {
|
) {
|
||||||
return {
|
return {
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
export const config = {
|
export const config = {
|
||||||
register_enabled: false,
|
features: {
|
||||||
|
registration: false,
|
||||||
|
},
|
||||||
}
|
}
|
@ -11,6 +11,7 @@ import { PinoLogger } from 'nestjs-pino';
|
|||||||
import { JwtAccessGuard } from './guards/jwt-access.guard';
|
import { JwtAccessGuard } from './guards/jwt-access.guard';
|
||||||
import { LoginDto } from './dto/login.dto';
|
import { LoginDto } from './dto/login.dto';
|
||||||
import { AuthenticationDto } from './dto/authentication.dto';
|
import { AuthenticationDto } from './dto/authentication.dto';
|
||||||
|
import { config } from 'src/asset/config/config';
|
||||||
|
|
||||||
@Controller('auth')
|
@Controller('auth')
|
||||||
export class AuthController {
|
export class AuthController {
|
||||||
@ -187,6 +188,14 @@ export class AuthController {
|
|||||||
@Res({ passthrough: true }) response: Response,
|
@Res({ passthrough: true }) response: Response,
|
||||||
@Body() body: RegisterUserDto,
|
@Body() body: RegisterUserDto,
|
||||||
) {
|
) {
|
||||||
|
if (!config.features.registration) {
|
||||||
|
response.statusCode = 404;
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
error_message: 'Registration disabled.',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
let user: UserEntity | null;
|
let user: UserEntity | null;
|
||||||
let data: AuthenticationDto | null;
|
let data: AuthenticationDto | null;
|
||||||
try {
|
try {
|
||||||
|
@ -6,7 +6,7 @@ import { AuthController } from './auth.controller';
|
|||||||
import { ConfigModule, ConfigService } from '@nestjs/config';
|
import { ConfigModule, ConfigService } from '@nestjs/config';
|
||||||
import { JwtModule } from '@nestjs/jwt';
|
import { JwtModule } from '@nestjs/jwt';
|
||||||
import { JwtOptions } from './jwt.options';
|
import { JwtOptions } from './jwt.options';
|
||||||
import { JwtStrategy } from './strategies/jwt.strategy';
|
import { JwtAccessStrategy } from './strategies/jwt-access.strategy';
|
||||||
import { AuthRefreshService } from './auth.refresh.service';
|
import { AuthRefreshService } from './auth.refresh.service';
|
||||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||||
import { AuthRefreshTokenEntity } from './entities/auth.refresh-token.entity';
|
import { AuthRefreshTokenEntity } from './entities/auth.refresh-token.entity';
|
||||||
@ -34,7 +34,7 @@ import { JwtRefreshStrategy } from './strategies/jwt-refresh.strategy';
|
|||||||
AuthAccessService,
|
AuthAccessService,
|
||||||
AuthRefreshService,
|
AuthRefreshService,
|
||||||
AuthService,
|
AuthService,
|
||||||
JwtStrategy,
|
JwtAccessStrategy,
|
||||||
JwtRefreshStrategy,
|
JwtRefreshStrategy,
|
||||||
],
|
],
|
||||||
controllers: [AuthController]
|
controllers: [AuthController]
|
||||||
|
@ -60,60 +60,60 @@ export class AuthService {
|
|||||||
accessToken: string,
|
accessToken: string,
|
||||||
refreshToken: string
|
refreshToken: string
|
||||||
): Promise<{ validation: boolean, userId: UUID | null, username: string | null }> {
|
): Promise<{ validation: boolean, userId: UUID | null, username: string | null }> {
|
||||||
if (!accessToken) {
|
let access: any = null;
|
||||||
if (!refreshToken) {
|
let refresh: any = null;
|
||||||
return {
|
|
||||||
validation: false,
|
|
||||||
userId: null,
|
|
||||||
username: null,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const refresh = await this.refreshTokens.verify(refreshToken);
|
if (accessToken) {
|
||||||
if (refresh.message || !refresh.exp || refresh.exp * 1000 <= new Date().getTime()) {
|
access = await this.accessTokens.verify(accessToken);
|
||||||
|
if (!access.username || !access.sub) {
|
||||||
return {
|
return {
|
||||||
validation: false,
|
validation: false,
|
||||||
userId: null,
|
userId: null,
|
||||||
username: null,
|
username: null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (refreshToken) {
|
||||||
|
refresh = await this.refreshTokens.verify(refreshToken);
|
||||||
|
if (!refresh.username || !refresh.sub) {
|
||||||
|
return {
|
||||||
|
validation: false,
|
||||||
|
userId: null,
|
||||||
|
username: null,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (accessToken && refreshToken) {
|
||||||
|
if (access.username != refresh.username || access.sub != refresh.sub) {
|
||||||
|
return {
|
||||||
|
validation: false,
|
||||||
|
userId: null,
|
||||||
|
username: null,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!accessToken || !access.exp || access.exp * 1000 <= new Date().getTime()) {
|
||||||
|
if (!refreshToken || !refresh.exp || refresh.exp * 1000 <= new Date().getTime()) {
|
||||||
|
// Both expired.
|
||||||
|
return {
|
||||||
|
validation: false,
|
||||||
|
userId: null,
|
||||||
|
username: null,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Refresh token is still active.
|
||||||
return {
|
return {
|
||||||
validation: null,
|
validation: null,
|
||||||
userId: refresh.sub,
|
userId: refresh.sub,
|
||||||
username: refresh.username,
|
username: refresh.username,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
const access = await this.accessTokens.verify(accessToken);
|
|
||||||
const refresh = await this.refreshTokens.verify(refreshToken);
|
|
||||||
if (!access.username || !refresh.username || access.username != refresh.username) {
|
|
||||||
return {
|
|
||||||
validation: false,
|
|
||||||
userId: null,
|
|
||||||
username: null,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (!access.sub || !refresh.sub || access.sub != refresh.sub) {
|
|
||||||
return {
|
|
||||||
validation: false,
|
|
||||||
userId: null,
|
|
||||||
username: null,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (access.message || !access.exp || access.exp * 1000 <= new Date().getTime()) {
|
// Access still active, at least.
|
||||||
if (refresh.message || !refresh.exp || refresh.exp * 1000 <= new Date().getTime()) {
|
|
||||||
return {
|
|
||||||
validation: false,
|
|
||||||
userId: null,
|
|
||||||
username: null,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
validation: null,
|
|
||||||
userId: access.sub,
|
|
||||||
username: access.username,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return {
|
return {
|
||||||
validation: true,
|
validation: true,
|
||||||
userId: access.sub,
|
userId: access.sub,
|
||||||
|
@ -6,12 +6,12 @@ import { ConfigService } from '@nestjs/config';
|
|||||||
import { UsersService } from 'src/users/users.service';
|
import { UsersService } from 'src/users/users.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class JwtStrategy extends PassportStrategy(Strategy, 'jwt-access') {
|
export class JwtAccessStrategy extends PassportStrategy(Strategy, 'jwt-access') {
|
||||||
constructor(private users: UsersService, private config: ConfigService) {
|
constructor(private users: UsersService, private config: ConfigService) {
|
||||||
super({
|
super({
|
||||||
jwtFromRequest: ExtractJwt.fromExtractors([
|
jwtFromRequest: ExtractJwt.fromExtractors([
|
||||||
//ExtractJwt.fromAuthHeaderAsBearerToken(),
|
//ExtractJwt.fromAuthHeaderAsBearerToken(),
|
||||||
JwtStrategy.extract,
|
JwtAccessStrategy.extract,
|
||||||
]),
|
]),
|
||||||
ignoreExpiration: false,
|
ignoreExpiration: false,
|
||||||
secretOrKey: config.getOrThrow<string>('AUTH_JWT_ACCESS_TOKEN_SECRET'),
|
secretOrKey: config.getOrThrow<string>('AUTH_JWT_ACCESS_TOKEN_SECRET'),
|
Reference in New Issue
Block a user