This commit is contained in:
1 parent
c5691da2b8
commit
de1b3754df
6 files changed
+949
-1165
No files matched your search
Generated
+909
-1130
File diff suppressed because it is too large.
Load diff
+17
-19
@@ -24,49 +24,47 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@apollo/server": "^5.5.1",
|
"@apollo/server": "^5.5.1",
|
||||||
"@as-integrations/express5": "^1.1.2",
|
"@as-integrations/express5": "^1.1.2",
|
||||||
"@aws-sdk/client-s3": "^3.1145.0",
|
"@aws-sdk/client-s3": "^3.1152.0",
|
||||||
"@better-auth/prisma-adapter": "^1.7.2",
|
"@better-auth/prisma-adapter": "^1.7.11",
|
||||||
"@nestjs/apollo": "^14.0.0",
|
"@nestjs/apollo": "^14.0.0",
|
||||||
"@nestjs/common": "^12.0.1",
|
"@nestjs/common": "^12.2.0",
|
||||||
"@nestjs/config": "^12.0.0",
|
"@nestjs/config": "^12.0.1",
|
||||||
"@nestjs/core": "^12.0.1",
|
"@nestjs/core": "^12.2.0",
|
||||||
"@nestjs/event-emitter": "^12.0.1",
|
"@nestjs/event-emitter": "^12.0.1",
|
||||||
"@nestjs/graphql": "^14.0.0",
|
"@nestjs/graphql": "^14.0.0",
|
||||||
"@nestjs/platform-express": "^12.0.1",
|
"@nestjs/platform-express": "^12.2.0",
|
||||||
"@nestjs/schedule": "^12.0.2",
|
"@nestjs/schedule": "^12.0.2",
|
||||||
"@nestjs/typeorm": "^12.0.1",
|
|
||||||
"@prisma/adapter-pg": "^7.10.0",
|
"@prisma/adapter-pg": "^7.10.0",
|
||||||
"@prisma/client": "^7.10.0",
|
"@prisma/client": "^7.10.0",
|
||||||
"@thallesp/nestjs-better-auth": "^2.7.0",
|
"@thallesp/nestjs-better-auth": "^2.8.0",
|
||||||
"better-auth": "^1.7.2",
|
"better-auth": "^1.7.11",
|
||||||
"class-transformer": "^0.5.1",
|
"class-transformer": "^0.5.1",
|
||||||
"class-validator": "^0.15.1",
|
"class-validator": "^0.15.1",
|
||||||
"file-type": "^22.1.1",
|
"file-type": "^22.2.0",
|
||||||
"firebase-admin": "^14.5.0",
|
"firebase-admin": "^14.5.0",
|
||||||
"graphql": "^16.14.2",
|
"graphql": "^16.14.2",
|
||||||
"nodemailer": "^10.0.0",
|
"nodemailer": "^10.1.7",
|
||||||
"pg": "^8.23.0",
|
"pg": "^8.23.0",
|
||||||
"reflect-metadata": "^0.2.2",
|
"reflect-metadata": "^0.2.2",
|
||||||
"rxjs": "^7.8.1",
|
"rxjs": "^7.8.1",
|
||||||
"typeorm": "^1.1.1",
|
"valibot": "^1.5.0"
|
||||||
"valibot": "^1.4.2"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@nestjs/cli": "^12.0.0",
|
"@nestjs/cli": "^12.0.0",
|
||||||
"@nestjs/mau": "^0.2.6",
|
"@nestjs/mau": "^0.2.8",
|
||||||
"@nestjs/schematics": "^12.0.0",
|
"@nestjs/schematics": "^12.0.0",
|
||||||
"@nestjs/testing": "^12.0.1",
|
"@nestjs/testing": "^12.2.0",
|
||||||
"@types/express": "^5.0.0",
|
"@types/express": "^5.0.0",
|
||||||
"@types/multer": "^2.3.0",
|
"@types/multer": "^2.3.0",
|
||||||
"@types/node": "^24.0.0",
|
"@types/node": "^24.0.0",
|
||||||
"@types/pg": "^8.23.1",
|
"@types/pg": "^8.23.1",
|
||||||
"@types/supertest": "^7.0.0",
|
"@types/supertest": "^7.2.1",
|
||||||
"@vitest/coverage-v8": "^4.1.2",
|
"@vitest/coverage-v8": "^4.1.2",
|
||||||
"oxlint": "^1.58.0",
|
"oxlint": "^1.88.0",
|
||||||
"prettier": "^3.4.2",
|
"prettier": "^3.9.10",
|
||||||
"prisma": "^7.10.0",
|
"prisma": "^7.10.0",
|
||||||
"source-map-support": "^0.5.21",
|
"source-map-support": "^0.5.21",
|
||||||
"supertest": "^7.0.0",
|
"supertest": "^7.3.1",
|
||||||
"typescript": "^6.0.2",
|
"typescript": "^6.0.2",
|
||||||
"vite-tsconfig-paths": "^5.1.4",
|
"vite-tsconfig-paths": "^5.1.4",
|
||||||
"vitest": "^4.1.2"
|
"vitest": "^4.1.2"
|
||||||
|
|||||||
@@ -26,21 +26,13 @@ import { join } from 'node:path';
|
|||||||
isGlobal: true,
|
isGlobal: true,
|
||||||
cache: true,
|
cache: true,
|
||||||
}),
|
}),
|
||||||
// Внутрипроцессная шина доменных событий. Notification-модуль слушает
|
|
||||||
// события через неё, не завязываясь на модули, которые их порождают.
|
|
||||||
EventEmitterModule.forRoot(),
|
EventEmitterModule.forRoot(),
|
||||||
// Периодические задачи (@Cron), например сборка файлов-сирот в FileModule
|
|
||||||
ScheduleModule.forRoot(),
|
ScheduleModule.forRoot(),
|
||||||
GraphQLModule.forRoot<ApolloDriverConfig>({
|
GraphQLModule.forRoot<ApolloDriverConfig>({
|
||||||
driver: ApolloDriver,
|
driver: ApolloDriver,
|
||||||
autoSchemaFile: join(process.cwd(), 'src/schema.gql'),
|
autoSchemaFile: join(process.cwd(), 'src/schema.gql'),
|
||||||
sortSchema: true,
|
sortSchema: true,
|
||||||
}),
|
}),
|
||||||
// TypeOrmModule.forRootAsync({
|
|
||||||
// imports: [ConfigModule],
|
|
||||||
// inject: [ConfigService],
|
|
||||||
// useFactory: pgConfig,
|
|
||||||
// }),
|
|
||||||
AuthModule.forRoot({
|
AuthModule.forRoot({
|
||||||
auth: auth,
|
auth: auth,
|
||||||
bodyParser: {
|
bodyParser: {
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { ConfigService } from '@nestjs/config';
|
import { ConfigService } from '@nestjs/config';
|
||||||
import { TypeOrmModuleOptions } from '@nestjs/typeorm';
|
|
||||||
|
|
||||||
export function pgConfig(config: ConfigService): TypeOrmModuleOptions {
|
export function pgConfig(config: ConfigService): unknown {
|
||||||
return {
|
return {
|
||||||
type: 'postgres',
|
type: 'postgres',
|
||||||
url: config.getOrThrow<string>('DATABASE_URL'),
|
url: config.getOrThrow<string>('DATABASE_URL'),
|
||||||
|
|||||||
+22
-1
@@ -2,12 +2,33 @@ import { betterAuth } from 'better-auth';
|
|||||||
import { prismaAdapter } from '@better-auth/prisma-adapter';
|
import { prismaAdapter } from '@better-auth/prisma-adapter';
|
||||||
import prisma from './prisma.js';
|
import prisma from './prisma.js';
|
||||||
import EmailSender from './email-sender.js';
|
import EmailSender from './email-sender.js';
|
||||||
|
import { emailOTP } from 'better-auth/plugins';
|
||||||
|
|
||||||
export const auth = betterAuth({
|
export const auth = betterAuth({
|
||||||
appName: process.env.APP_NAME ?? 'app',
|
appName: process.env.APP_NAME ?? 'app',
|
||||||
basePath: '/api/auth',
|
basePath: '/api/auth',
|
||||||
plugins: [
|
plugins: [
|
||||||
// authTransformResponse()
|
// authTransformResponse()
|
||||||
|
emailOTP({
|
||||||
|
async sendVerificationOTP({ email, otp, type }) {
|
||||||
|
if (type === 'sign-in') {
|
||||||
|
// Send the OTP for sign in
|
||||||
|
console.log({ email, otp, type });
|
||||||
|
|
||||||
|
void EmailSender.getTransporter().sendMail({
|
||||||
|
to: email,
|
||||||
|
subject: `Your OTP code is: ${otp}`,
|
||||||
|
text: `Your OTP code is: ${otp}`,
|
||||||
|
});
|
||||||
|
} else if (type === 'email-verification') {
|
||||||
|
// Send the OTP for email verification
|
||||||
|
console.log({ email, otp, type });
|
||||||
|
} else {
|
||||||
|
// Send the OTP for password reset
|
||||||
|
console.log({ email, otp, type });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}),
|
||||||
],
|
],
|
||||||
database: prismaAdapter(prisma, {
|
database: prismaAdapter(prisma, {
|
||||||
provider: 'postgresql',
|
provider: 'postgresql',
|
||||||
@@ -24,7 +45,7 @@ export const auth = betterAuth({
|
|||||||
emailAndPassword: {
|
emailAndPassword: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
autoSignIn: false,
|
autoSignIn: false,
|
||||||
requireEmailVerification: false,
|
requireEmailVerification: true,
|
||||||
onExistingUserSignUp: async ({ user }, request) => {
|
onExistingUserSignUp: async ({ user }, request) => {
|
||||||
console.log('onExistingUserSignUp', { user });
|
console.log('onExistingUserSignUp', { user });
|
||||||
|
|
||||||
|
|||||||
@@ -16,12 +16,7 @@ async function bootstrap() {
|
|||||||
logger: new CustomLogger(),
|
logger: new CustomLogger(),
|
||||||
});
|
});
|
||||||
|
|
||||||
// app.useGlobalPipes(new StandardSchemaValidationPipe());
|
|
||||||
|
|
||||||
app.setGlobalPrefix('api');
|
app.setGlobalPrefix('api');
|
||||||
|
|
||||||
// Глобальный body-parser отключён (better-auth сам парсит своё тело),
|
|
||||||
// поэтому для GraphQL включаем JSON-парсинг точечно на его пути.
|
|
||||||
app.use('/graphql', json());
|
app.use('/graphql', json());
|
||||||
app.useGlobalPipes(new ValidationPipe({ whitelist: true, transform: true }));
|
app.useGlobalPipes(new ValidationPipe({ whitelist: true, transform: true }));
|
||||||
app.useGlobalInterceptors(new TransformResponseInterceptor());
|
app.useGlobalInterceptors(new TransformResponseInterceptor());
|
||||||
|
|||||||
Reference in new issue
Block a user