move session to module
This commit is contained in:
parent
ff431c958c
commit
9c7820dc94
50
src/main.ts
50
src/main.ts
@ -1,9 +1,6 @@
|
||||
import { NestFactory } from '@nestjs/core';
|
||||
import { AppModule } from './app.module';
|
||||
import * as dotenv from 'dotenv';
|
||||
import * as session from 'express-session';
|
||||
import * as connectRedis from 'connect-redis';
|
||||
import * as redis from 'redis';
|
||||
import * as cookieParser from 'cookie-parser';
|
||||
import { join } from 'path';
|
||||
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
|
||||
@ -11,6 +8,7 @@ import { NestExpressApplication } from '@nestjs/platform-express';
|
||||
import { AdminApiModule } from './modules/api/admin/admin.module';
|
||||
import { OAuth2RouterModule } from './modules/static-front-end/oauth2-router/oauth2-router.module';
|
||||
import { ConfigurationService } from './modules/config/config.service';
|
||||
import { ApiModule } from './modules/api/api.module';
|
||||
|
||||
dotenv.config();
|
||||
|
||||
@ -23,20 +21,33 @@ async function bootstrap() {
|
||||
.setTitle('Icy Network Authentication Server')
|
||||
.setDescription('Central authentication and management server')
|
||||
.setVersion('1.0')
|
||||
.addTag('api')
|
||||
.addTag('admin')
|
||||
.addTag('oauth2')
|
||||
.addBearerAuth()
|
||||
.addOAuth2({
|
||||
type: 'oauth2',
|
||||
flows: {
|
||||
authorizationCode: {
|
||||
authorizationUrl: '/oauth2/authorize',
|
||||
tokenUrl: '/oauth2/token',
|
||||
scopes: {
|
||||
email: 'Access email address',
|
||||
image: 'Access profile picture',
|
||||
privileges: 'List of user privileges',
|
||||
management: 'Administrative access',
|
||||
openid: 'Get ID token',
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
.build();
|
||||
const document = SwaggerModule.createDocument(app, docBuilder, {
|
||||
include: [AdminApiModule, OAuth2RouterModule],
|
||||
});
|
||||
SwaggerModule.setup('api', app, document);
|
||||
|
||||
const RedisStore = connectRedis(session);
|
||||
const redisClient = redis.createClient({
|
||||
url: process.env.REDIS_URL || 'redis://localhost:6379',
|
||||
legacyMode: true,
|
||||
const document = SwaggerModule.createDocument(app, docBuilder, {
|
||||
include: [ApiModule, AdminApiModule, OAuth2RouterModule],
|
||||
});
|
||||
redisClient.connect();
|
||||
|
||||
SwaggerModule.setup('api/openapi', app, document);
|
||||
|
||||
// app.use(express.urlencoded());
|
||||
app.use(cookieParser());
|
||||
@ -47,21 +58,6 @@ async function bootstrap() {
|
||||
app.disable('x-powered-by');
|
||||
}
|
||||
|
||||
app.use(
|
||||
/\/((?!api).)*/,
|
||||
session({
|
||||
name: config.get<string>('app.session_name'),
|
||||
secret: config.get<string>('app.session_secret'),
|
||||
resave: true,
|
||||
saveUninitialized: false,
|
||||
store: new RedisStore({ client: redisClient }),
|
||||
cookie: {
|
||||
sameSite: 'strict',
|
||||
secure: process.env.NODE_ENV === 'production',
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
app.useStaticAssets(join(__dirname, '..', 'public'), {
|
||||
prefix: '/public/',
|
||||
});
|
||||
|
@ -3,7 +3,6 @@ import { MulterModule } from '@nestjs/platform-express';
|
||||
import * as multer from 'multer';
|
||||
import * as mime from 'mime-types';
|
||||
import { join } from 'path';
|
||||
import { ConfigurationService } from '../../config/config.service';
|
||||
import { OAuth2Module } from 'src/modules/oauth2/oauth2.module';
|
||||
import { ObjectsModule } from 'src/modules/objects/objects.module';
|
||||
import { OAuth2AdminController } from './oauth2-admin.controller';
|
||||
@ -23,37 +22,34 @@ import { AuditAdminController } from './audit-admin.controller';
|
||||
imports: [
|
||||
ObjectsModule,
|
||||
OAuth2Module,
|
||||
ConfigurationModule,
|
||||
MulterModule.registerAsync({
|
||||
imports: [ConfigurationModule],
|
||||
useFactory: async () => {
|
||||
return {
|
||||
storage: multer.diskStorage({
|
||||
destination: (req, file, cb) => {
|
||||
cb(null, join(__dirname, '..', '..', '..', '..', 'uploads'));
|
||||
},
|
||||
filename: (req, file, cb) => {
|
||||
const hashTruncate = req.user.uuid.split('-')[0];
|
||||
const timestamp = Math.floor(Date.now() / 1000);
|
||||
const ext = mime.extension(file.mimetype);
|
||||
cb(null, `app-${hashTruncate}-${timestamp}.${ext}`);
|
||||
},
|
||||
}),
|
||||
limits: {
|
||||
fileSize: 1.049e7, // 10 MiB
|
||||
useFactory: async () => ({
|
||||
storage: multer.diskStorage({
|
||||
destination: (req, file, cb) => {
|
||||
cb(null, join(__dirname, '..', '..', '..', '..', 'uploads'));
|
||||
},
|
||||
fileFilter: (req, file, cb) => {
|
||||
if (
|
||||
!file.mimetype.startsWith('image/') ||
|
||||
file.mimetype.includes('svg')
|
||||
) {
|
||||
return cb(new Error('Invalid file type.'), false);
|
||||
}
|
||||
filename: (req, file, cb) => {
|
||||
const hashTruncate = req.user.uuid.split('-')[0];
|
||||
const timestamp = Math.floor(Date.now() / 1000);
|
||||
const ext = mime.extension(file.mimetype);
|
||||
cb(null, `app-${hashTruncate}-${timestamp}.${ext}`);
|
||||
},
|
||||
}),
|
||||
limits: {
|
||||
fileSize: 1.049e7, // 10 MiB
|
||||
},
|
||||
fileFilter: (req, file, cb) => {
|
||||
if (
|
||||
!file.mimetype.startsWith('image/') ||
|
||||
file.mimetype.includes('svg')
|
||||
) {
|
||||
return cb(new Error('Invalid file type.'), false);
|
||||
}
|
||||
|
||||
cb(null, true);
|
||||
},
|
||||
};
|
||||
},
|
||||
inject: [ConfigurationService],
|
||||
cb(null, true);
|
||||
},
|
||||
}),
|
||||
}),
|
||||
],
|
||||
providers: [AdminService],
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Controller, Get, Query, UseGuards } from '@nestjs/common';
|
||||
import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
|
||||
import { ApiBearerAuth, ApiOAuth2, ApiTags } from '@nestjs/swagger';
|
||||
import { Privileges } from 'src/decorators/privileges.decorator';
|
||||
import { Scopes } from 'src/decorators/scopes.decorator';
|
||||
import { OAuth2Guard } from 'src/guards/oauth2.guard';
|
||||
@ -14,6 +14,7 @@ import { PageOptions } from 'src/types/pagination.interfaces';
|
||||
|
||||
@ApiBearerAuth()
|
||||
@ApiTags('admin')
|
||||
@ApiOAuth2(['management'])
|
||||
@Controller('/api/admin/audit')
|
||||
@UseGuards(OAuth2Guard, PrivilegesGuard, ScopesGuard)
|
||||
export class AuditAdminController {
|
||||
|
@ -15,7 +15,7 @@ import {
|
||||
UseGuards,
|
||||
UseInterceptors,
|
||||
} from '@nestjs/common';
|
||||
import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
|
||||
import { ApiBearerAuth, ApiOAuth2, ApiTags } from '@nestjs/swagger';
|
||||
import { FileInterceptor } from '@nestjs/platform-express';
|
||||
import { unlink } from 'fs/promises';
|
||||
import { Privileges } from 'src/decorators/privileges.decorator';
|
||||
@ -57,6 +57,7 @@ const REQUIRED_CLIENT_FIELDS = ['title', 'grants', 'activated'];
|
||||
|
||||
@ApiBearerAuth()
|
||||
@ApiTags('admin')
|
||||
@ApiOAuth2(['management'])
|
||||
@Controller('/api/admin/oauth2')
|
||||
@UseGuards(OAuth2Guard, PrivilegesGuard, ScopesGuard)
|
||||
export class OAuth2AdminController {
|
||||
|
@ -6,7 +6,7 @@ import {
|
||||
Post,
|
||||
UseGuards,
|
||||
} from '@nestjs/common';
|
||||
import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
|
||||
import { ApiBearerAuth, ApiOAuth2, ApiTags } from '@nestjs/swagger';
|
||||
import { Privileges } from 'src/decorators/privileges.decorator';
|
||||
import { Scopes } from 'src/decorators/scopes.decorator';
|
||||
import { OAuth2Guard } from 'src/guards/oauth2.guard';
|
||||
@ -16,6 +16,7 @@ import { PrivilegeService } from 'src/modules/objects/privilege/privilege.servic
|
||||
|
||||
@ApiBearerAuth()
|
||||
@ApiTags('admin')
|
||||
@ApiOAuth2(['management'])
|
||||
@Controller('/api/admin/privileges')
|
||||
@UseGuards(OAuth2Guard, PrivilegesGuard, ScopesGuard)
|
||||
export class PrivilegeAdminController {
|
||||
|
@ -12,7 +12,7 @@ import {
|
||||
Query,
|
||||
UseGuards,
|
||||
} from '@nestjs/common';
|
||||
import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
|
||||
import { ApiBearerAuth, ApiOAuth2, ApiTags } from '@nestjs/swagger';
|
||||
import { Privileges } from 'src/decorators/privileges.decorator';
|
||||
import { Scopes } from 'src/decorators/scopes.decorator';
|
||||
import { OAuth2Guard } from 'src/guards/oauth2.guard';
|
||||
@ -29,6 +29,7 @@ const RELATIONS = ['picture', 'privileges'];
|
||||
|
||||
@ApiBearerAuth()
|
||||
@ApiTags('admin')
|
||||
@ApiOAuth2(['management'])
|
||||
@Controller('/api/admin/users')
|
||||
@UseGuards(OAuth2Guard, PrivilegesGuard, ScopesGuard)
|
||||
export class UserAdminController {
|
||||
|
@ -19,7 +19,9 @@ import { OAuth2ClientService } from '../objects/oauth2-client/oauth2-client.serv
|
||||
import { User } from '../objects/user/user.entity';
|
||||
import { FormUtilityService } from '../utility/services/form-utility.service';
|
||||
import { UploadService } from '../objects/upload/upload.service';
|
||||
import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
|
||||
|
||||
@ApiTags('api')
|
||||
@Controller({
|
||||
path: '/api',
|
||||
})
|
||||
@ -31,7 +33,22 @@ export class ApiController {
|
||||
private _upload: UploadService,
|
||||
) {}
|
||||
|
||||
@Get()
|
||||
welcome() {
|
||||
return {
|
||||
welcome: { to: 'Icy Network!' },
|
||||
api: true,
|
||||
oauth2: {
|
||||
authorizationUrl: '/oauth2/authorize',
|
||||
tokenUrl: '/oauth2/token',
|
||||
userUrl: '/api/user',
|
||||
},
|
||||
swaggerdoc: '/api/openapi',
|
||||
};
|
||||
}
|
||||
|
||||
@Get('/user')
|
||||
@ApiBearerAuth()
|
||||
@UseGuards(OAuth2Guard)
|
||||
getCurrentUser(@CurrentUser() user: User, @Scope() scopeStr: string) {
|
||||
const scope = scopeStr.split(' ');
|
||||
@ -73,6 +90,7 @@ export class ApiController {
|
||||
}
|
||||
|
||||
@Get('/client')
|
||||
@ApiBearerAuth()
|
||||
@UseGuards(OAuth2Guard, ScopesGuard)
|
||||
async getCurrentClient(@Bearer() token: OAuth2AccessToken) {
|
||||
const client = await this._oaClient.getById(token.client_id, [
|
||||
@ -90,6 +108,7 @@ export class ApiController {
|
||||
}
|
||||
|
||||
@Get('/upload/:file')
|
||||
@ApiBearerAuth()
|
||||
@UseGuards(OAuth2Guard)
|
||||
async sendFile(@Param('file') fileName: string) {
|
||||
const cleanFile = decodeURI(fileName).replace(/(\&(.*))/, '');
|
||||
|
@ -1,9 +1,5 @@
|
||||
import {
|
||||
MiddlewareConsumer,
|
||||
Module,
|
||||
NestModule,
|
||||
RequestMethod,
|
||||
} from '@nestjs/common';
|
||||
import { Inject, MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
|
||||
import { RequestHandler } from 'express';
|
||||
import { CSRFMiddleware } from 'src/middleware/csrf.middleware';
|
||||
import { FlashMiddleware } from 'src/middleware/flash.middleware';
|
||||
import { UserMiddleware } from 'src/middleware/user.middleware';
|
||||
@ -11,19 +7,25 @@ import { ValidateCSRFMiddleware } from 'src/middleware/validate-csrf.middleware'
|
||||
import { AuditModule } from 'src/modules/objects/audit/audit.module';
|
||||
import { UserTokenModule } from 'src/modules/objects/user-token/user-token.module';
|
||||
import { UserModule } from 'src/modules/objects/user/user.module';
|
||||
import { SessionModule } from '../session/session.module';
|
||||
import { LoginController } from './login.controller';
|
||||
|
||||
@Module({
|
||||
imports: [UserModule, UserTokenModule, AuditModule],
|
||||
imports: [UserModule, UserTokenModule, AuditModule, SessionModule],
|
||||
controllers: [LoginController],
|
||||
})
|
||||
export class LoginModule implements NestModule {
|
||||
configure(consumer: MiddlewareConsumer) {
|
||||
consumer.apply(CSRFMiddleware, UserMiddleware).forRoutes(LoginController);
|
||||
consumer
|
||||
.apply(ValidateCSRFMiddleware)
|
||||
.forRoutes({ path: 'login*', method: RequestMethod.POST });
|
||||
constructor(@Inject('SESSION') private _session: RequestHandler) {}
|
||||
|
||||
consumer.apply(FlashMiddleware).forRoutes('login*');
|
||||
configure(consumer: MiddlewareConsumer) {
|
||||
consumer
|
||||
.apply(
|
||||
this._session,
|
||||
CSRFMiddleware,
|
||||
FlashMiddleware,
|
||||
UserMiddleware,
|
||||
ValidateCSRFMiddleware,
|
||||
)
|
||||
.forRoutes(LoginController);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
|
||||
import { Inject, MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
|
||||
import { RequestHandler } from 'express';
|
||||
// import * as cors from 'cors';
|
||||
import { AuthMiddleware } from 'src/middleware/auth.middleware';
|
||||
import { CSRFMiddleware } from 'src/middleware/csrf.middleware';
|
||||
@ -7,26 +8,31 @@ import { ValidateCSRFMiddleware } from 'src/middleware/validate-csrf.middleware'
|
||||
import { OAuth2Module } from 'src/modules/oauth2/oauth2.module';
|
||||
import { OAuth2Service } from 'src/modules/oauth2/oauth2.service';
|
||||
import { UserModule } from 'src/modules/objects/user/user.module';
|
||||
import { SessionModule } from '../session/session.module';
|
||||
import { OAuth2Controller } from './oauth2-router.controller';
|
||||
|
||||
@Module({
|
||||
controllers: [OAuth2Controller],
|
||||
imports: [OAuth2Module, UserModule],
|
||||
imports: [OAuth2Module, UserModule, SessionModule],
|
||||
})
|
||||
export class OAuth2RouterModule implements NestModule {
|
||||
// private corsOpts = cors({ origin: true, credentials: true });
|
||||
|
||||
constructor(private _service: OAuth2Service) {}
|
||||
constructor(
|
||||
private _service: OAuth2Service,
|
||||
@Inject('SESSION') private _session: RequestHandler,
|
||||
) {}
|
||||
|
||||
configure(consumer: MiddlewareConsumer) {
|
||||
consumer
|
||||
.apply(
|
||||
this._session,
|
||||
CSRFMiddleware,
|
||||
UserMiddleware,
|
||||
AuthMiddleware,
|
||||
ValidateCSRFMiddleware,
|
||||
)
|
||||
.forRoutes('oauth2/authorize');
|
||||
.forRoutes('/oauth2/authorize');
|
||||
|
||||
// consumer
|
||||
// .apply(this.corsOpts)
|
||||
|
@ -1,31 +1,30 @@
|
||||
import {
|
||||
MiddlewareConsumer,
|
||||
Module,
|
||||
NestModule,
|
||||
RequestMethod,
|
||||
} from '@nestjs/common';
|
||||
import { Inject, MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
|
||||
import { RequestHandler } from 'express';
|
||||
import { CSRFMiddleware } from 'src/middleware/csrf.middleware';
|
||||
import { FlashMiddleware } from 'src/middleware/flash.middleware';
|
||||
import { UserMiddleware } from 'src/middleware/user.middleware';
|
||||
import { ValidateCSRFMiddleware } from 'src/middleware/validate-csrf.middleware';
|
||||
import { AuditModule } from 'src/modules/objects/audit/audit.module';
|
||||
import { UserModule } from 'src/modules/objects/user/user.module';
|
||||
import { SessionModule } from '../session/session.module';
|
||||
import { RegisterController } from './register.controller';
|
||||
|
||||
@Module({
|
||||
imports: [UserModule, AuditModule],
|
||||
imports: [UserModule, AuditModule, SessionModule],
|
||||
controllers: [RegisterController],
|
||||
})
|
||||
export class RegisterModule implements NestModule {
|
||||
constructor(@Inject('SESSION') private _session: RequestHandler) {}
|
||||
|
||||
configure(consumer: MiddlewareConsumer) {
|
||||
consumer
|
||||
.apply(CSRFMiddleware, UserMiddleware)
|
||||
.apply(
|
||||
this._session,
|
||||
CSRFMiddleware,
|
||||
FlashMiddleware,
|
||||
UserMiddleware,
|
||||
ValidateCSRFMiddleware,
|
||||
)
|
||||
.forRoutes(RegisterController);
|
||||
|
||||
consumer
|
||||
.apply(ValidateCSRFMiddleware)
|
||||
.forRoutes({ path: 'register*', method: RequestMethod.POST });
|
||||
|
||||
consumer.apply(FlashMiddleware).forRoutes('register*');
|
||||
}
|
||||
}
|
||||
|
10
src/modules/static-front-end/session/session.module.ts
Normal file
10
src/modules/static-front-end/session/session.module.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { ConfigurationModule } from 'src/modules/config/config.module';
|
||||
import { sessionProviders } from './session.providers';
|
||||
|
||||
@Module({
|
||||
providers: [...sessionProviders],
|
||||
exports: [...sessionProviders],
|
||||
imports: [ConfigurationModule],
|
||||
})
|
||||
export class SessionModule {}
|
49
src/modules/static-front-end/session/session.providers.ts
Normal file
49
src/modules/static-front-end/session/session.providers.ts
Normal file
@ -0,0 +1,49 @@
|
||||
import { FactoryProvider } from '@nestjs/common';
|
||||
import { ConfigurationService } from 'src/modules/config/config.service';
|
||||
|
||||
import * as session from 'express-session';
|
||||
import * as connectRedis from 'connect-redis';
|
||||
import * as redis from 'redis';
|
||||
import { RequestHandler } from 'express';
|
||||
|
||||
export const sessionProviders = [
|
||||
{
|
||||
provide: 'SESSION_STORE',
|
||||
useFactory: async (
|
||||
config: ConfigurationService,
|
||||
): Promise<connectRedis.RedisStore> => {
|
||||
const RedisStore = connectRedis(session);
|
||||
const redisClient = redis.createClient({
|
||||
url:
|
||||
process.env.REDIS_URL ||
|
||||
config.get<string>('app.redis_url') ||
|
||||
'redis://localhost:6379',
|
||||
legacyMode: true,
|
||||
});
|
||||
|
||||
await redisClient.connect();
|
||||
|
||||
return new RedisStore({ client: redisClient });
|
||||
},
|
||||
inject: [ConfigurationService],
|
||||
} as FactoryProvider<connectRedis.RedisStore>,
|
||||
{
|
||||
provide: 'SESSION',
|
||||
useFactory: (
|
||||
store: connectRedis.RedisStore,
|
||||
config: ConfigurationService,
|
||||
) =>
|
||||
session({
|
||||
name: config.get<string>('app.session_name'),
|
||||
secret: config.get<string>('app.session_secret'),
|
||||
resave: true,
|
||||
saveUninitialized: false,
|
||||
store,
|
||||
cookie: {
|
||||
sameSite: 'strict',
|
||||
secure: process.env.NODE_ENV === 'production',
|
||||
},
|
||||
}),
|
||||
inject: ['SESSION_STORE', ConfigurationService],
|
||||
} as FactoryProvider<RequestHandler>,
|
||||
];
|
@ -1,9 +1,4 @@
|
||||
import {
|
||||
MiddlewareConsumer,
|
||||
Module,
|
||||
NestModule,
|
||||
RequestMethod,
|
||||
} from '@nestjs/common';
|
||||
import { Inject, MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
|
||||
import { MulterModule } from '@nestjs/platform-express';
|
||||
import * as multer from 'multer';
|
||||
import * as mime from 'mime-types';
|
||||
@ -12,7 +7,6 @@ import { AuthMiddleware } from 'src/middleware/auth.middleware';
|
||||
import { FlashMiddleware } from 'src/middleware/flash.middleware';
|
||||
import { ValidateCSRFMiddleware } from 'src/middleware/validate-csrf.middleware';
|
||||
import { ConfigurationModule } from 'src/modules/config/config.module';
|
||||
import { ConfigurationService } from 'src/modules/config/config.service';
|
||||
import { UploadModule } from 'src/modules/objects/upload/upload.module';
|
||||
import { UserModule } from 'src/modules/objects/user/user.module';
|
||||
import { OAuth2TokenModule } from 'src/modules/objects/oauth2-token/oauth2-token.module';
|
||||
@ -24,6 +18,8 @@ import { SettingsService } from './settings.service';
|
||||
import { CSRFMiddleware } from 'src/middleware/csrf.middleware';
|
||||
import { UserMiddleware } from 'src/middleware/user.middleware';
|
||||
import { AuditModule } from 'src/modules/objects/audit/audit.module';
|
||||
import { RequestHandler } from 'express';
|
||||
import { SessionModule } from '../session/session.module';
|
||||
|
||||
@Module({
|
||||
controllers: [SettingsController],
|
||||
@ -32,59 +28,55 @@ import { AuditModule } from 'src/modules/objects/audit/audit.module';
|
||||
UploadModule,
|
||||
UserModule,
|
||||
UserTokenModule,
|
||||
SessionModule,
|
||||
AuditModule,
|
||||
OAuth2Module,
|
||||
OAuth2ClientModule,
|
||||
OAuth2TokenModule,
|
||||
MulterModule.registerAsync({
|
||||
imports: [ConfigurationModule],
|
||||
useFactory: async (config: ConfigurationService) => {
|
||||
return {
|
||||
storage: multer.diskStorage({
|
||||
destination: (req, file, cb) => {
|
||||
cb(null, join(__dirname, '..', '..', '..', '..', 'uploads'));
|
||||
},
|
||||
filename: (req, file, cb) => {
|
||||
const hashTruncate = req.user.uuid.split('-')[0];
|
||||
const timestamp = Math.floor(Date.now() / 1000);
|
||||
const ext = mime.extension(file.mimetype);
|
||||
cb(null, `user-${hashTruncate}-${timestamp}.${ext}`);
|
||||
},
|
||||
}),
|
||||
limits: {
|
||||
fileSize: 1.049e7, // 10 MiB
|
||||
useFactory: async () => ({
|
||||
storage: multer.diskStorage({
|
||||
destination: (req, file, cb) => {
|
||||
cb(null, join(__dirname, '..', '..', '..', '..', 'uploads'));
|
||||
},
|
||||
fileFilter: (req, file, cb) => {
|
||||
if (
|
||||
!file.mimetype.startsWith('image/') ||
|
||||
file.mimetype.includes('svg')
|
||||
) {
|
||||
return cb(new Error('Invalid file type.'), false);
|
||||
}
|
||||
filename: (req, file, cb) => {
|
||||
const hashTruncate = req.user.uuid.split('-')[0];
|
||||
const timestamp = Math.floor(Date.now() / 1000);
|
||||
const ext = mime.extension(file.mimetype);
|
||||
cb(null, `user-${hashTruncate}-${timestamp}.${ext}`);
|
||||
},
|
||||
}),
|
||||
limits: {
|
||||
fileSize: 1.049e7, // 10 MiB
|
||||
},
|
||||
fileFilter: (req, file, cb) => {
|
||||
if (
|
||||
!file.mimetype.startsWith('image/') ||
|
||||
file.mimetype.includes('svg')
|
||||
) {
|
||||
return cb(new Error('Invalid file type.'), false);
|
||||
}
|
||||
|
||||
cb(null, true);
|
||||
},
|
||||
};
|
||||
},
|
||||
inject: [ConfigurationService],
|
||||
cb(null, true);
|
||||
},
|
||||
}),
|
||||
}),
|
||||
],
|
||||
providers: [SettingsService],
|
||||
})
|
||||
export class SettingsModule implements NestModule {
|
||||
constructor(@Inject('SESSION') private _session: RequestHandler) {}
|
||||
|
||||
configure(consumer: MiddlewareConsumer) {
|
||||
consumer
|
||||
.apply(CSRFMiddleware, UserMiddleware)
|
||||
.apply(
|
||||
this._session,
|
||||
CSRFMiddleware,
|
||||
FlashMiddleware,
|
||||
UserMiddleware,
|
||||
AuthMiddleware,
|
||||
ValidateCSRFMiddleware,
|
||||
)
|
||||
.forRoutes(SettingsController);
|
||||
consumer
|
||||
.apply(ValidateCSRFMiddleware)
|
||||
.forRoutes(
|
||||
{ path: '/account*', method: RequestMethod.POST },
|
||||
{ path: '/account*', method: RequestMethod.PATCH },
|
||||
{ path: '/account*', method: RequestMethod.DELETE },
|
||||
);
|
||||
|
||||
consumer.apply(AuthMiddleware).forRoutes('account*');
|
||||
consumer.apply(FlashMiddleware).forRoutes('account*');
|
||||
}
|
||||
}
|
||||
|
@ -6,11 +6,13 @@ import { ObjectsModule } from '../objects/objects.module';
|
||||
import { LoginModule } from './login/login.module';
|
||||
import { OAuth2RouterModule } from './oauth2-router/oauth2-router.module';
|
||||
import { RegisterModule } from './register/register.module';
|
||||
import { SessionModule } from './session/session.module';
|
||||
import { SettingsModule } from './settings/settings.module';
|
||||
import { TwoFactorModule } from './two-factor/two-factor.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
SessionModule,
|
||||
ConfigurationModule,
|
||||
JWTModule,
|
||||
|
||||
|
@ -1,23 +1,33 @@
|
||||
import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
|
||||
import { Inject, MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
|
||||
import { RequestHandler } from 'express';
|
||||
import { AuthMiddleware } from 'src/middleware/auth.middleware';
|
||||
import { CSRFMiddleware } from 'src/middleware/csrf.middleware';
|
||||
import { FlashMiddleware } from 'src/middleware/flash.middleware';
|
||||
import { UserMiddleware } from 'src/middleware/user.middleware';
|
||||
import { ValidateCSRFMiddleware } from 'src/middleware/validate-csrf.middleware';
|
||||
import { AuditModule } from 'src/modules/objects/audit/audit.module';
|
||||
import { UserTokenModule } from 'src/modules/objects/user-token/user-token.module';
|
||||
import { UserModule } from 'src/modules/objects/user/user.module';
|
||||
import { SessionModule } from '../session/session.module';
|
||||
import { TwoFactorController } from './two-factor.controller';
|
||||
|
||||
@Module({
|
||||
imports: [UserModule, UserTokenModule, AuditModule],
|
||||
imports: [UserModule, UserTokenModule, AuditModule, SessionModule],
|
||||
controllers: [TwoFactorController],
|
||||
})
|
||||
export class TwoFactorModule implements NestModule {
|
||||
constructor(@Inject('SESSION') private _session: RequestHandler) {}
|
||||
|
||||
configure(consumer: MiddlewareConsumer) {
|
||||
consumer
|
||||
.apply(CSRFMiddleware, UserMiddleware)
|
||||
.apply(
|
||||
this._session,
|
||||
CSRFMiddleware,
|
||||
UserMiddleware,
|
||||
AuthMiddleware,
|
||||
FlashMiddleware,
|
||||
ValidateCSRFMiddleware,
|
||||
)
|
||||
.forRoutes(TwoFactorController);
|
||||
consumer.apply(AuthMiddleware).forRoutes('account/two-factor/activate');
|
||||
consumer.apply(FlashMiddleware).forRoutes('account/two-factor/activate');
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user