feat: nestjs config package added
This commit is contained in:
@@ -28,6 +28,7 @@
|
|||||||
"@nestjs-modules/mailer": "^1.9.1",
|
"@nestjs-modules/mailer": "^1.9.1",
|
||||||
"@nestjs/apollo": "^12.0.9",
|
"@nestjs/apollo": "^12.0.9",
|
||||||
"@nestjs/common": "^10.2.6",
|
"@nestjs/common": "^10.2.6",
|
||||||
|
"@nestjs/config": "^3.1.1",
|
||||||
"@nestjs/core": "^10.2.6",
|
"@nestjs/core": "^10.2.6",
|
||||||
"@nestjs/graphql": "^12.0.9",
|
"@nestjs/graphql": "^12.0.9",
|
||||||
"@nestjs/jwt": "^10.1.1",
|
"@nestjs/jwt": "^10.1.1",
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import { TeamEnvironmentsService } from '../team-environments/team-environments.
|
|||||||
import { TeamInvitationService } from '../team-invitation/team-invitation.service';
|
import { TeamInvitationService } from '../team-invitation/team-invitation.service';
|
||||||
import { TeamMemberRole } from '../team/team.model';
|
import { TeamMemberRole } from '../team/team.model';
|
||||||
import { ShortcodeService } from 'src/shortcode/shortcode.service';
|
import { ShortcodeService } from 'src/shortcode/shortcode.service';
|
||||||
|
import { ConfigService } from '@nestjs/config';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AdminService {
|
export class AdminService {
|
||||||
@@ -39,6 +40,7 @@ export class AdminService {
|
|||||||
private readonly prisma: PrismaService,
|
private readonly prisma: PrismaService,
|
||||||
private readonly mailerService: MailerService,
|
private readonly mailerService: MailerService,
|
||||||
private readonly shortcodeService: ShortcodeService,
|
private readonly shortcodeService: ShortcodeService,
|
||||||
|
private readonly configService: ConfigService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -79,7 +81,7 @@ export class AdminService {
|
|||||||
template: 'user-invitation',
|
template: 'user-invitation',
|
||||||
variables: {
|
variables: {
|
||||||
inviteeEmail: inviteeEmail,
|
inviteeEmail: inviteeEmail,
|
||||||
magicLink: `${process.env.VITE_BASE_URL}`,
|
magicLink: `${this.configService.get('VITE_BASE_URL')}`,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|||||||
@@ -20,49 +20,62 @@ import { ShortcodeModule } from './shortcode/shortcode.module';
|
|||||||
import { COOKIES_NOT_FOUND } from './errors';
|
import { COOKIES_NOT_FOUND } from './errors';
|
||||||
import { ThrottlerModule } from '@nestjs/throttler';
|
import { ThrottlerModule } from '@nestjs/throttler';
|
||||||
import { AppController } from './app.controller';
|
import { AppController } from './app.controller';
|
||||||
|
import { ConfigModule, ConfigService } from '@nestjs/config';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
GraphQLModule.forRoot<ApolloDriverConfig>({
|
ConfigModule.forRoot({
|
||||||
buildSchemaOptions: {
|
isGlobal: true,
|
||||||
numberScalarMode: 'integer',
|
|
||||||
},
|
|
||||||
playground: process.env.PRODUCTION !== 'true',
|
|
||||||
autoSchemaFile: true,
|
|
||||||
installSubscriptionHandlers: true,
|
|
||||||
subscriptions: {
|
|
||||||
'subscriptions-transport-ws': {
|
|
||||||
path: '/graphql',
|
|
||||||
onConnect: (_, websocket) => {
|
|
||||||
try {
|
|
||||||
const cookies = subscriptionContextCookieParser(
|
|
||||||
websocket.upgradeReq.headers.cookie,
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
|
||||||
headers: { ...websocket?.upgradeReq?.headers, cookies },
|
|
||||||
};
|
|
||||||
} catch (error) {
|
|
||||||
throw new HttpException(COOKIES_NOT_FOUND, 400, {
|
|
||||||
cause: new Error(COOKIES_NOT_FOUND),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
context: ({ req, res, connection }) => ({
|
|
||||||
req,
|
|
||||||
res,
|
|
||||||
connection,
|
|
||||||
}),
|
|
||||||
driver: ApolloDriver,
|
|
||||||
}),
|
}),
|
||||||
ThrottlerModule.forRoot([
|
GraphQLModule.forRootAsync<ApolloDriverConfig>({
|
||||||
{
|
driver: ApolloDriver,
|
||||||
ttl: +process.env.RATE_LIMIT_TTL,
|
imports: [ConfigModule],
|
||||||
limit: +process.env.RATE_LIMIT_MAX,
|
inject: [ConfigService],
|
||||||
|
useFactory: async (configService: ConfigService) => {
|
||||||
|
return {
|
||||||
|
buildSchemaOptions: {
|
||||||
|
numberScalarMode: 'integer',
|
||||||
|
},
|
||||||
|
playground: configService.get('PRODUCTION') !== 'true',
|
||||||
|
autoSchemaFile: true,
|
||||||
|
installSubscriptionHandlers: true,
|
||||||
|
subscriptions: {
|
||||||
|
'subscriptions-transport-ws': {
|
||||||
|
path: '/graphql',
|
||||||
|
onConnect: (_, websocket) => {
|
||||||
|
try {
|
||||||
|
const cookies = subscriptionContextCookieParser(
|
||||||
|
websocket.upgradeReq.headers.cookie,
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
headers: { ...websocket?.upgradeReq?.headers, cookies },
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
throw new HttpException(COOKIES_NOT_FOUND, 400, {
|
||||||
|
cause: new Error(COOKIES_NOT_FOUND),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
context: ({ req, res, connection }) => ({
|
||||||
|
req,
|
||||||
|
res,
|
||||||
|
connection,
|
||||||
|
}),
|
||||||
|
};
|
||||||
},
|
},
|
||||||
]),
|
}),
|
||||||
|
ThrottlerModule.forRootAsync({
|
||||||
|
imports: [ConfigModule],
|
||||||
|
inject: [ConfigService],
|
||||||
|
useFactory: async (configService: ConfigService) => [
|
||||||
|
{
|
||||||
|
ttl: +configService.get('RATE_LIMIT_TTL'),
|
||||||
|
limit: +configService.get('RATE_LIMIT_MAX'),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
UserModule,
|
UserModule,
|
||||||
AuthModule,
|
AuthModule,
|
||||||
AdminModule,
|
AdminModule,
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import { GoogleStrategy } from './strategies/google.strategy';
|
|||||||
import { GithubStrategy } from './strategies/github.strategy';
|
import { GithubStrategy } from './strategies/github.strategy';
|
||||||
import { MicrosoftStrategy } from './strategies/microsoft.strategy';
|
import { MicrosoftStrategy } from './strategies/microsoft.strategy';
|
||||||
import { AuthProvider, authProviderCheck } from './helper';
|
import { AuthProvider, authProviderCheck } from './helper';
|
||||||
|
import { ConfigModule, ConfigService } from '@nestjs/config';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
@@ -19,8 +20,12 @@ import { AuthProvider, authProviderCheck } from './helper';
|
|||||||
UserModule,
|
UserModule,
|
||||||
MailerModule,
|
MailerModule,
|
||||||
PassportModule,
|
PassportModule,
|
||||||
JwtModule.register({
|
JwtModule.registerAsync({
|
||||||
secret: process.env.JWT_SECRET,
|
imports: [ConfigModule],
|
||||||
|
inject: [ConfigService],
|
||||||
|
useFactory: async (configService: ConfigService) => ({
|
||||||
|
secret: configService.get('JWT_SECRET'),
|
||||||
|
}),
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import { AuthError } from 'src/types/AuthError';
|
|||||||
import { AuthUser, IsAdmin } from 'src/types/AuthUser';
|
import { AuthUser, IsAdmin } from 'src/types/AuthUser';
|
||||||
import { VerificationToken } from '@prisma/client';
|
import { VerificationToken } from '@prisma/client';
|
||||||
import { Origin } from './helper';
|
import { Origin } from './helper';
|
||||||
|
import { ConfigService } from '@nestjs/config';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AuthService {
|
export class AuthService {
|
||||||
@@ -36,6 +37,7 @@ export class AuthService {
|
|||||||
private prismaService: PrismaService,
|
private prismaService: PrismaService,
|
||||||
private jwtService: JwtService,
|
private jwtService: JwtService,
|
||||||
private readonly mailerService: MailerService,
|
private readonly mailerService: MailerService,
|
||||||
|
private readonly configService: ConfigService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -46,10 +48,12 @@ export class AuthService {
|
|||||||
*/
|
*/
|
||||||
private async generateMagicLinkTokens(user: AuthUser) {
|
private async generateMagicLinkTokens(user: AuthUser) {
|
||||||
const salt = await bcrypt.genSalt(
|
const salt = await bcrypt.genSalt(
|
||||||
parseInt(process.env.TOKEN_SALT_COMPLEXITY),
|
parseInt(this.configService.get('TOKEN_SALT_COMPLEXITY')),
|
||||||
);
|
);
|
||||||
const expiresOn = DateTime.now()
|
const expiresOn = DateTime.now()
|
||||||
.plus({ hours: parseInt(process.env.MAGIC_LINK_TOKEN_VALIDITY) })
|
.plus({
|
||||||
|
hours: parseInt(this.configService.get('MAGIC_LINK_TOKEN_VALIDITY')),
|
||||||
|
})
|
||||||
.toISO()
|
.toISO()
|
||||||
.toString();
|
.toString();
|
||||||
|
|
||||||
@@ -95,13 +99,13 @@ export class AuthService {
|
|||||||
*/
|
*/
|
||||||
private async generateRefreshToken(userUid: string) {
|
private async generateRefreshToken(userUid: string) {
|
||||||
const refreshTokenPayload: RefreshTokenPayload = {
|
const refreshTokenPayload: RefreshTokenPayload = {
|
||||||
iss: process.env.VITE_BASE_URL,
|
iss: this.configService.get('VITE_BASE_URL'),
|
||||||
sub: userUid,
|
sub: userUid,
|
||||||
aud: [process.env.VITE_BASE_URL],
|
aud: [this.configService.get('VITE_BASE_URL')],
|
||||||
};
|
};
|
||||||
|
|
||||||
const refreshToken = await this.jwtService.sign(refreshTokenPayload, {
|
const refreshToken = await this.jwtService.sign(refreshTokenPayload, {
|
||||||
expiresIn: process.env.REFRESH_TOKEN_VALIDITY, //7 Days
|
expiresIn: this.configService.get('REFRESH_TOKEN_VALIDITY'), //7 Days
|
||||||
});
|
});
|
||||||
|
|
||||||
const refreshTokenHash = await argon2.hash(refreshToken);
|
const refreshTokenHash = await argon2.hash(refreshToken);
|
||||||
@@ -127,9 +131,9 @@ export class AuthService {
|
|||||||
*/
|
*/
|
||||||
async generateAuthTokens(userUid: string) {
|
async generateAuthTokens(userUid: string) {
|
||||||
const accessTokenPayload: AccessTokenPayload = {
|
const accessTokenPayload: AccessTokenPayload = {
|
||||||
iss: process.env.VITE_BASE_URL,
|
iss: this.configService.get('VITE_BASE_URL'),
|
||||||
sub: userUid,
|
sub: userUid,
|
||||||
aud: [process.env.VITE_BASE_URL],
|
aud: [this.configService.get('VITE_BASE_URL')],
|
||||||
};
|
};
|
||||||
|
|
||||||
const refreshToken = await this.generateRefreshToken(userUid);
|
const refreshToken = await this.generateRefreshToken(userUid);
|
||||||
@@ -137,7 +141,7 @@ export class AuthService {
|
|||||||
|
|
||||||
return E.right(<AuthTokens>{
|
return E.right(<AuthTokens>{
|
||||||
access_token: await this.jwtService.sign(accessTokenPayload, {
|
access_token: await this.jwtService.sign(accessTokenPayload, {
|
||||||
expiresIn: process.env.ACCESS_TOKEN_VALIDITY, //1 Day
|
expiresIn: this.configService.get('ACCESS_TOKEN_VALIDITY'), //1 Day
|
||||||
}),
|
}),
|
||||||
refresh_token: refreshToken.right,
|
refresh_token: refreshToken.right,
|
||||||
});
|
});
|
||||||
@@ -218,14 +222,14 @@ export class AuthService {
|
|||||||
let url: string;
|
let url: string;
|
||||||
switch (origin) {
|
switch (origin) {
|
||||||
case Origin.ADMIN:
|
case Origin.ADMIN:
|
||||||
url = process.env.VITE_ADMIN_URL;
|
url = this.configService.get('VITE_ADMIN_URL');
|
||||||
break;
|
break;
|
||||||
case Origin.APP:
|
case Origin.APP:
|
||||||
url = process.env.VITE_BASE_URL;
|
url = this.configService.get('VITE_BASE_URL');
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// if origin is invalid by default set URL to Hoppscotch-App
|
// if origin is invalid by default set URL to Hoppscotch-App
|
||||||
url = process.env.VITE_BASE_URL;
|
url = this.configService.get('VITE_BASE_URL');
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.mailerService.sendEmail(email, {
|
await this.mailerService.sendEmail(email, {
|
||||||
|
|||||||
@@ -5,18 +5,20 @@ import { AuthService } from '../auth.service';
|
|||||||
import { UserService } from 'src/user/user.service';
|
import { UserService } from 'src/user/user.service';
|
||||||
import * as O from 'fp-ts/Option';
|
import * as O from 'fp-ts/Option';
|
||||||
import * as E from 'fp-ts/Either';
|
import * as E from 'fp-ts/Either';
|
||||||
|
import { ConfigService } from '@nestjs/config';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class GithubStrategy extends PassportStrategy(Strategy) {
|
export class GithubStrategy extends PassportStrategy(Strategy) {
|
||||||
constructor(
|
constructor(
|
||||||
private authService: AuthService,
|
private authService: AuthService,
|
||||||
private usersService: UserService,
|
private usersService: UserService,
|
||||||
|
private configService: ConfigService,
|
||||||
) {
|
) {
|
||||||
super({
|
super({
|
||||||
clientID: process.env.GITHUB_CLIENT_ID,
|
clientID: configService.get('GITHUB_CLIENT_ID'),
|
||||||
clientSecret: process.env.GITHUB_CLIENT_SECRET,
|
clientSecret: configService.get('GITHUB_CLIENT_SECRET'),
|
||||||
callbackURL: process.env.GITHUB_CALLBACK_URL,
|
callbackURL: configService.get('GITHUB_CALLBACK_URL'),
|
||||||
scope: [process.env.GITHUB_SCOPE],
|
scope: [configService.get('GITHUB_SCOPE')],
|
||||||
store: true,
|
store: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,18 +5,20 @@ import { UserService } from 'src/user/user.service';
|
|||||||
import * as O from 'fp-ts/Option';
|
import * as O from 'fp-ts/Option';
|
||||||
import { AuthService } from '../auth.service';
|
import { AuthService } from '../auth.service';
|
||||||
import * as E from 'fp-ts/Either';
|
import * as E from 'fp-ts/Either';
|
||||||
|
import { ConfigService } from '@nestjs/config';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class GoogleStrategy extends PassportStrategy(Strategy) {
|
export class GoogleStrategy extends PassportStrategy(Strategy) {
|
||||||
constructor(
|
constructor(
|
||||||
private usersService: UserService,
|
private usersService: UserService,
|
||||||
private authService: AuthService,
|
private authService: AuthService,
|
||||||
|
private configService: ConfigService,
|
||||||
) {
|
) {
|
||||||
super({
|
super({
|
||||||
clientID: process.env.GOOGLE_CLIENT_ID,
|
clientID: configService.get('GOOGLE_CLIENT_ID'),
|
||||||
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
|
clientSecret: configService.get('GOOGLE_CLIENT_SECRET'),
|
||||||
callbackURL: process.env.GOOGLE_CALLBACK_URL,
|
callbackURL: configService.get('GOOGLE_CALLBACK_URL'),
|
||||||
scope: process.env.GOOGLE_SCOPE.split(','),
|
scope: configService.get('GOOGLE_SCOPE').split(','),
|
||||||
passReqToCallback: true,
|
passReqToCallback: true,
|
||||||
store: true,
|
store: true,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -15,10 +15,14 @@ import {
|
|||||||
INVALID_ACCESS_TOKEN,
|
INVALID_ACCESS_TOKEN,
|
||||||
USER_NOT_FOUND,
|
USER_NOT_FOUND,
|
||||||
} from 'src/errors';
|
} from 'src/errors';
|
||||||
|
import { ConfigService } from '@nestjs/config';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class JwtStrategy extends PassportStrategy(Strategy, 'jwt') {
|
export class JwtStrategy extends PassportStrategy(Strategy, 'jwt') {
|
||||||
constructor(private usersService: UserService) {
|
constructor(
|
||||||
|
private usersService: UserService,
|
||||||
|
private configService: ConfigService,
|
||||||
|
) {
|
||||||
super({
|
super({
|
||||||
jwtFromRequest: ExtractJwt.fromExtractors([
|
jwtFromRequest: ExtractJwt.fromExtractors([
|
||||||
(request: Request) => {
|
(request: Request) => {
|
||||||
@@ -29,7 +33,7 @@ export class JwtStrategy extends PassportStrategy(Strategy, 'jwt') {
|
|||||||
return ATCookie;
|
return ATCookie;
|
||||||
},
|
},
|
||||||
]),
|
]),
|
||||||
secretOrKey: process.env.JWT_SECRET,
|
secretOrKey: configService.get('JWT_SECRET'),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,19 +5,21 @@ import { AuthService } from '../auth.service';
|
|||||||
import { UserService } from 'src/user/user.service';
|
import { UserService } from 'src/user/user.service';
|
||||||
import * as O from 'fp-ts/Option';
|
import * as O from 'fp-ts/Option';
|
||||||
import * as E from 'fp-ts/Either';
|
import * as E from 'fp-ts/Either';
|
||||||
|
import { ConfigService } from '@nestjs/config';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class MicrosoftStrategy extends PassportStrategy(Strategy) {
|
export class MicrosoftStrategy extends PassportStrategy(Strategy) {
|
||||||
constructor(
|
constructor(
|
||||||
private authService: AuthService,
|
private authService: AuthService,
|
||||||
private usersService: UserService,
|
private usersService: UserService,
|
||||||
|
private configService: ConfigService,
|
||||||
) {
|
) {
|
||||||
super({
|
super({
|
||||||
clientID: process.env.MICROSOFT_CLIENT_ID,
|
clientID: configService.get('MICROSOFT_CLIENT_ID'),
|
||||||
clientSecret: process.env.MICROSOFT_CLIENT_SECRET,
|
clientSecret: configService.get('MICROSOFT_CLIENT_SECRET'),
|
||||||
callbackURL: process.env.MICROSOFT_CALLBACK_URL,
|
callbackURL: configService.get('MICROSOFT_CALLBACK_URL'),
|
||||||
scope: [process.env.MICROSOFT_SCOPE],
|
scope: [configService.get('MICROSOFT_SCOPE')],
|
||||||
tenant: process.env.MICROSOFT_TENANT,
|
tenant: configService.get('MICROSOFT_TENANT'),
|
||||||
store: true,
|
store: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,10 +14,14 @@ import {
|
|||||||
USER_NOT_FOUND,
|
USER_NOT_FOUND,
|
||||||
} from 'src/errors';
|
} from 'src/errors';
|
||||||
import * as O from 'fp-ts/Option';
|
import * as O from 'fp-ts/Option';
|
||||||
|
import { ConfigService } from '@nestjs/config';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class RTJwtStrategy extends PassportStrategy(Strategy, 'jwt-refresh') {
|
export class RTJwtStrategy extends PassportStrategy(Strategy, 'jwt-refresh') {
|
||||||
constructor(private usersService: UserService) {
|
constructor(
|
||||||
|
private usersService: UserService,
|
||||||
|
private configService: ConfigService,
|
||||||
|
) {
|
||||||
super({
|
super({
|
||||||
jwtFromRequest: ExtractJwt.fromExtractors([
|
jwtFromRequest: ExtractJwt.fromExtractors([
|
||||||
(request: Request) => {
|
(request: Request) => {
|
||||||
@@ -28,7 +32,7 @@ export class RTJwtStrategy extends PassportStrategy(Strategy, 'jwt-refresh') {
|
|||||||
return RTCookie;
|
return RTCookie;
|
||||||
},
|
},
|
||||||
]),
|
]),
|
||||||
secretOrKey: process.env.JWT_SECRET,
|
secretOrKey: configService.get('JWT_SECRET'),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,21 +7,27 @@ import {
|
|||||||
MAILER_FROM_ADDRESS_UNDEFINED,
|
MAILER_FROM_ADDRESS_UNDEFINED,
|
||||||
MAILER_SMTP_URL_UNDEFINED,
|
MAILER_SMTP_URL_UNDEFINED,
|
||||||
} from 'src/errors';
|
} from 'src/errors';
|
||||||
|
import { ConfigModule, ConfigService } from '@nestjs/config';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
NestMailerModule.forRoot({
|
NestMailerModule.forRootAsync({
|
||||||
transport:
|
imports: [ConfigModule],
|
||||||
process.env.MAILER_SMTP_URL ?? throwErr(MAILER_SMTP_URL_UNDEFINED),
|
inject: [ConfigService],
|
||||||
defaults: {
|
useFactory: async (configService: ConfigService) => ({
|
||||||
from:
|
transport:
|
||||||
process.env.MAILER_ADDRESS_FROM ??
|
configService.get('MAILER_SMTP_URL') ??
|
||||||
throwErr(MAILER_FROM_ADDRESS_UNDEFINED),
|
throwErr(MAILER_SMTP_URL_UNDEFINED),
|
||||||
},
|
defaults: {
|
||||||
template: {
|
from:
|
||||||
dir: __dirname + '/templates',
|
configService.get('MAILER_ADDRESS_FROM') ??
|
||||||
adapter: new HandlebarsAdapter(),
|
throwErr(MAILER_FROM_ADDRESS_UNDEFINED),
|
||||||
},
|
},
|
||||||
|
template: {
|
||||||
|
dir: __dirname + '/templates',
|
||||||
|
adapter: new HandlebarsAdapter(),
|
||||||
|
},
|
||||||
|
}),
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
providers: [MailerService],
|
providers: [MailerService],
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import { UserService } from 'src/user/user.service';
|
|||||||
import { PubSubService } from 'src/pubsub/pubsub.service';
|
import { PubSubService } from 'src/pubsub/pubsub.service';
|
||||||
import { validateEmail } from '../utils';
|
import { validateEmail } from '../utils';
|
||||||
import { AuthUser } from 'src/types/AuthUser';
|
import { AuthUser } from 'src/types/AuthUser';
|
||||||
|
import { ConfigService } from '@nestjs/config';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class TeamInvitationService {
|
export class TeamInvitationService {
|
||||||
@@ -28,8 +29,8 @@ export class TeamInvitationService {
|
|||||||
private readonly userService: UserService,
|
private readonly userService: UserService,
|
||||||
private readonly teamService: TeamService,
|
private readonly teamService: TeamService,
|
||||||
private readonly mailerService: MailerService,
|
private readonly mailerService: MailerService,
|
||||||
|
|
||||||
private readonly pubsub: PubSubService,
|
private readonly pubsub: PubSubService,
|
||||||
|
private readonly configService: ConfigService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -150,7 +151,9 @@ export class TeamInvitationService {
|
|||||||
template: 'team-invitation',
|
template: 'team-invitation',
|
||||||
variables: {
|
variables: {
|
||||||
invitee: creator.displayName ?? 'A Hoppscotch User',
|
invitee: creator.displayName ?? 'A Hoppscotch User',
|
||||||
action_url: `${process.env.VITE_BASE_URL}/join-team?id=${dbInvitation.id}`,
|
action_url: `${this.configService.get('VITE_BASE_URL')}/join-team?id=${
|
||||||
|
dbInvitation.id
|
||||||
|
}`,
|
||||||
invite_team_name: team.name,
|
invite_team_name: team.name,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
1135
pnpm-lock.yaml
generated
1135
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user