mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2025-11-13 16:22:59 +10:00
fix bugs
This commit is contained in:
@ -99,7 +99,7 @@ const Section: React.FC<Props> = ({
|
|||||||
|
|
||||||
<Button variant="outlined" startIcon={<Add />} onClick={handleAdd}>
|
<Button variant="outlined" startIcon={<Add />} onClick={handleAdd}>
|
||||||
{t<string>('builder.common.actions.add', {
|
{t<string>('builder.common.actions.add', {
|
||||||
token: t<string>(`builder.leftSidebar.${path}.heading`, heading),
|
token: t<string>(`builder.leftSidebar.${path}.heading`, { defaultValue: heading }),
|
||||||
})}
|
})}
|
||||||
</Button>
|
</Button>
|
||||||
</footer>
|
</footer>
|
||||||
|
|||||||
@ -62,7 +62,7 @@ const Heading: React.FC<Props> = ({
|
|||||||
{editMode ? (
|
{editMode ? (
|
||||||
<TextField size="small" value={heading} className="w-3/4" onChange={handleChange} />
|
<TextField size="small" value={heading} className="w-3/4" onChange={handleChange} />
|
||||||
) : (
|
) : (
|
||||||
<h1>{t<string>(`builder.leftSidebar.${path}.heading`, heading)}</h1>
|
<h1>{t<string>(`builder.leftSidebar.${path}.heading`, { defaultValue: heading })}</h1>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@ -89,7 +89,7 @@ const UserProfileModal = () => {
|
|||||||
render={({ field, fieldState }) => (
|
render={({ field, fieldState }) => (
|
||||||
<TextField
|
<TextField
|
||||||
autoFocus
|
autoFocus
|
||||||
label={t('modals.auth.profile.form.name.label')}
|
label={t<string>('modals.auth.profile.form.name.label')}
|
||||||
error={!!fieldState.error}
|
error={!!fieldState.error}
|
||||||
helperText={fieldState.error?.message}
|
helperText={fieldState.error?.message}
|
||||||
{...field}
|
{...field}
|
||||||
@ -114,16 +114,16 @@ const UserProfileModal = () => {
|
|||||||
render={({ field, fieldState }) => (
|
render={({ field, fieldState }) => (
|
||||||
<TextField
|
<TextField
|
||||||
disabled
|
disabled
|
||||||
label={t('modals.auth.profile.form.email.label')}
|
label={t<string>('modals.auth.profile.form.email.label')}
|
||||||
error={!!fieldState.error}
|
error={!!fieldState.error}
|
||||||
helperText={t('modals.auth.profile.form.email.help-text')}
|
helperText={t<string>('modals.auth.profile.form.email.help-text')}
|
||||||
{...field}
|
{...field}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<Button onClick={handleUpdate}>{t('modals.auth.profile.actions.save')}</Button>
|
<Button onClick={handleUpdate}>{t<string>('modals.auth.profile.actions.save')}</Button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
@ -133,10 +133,12 @@ const UserProfileModal = () => {
|
|||||||
|
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<CrisisAlert />
|
<CrisisAlert />
|
||||||
<h5 className="font-medium">{t('modals.auth.profile.delete-account.heading')}</h5>
|
<h5 className="font-medium">{t<string>('modals.auth.profile.delete-account.heading')}</h5>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p className="text-xs opacity-75">{t('modals.auth.profile.delete-account.body', { keyword: 'delete' })}</p>
|
<p className="text-xs opacity-75">
|
||||||
|
{t<string>('modals.auth.profile.delete-account.body', { keyword: 'delete' })}
|
||||||
|
</p>
|
||||||
|
|
||||||
<div className="flex max-w-xs flex-col gap-4">
|
<div className="flex max-w-xs flex-col gap-4">
|
||||||
<TextField
|
<TextField
|
||||||
@ -147,7 +149,7 @@ const UserProfileModal = () => {
|
|||||||
|
|
||||||
<div>
|
<div>
|
||||||
<Button variant="contained" color="error" disabled={!isDeleteTextValid} onClick={handleDelete}>
|
<Button variant="contained" color="error" disabled={!isDeleteTextValid} onClick={handleDelete}>
|
||||||
{t('modals.auth.profile.delete-account.actions.delete')}
|
{t<string>('modals.auth.profile.delete-account.actions.delete')}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -57,12 +57,17 @@ const WorkModal: React.FC = () => {
|
|||||||
const isEditMode = useMemo(() => !!item, [item]);
|
const isEditMode = useMemo(() => !!item, [item]);
|
||||||
|
|
||||||
const addText = useMemo(
|
const addText = useMemo(
|
||||||
() => t<string>('builder.common.actions.add', { token: t<string>(`builder.leftSidebar.${path}.heading`, heading) }),
|
() =>
|
||||||
|
t<string>('builder.common.actions.add', {
|
||||||
|
token: t<string>(`builder.leftSidebar.${path}.heading`, { defaultValue: heading }),
|
||||||
|
}),
|
||||||
[t, heading]
|
[t, heading]
|
||||||
);
|
);
|
||||||
const editText = useMemo(
|
const editText = useMemo(
|
||||||
() =>
|
() =>
|
||||||
t<string>('builder.common.actions.edit', { token: t<string>(`builder.leftSidebar.${path}.heading`, heading) }),
|
t<string>('builder.common.actions.edit', {
|
||||||
|
token: t<string>(`builder.leftSidebar.${path}.heading`, { defaultValue: heading }),
|
||||||
|
}),
|
||||||
[t, heading]
|
[t, heading]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -48,6 +48,7 @@ const i18nConfig = {
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
nsSeparator: '.',
|
nsSeparator: '.',
|
||||||
|
returnNull: false,
|
||||||
localePath: path.resolve('./public/locales'),
|
localePath: path.resolve('./public/locales'),
|
||||||
ns: ['common', 'modals', 'landing', 'dashboard', 'builder'],
|
ns: ['common', 'modals', 'landing', 'dashboard', 'builder'],
|
||||||
};
|
};
|
||||||
|
|||||||
5
client/types/next-env.d.ts
vendored
5
client/types/next-env.d.ts
vendored
@ -1,5 +0,0 @@
|
|||||||
/// <reference types="next" />
|
|
||||||
/// <reference types="next/image-types/global" />
|
|
||||||
|
|
||||||
// NOTE: This file should not be edited
|
|
||||||
// see https://nextjs.org/docs/basic-features/typescript for more information.
|
|
||||||
@ -19,7 +19,7 @@ import { LocalStrategy } from './strategy/local.strategy';
|
|||||||
imports: [ConfigModule],
|
imports: [ConfigModule],
|
||||||
inject: [ConfigService],
|
inject: [ConfigService],
|
||||||
useFactory: async (configService: ConfigService) => ({
|
useFactory: async (configService: ConfigService) => ({
|
||||||
secret: configService.get<string>('auth.jwtSecret'),
|
secret: configService.get('auth.jwtSecret'),
|
||||||
signOptions: {
|
signOptions: {
|
||||||
expiresIn: `${configService.get<number>('auth.jwtExpiryTime')}s`,
|
expiresIn: `${configService.get<number>('auth.jwtExpiryTime')}s`,
|
||||||
},
|
},
|
||||||
|
|||||||
@ -106,15 +106,15 @@ export class AuthService {
|
|||||||
|
|
||||||
getUserFromAccessToken(accessToken: string) {
|
getUserFromAccessToken(accessToken: string) {
|
||||||
const payload: User = this.jwtService.verify(accessToken, {
|
const payload: User = this.jwtService.verify(accessToken, {
|
||||||
secret: this.configService.get<string>('auth.jwtSecret'),
|
secret: this.configService.get('auth.jwtSecret'),
|
||||||
});
|
});
|
||||||
|
|
||||||
return this.usersService.findById(payload.id);
|
return this.usersService.findById(payload.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
async authenticateWithGoogle(credential: string) {
|
async authenticateWithGoogle(credential: string) {
|
||||||
const clientID = this.configService.get<string>('google.clientID');
|
const clientID = this.configService.get('google.clientID');
|
||||||
const clientSecret = this.configService.get<string>('google.clientSecret');
|
const clientSecret = this.configService.get('google.clientSecret');
|
||||||
|
|
||||||
const OAuthClient = new OAuth2Client(clientID, clientSecret);
|
const OAuthClient = new OAuth2Client(clientID, clientSecret);
|
||||||
const client = await OAuthClient.verifyIdToken({ idToken: credential });
|
const client = await OAuthClient.verifyIdToken({ idToken: credential });
|
||||||
|
|||||||
@ -11,7 +11,7 @@ export class JwtStrategy extends PassportStrategy(Strategy) {
|
|||||||
constructor(configService: ConfigService, private readonly usersService: UsersService) {
|
constructor(configService: ConfigService, private readonly usersService: UsersService) {
|
||||||
super({
|
super({
|
||||||
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
|
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
|
||||||
secretOrKey: configService.get<string>('auth.jwtSecret'),
|
secretOrKey: configService.get('auth.jwtSecret'),
|
||||||
ignoreExpiration: false,
|
ignoreExpiration: false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,15 +12,15 @@ import { User } from '@/users/entities/user.entity';
|
|||||||
inject: [ConfigService],
|
inject: [ConfigService],
|
||||||
useFactory: async (configService: ConfigService) => ({
|
useFactory: async (configService: ConfigService) => ({
|
||||||
type: 'postgres',
|
type: 'postgres',
|
||||||
host: configService.get<string>('postgres.host'),
|
host: configService.get('postgres.host'),
|
||||||
port: configService.get<number>('postgres.port'),
|
port: configService.get<number>('postgres.port'),
|
||||||
username: configService.get<string>('postgres.username'),
|
username: configService.get('postgres.username'),
|
||||||
password: configService.get<string>('postgres.password'),
|
password: configService.get('postgres.password'),
|
||||||
database: configService.get<string>('postgres.database'),
|
database: configService.get('postgres.database'),
|
||||||
poolSize: 22,
|
poolSize: 22,
|
||||||
synchronize: true,
|
synchronize: true,
|
||||||
entities: [User, Resume],
|
entities: [User, Resume],
|
||||||
ssl: configService.get<string>('postgres.certificate') && {
|
ssl: configService.get('postgres.certificate') && {
|
||||||
ca: Buffer.from(configService.get<string>('postgres.certificate'), 'base64').toString('ascii'),
|
ca: Buffer.from(configService.get<string>('postgres.certificate'), 'base64').toString('ascii'),
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
|||||||
@ -12,7 +12,7 @@ export class FontsService {
|
|||||||
constructor(private configService: ConfigService, private httpService: HttpService) {}
|
constructor(private configService: ConfigService, private httpService: HttpService) {}
|
||||||
|
|
||||||
async getAll(): Promise<Font[]> {
|
async getAll(): Promise<Font[]> {
|
||||||
const apiKey = this.configService.get<string>('google.apiKey');
|
const apiKey = this.configService.get('google.apiKey');
|
||||||
const url = 'https://www.googleapis.com/webfonts/v1/webfonts?key=' + apiKey;
|
const url = 'https://www.googleapis.com/webfonts/v1/webfonts?key=' + apiKey;
|
||||||
|
|
||||||
let data = [];
|
let data = [];
|
||||||
|
|||||||
@ -12,14 +12,14 @@ export class MailService {
|
|||||||
|
|
||||||
constructor(private configService: ConfigService) {
|
constructor(private configService: ConfigService) {
|
||||||
this.transporter = createTransport({
|
this.transporter = createTransport({
|
||||||
host: this.configService.get<string>('mail.host'),
|
host: this.configService.get('mail.host'),
|
||||||
port: this.configService.get<number>('mail.port'),
|
port: this.configService.get<number>('mail.port'),
|
||||||
pool: true,
|
pool: true,
|
||||||
secure: false,
|
secure: false,
|
||||||
tls: { ciphers: 'SSLv3' },
|
tls: { ciphers: 'SSLv3' },
|
||||||
auth: {
|
auth: {
|
||||||
user: this.configService.get<string>('mail.username'),
|
user: this.configService.get('mail.username'),
|
||||||
pass: this.configService.get<string>('mail.password'),
|
pass: this.configService.get('mail.password'),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -35,13 +35,13 @@ export class MailService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async sendForgotPasswordEmail(user: User, resetToken: string): Promise<void> {
|
async sendForgotPasswordEmail(user: User, resetToken: string): Promise<void> {
|
||||||
const appUrl = this.configService.get<string>('app.url');
|
const appUrl = this.configService.get('app.url');
|
||||||
const url = `${appUrl}?modal=auth.reset&resetToken=${resetToken}`;
|
const url = `${appUrl}?modal=auth.reset&resetToken=${resetToken}`;
|
||||||
|
|
||||||
const sendMailDto: SendMailDto = {
|
const sendMailDto: SendMailDto = {
|
||||||
from: {
|
from: {
|
||||||
name: this.configService.get<string>('mail.from.name'),
|
name: this.configService.get('mail.from.name'),
|
||||||
email: this.configService.get<string>('mail.from.email'),
|
email: this.configService.get('mail.from.email'),
|
||||||
},
|
},
|
||||||
to: {
|
to: {
|
||||||
name: user.name,
|
name: user.name,
|
||||||
|
|||||||
@ -10,7 +10,7 @@ const bootstrap = async () => {
|
|||||||
const app = await NestFactory.create<NestExpressApplication>(AppModule);
|
const app = await NestFactory.create<NestExpressApplication>(AppModule);
|
||||||
const configService = app.get(ConfigService);
|
const configService = app.get(ConfigService);
|
||||||
|
|
||||||
const appUrl = configService.get<string>('app.url');
|
const appUrl = configService.get('app.url');
|
||||||
|
|
||||||
// Middleware
|
// Middleware
|
||||||
app.enableCors({ origin: [appUrl], credentials: true });
|
app.enableCors({ origin: [appUrl], credentials: true });
|
||||||
|
|||||||
@ -24,7 +24,7 @@ export class PrinterService implements OnModuleInit, OnModuleDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async printAsPdf(username: string, slug: string, lastUpdated: string): Promise<string> {
|
async printAsPdf(username: string, slug: string, lastUpdated: string): Promise<string> {
|
||||||
const serverUrl = this.configService.get<string>('app.serverUrl');
|
const serverUrl = this.configService.get('app.serverUrl');
|
||||||
|
|
||||||
const directory = join(__dirname, '..', 'assets/exports');
|
const directory = join(__dirname, '..', 'assets/exports');
|
||||||
const filename = `RxResume_PDFExport_${username}_${slug}_${lastUpdated}.pdf`;
|
const filename = `RxResume_PDFExport_${username}_${slug}_${lastUpdated}.pdf`;
|
||||||
@ -47,8 +47,8 @@ export class PrinterService implements OnModuleInit, OnModuleDestroy {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
const url = this.configService.get<string>('app.url');
|
const url = this.configService.get('app.url');
|
||||||
const secretKey = this.configService.get<string>('app.secretKey');
|
const secretKey = this.configService.get('app.secretKey');
|
||||||
const pdfDeletionTime = this.configService.get<number>('cache.pdfDeletionTime');
|
const pdfDeletionTime = this.configService.get<number>('cache.pdfDeletionTime');
|
||||||
|
|
||||||
const page = await this.browser.newPage();
|
const page = await this.browser.newPage();
|
||||||
|
|||||||
@ -34,15 +34,15 @@ export class ResumeService {
|
|||||||
private configService: ConfigService,
|
private configService: ConfigService,
|
||||||
private usersService: UsersService
|
private usersService: UsersService
|
||||||
) {
|
) {
|
||||||
this.s3Enabled = !isEmpty(configService.get<string>('storage.bucket'));
|
this.s3Enabled = !isEmpty(configService.get('storage.bucket'));
|
||||||
|
|
||||||
if (this.s3Enabled) {
|
if (this.s3Enabled) {
|
||||||
this.s3Client = new S3({
|
this.s3Client = new S3({
|
||||||
endpoint: configService.get<string>('storage.endpoint'),
|
endpoint: configService.get('storage.endpoint'),
|
||||||
region: configService.get<string>('storage.region'),
|
region: configService.get('storage.region'),
|
||||||
credentials: {
|
credentials: {
|
||||||
accessKeyId: configService.get<string>('storage.accessKey'),
|
accessKeyId: configService.get('storage.accessKey'),
|
||||||
secretAccessKey: configService.get<string>('storage.secretKey'),
|
secretAccessKey: configService.get('storage.secretKey'),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -141,7 +141,7 @@ export class ResumeService {
|
|||||||
|
|
||||||
const isPrivate = !resume.public;
|
const isPrivate = !resume.public;
|
||||||
const isOwner = resume.user.id === userId;
|
const isOwner = resume.user.id === userId;
|
||||||
const isInternal = secretKey === this.configService.get<string>('app.secretKey');
|
const isInternal = secretKey === this.configService.get('app.secretKey');
|
||||||
|
|
||||||
if (!isInternal && isPrivate && !isOwner) {
|
if (!isInternal && isPrivate && !isOwner) {
|
||||||
throw new HttpException('The resume you are looking does not exist, or maybe never did?', HttpStatus.NOT_FOUND);
|
throw new HttpException('The resume you are looking does not exist, or maybe never did?', HttpStatus.NOT_FOUND);
|
||||||
@ -159,7 +159,7 @@ export class ResumeService {
|
|||||||
|
|
||||||
const isPrivate = !resume.public;
|
const isPrivate = !resume.public;
|
||||||
const isOwner = resume.user.id === userId;
|
const isOwner = resume.user.id === userId;
|
||||||
const isInternal = secretKey === this.configService.get<string>('app.secretKey');
|
const isInternal = secretKey === this.configService.get('app.secretKey');
|
||||||
|
|
||||||
if (!isInternal && isPrivate && !isOwner) {
|
if (!isInternal && isPrivate && !isOwner) {
|
||||||
throw new HttpException('The resume you are looking does not exist, or maybe never did?', HttpStatus.NOT_FOUND);
|
throw new HttpException('The resume you are looking does not exist, or maybe never did?', HttpStatus.NOT_FOUND);
|
||||||
@ -247,7 +247,7 @@ export class ResumeService {
|
|||||||
let updatedResume = null;
|
let updatedResume = null;
|
||||||
|
|
||||||
if (this.s3Enabled) {
|
if (this.s3Enabled) {
|
||||||
const urlPrefix = this.configService.get<string>('storage.urlPrefix');
|
const urlPrefix = this.configService.get('storage.urlPrefix');
|
||||||
const key = `uploads/${userId}/${id}/${filename}`;
|
const key = `uploads/${userId}/${id}/${filename}`;
|
||||||
const publicUrl = urlPrefix + key;
|
const publicUrl = urlPrefix + key;
|
||||||
await this.s3Client.send(
|
await this.s3Client.send(
|
||||||
@ -255,13 +255,13 @@ export class ResumeService {
|
|||||||
Key: key,
|
Key: key,
|
||||||
Body: file.buffer,
|
Body: file.buffer,
|
||||||
ACL: 'public-read',
|
ACL: 'public-read',
|
||||||
Bucket: this.configService.get<string>('storage.bucket'),
|
Bucket: this.configService.get('storage.bucket'),
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
updatedResume = set(resume, 'basics.photo.url', publicUrl);
|
updatedResume = set(resume, 'basics.photo.url', publicUrl);
|
||||||
} else {
|
} else {
|
||||||
const path = `${__dirname}/../assets/uploads/${userId}/${id}/`;
|
const path = `${__dirname}/../assets/uploads/${userId}/${id}/`;
|
||||||
const serverUrl = this.configService.get<string>('app.serverUrl');
|
const serverUrl = this.configService.get('app.serverUrl');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await fs.mkdir(path, { recursive: true });
|
await fs.mkdir(path, { recursive: true });
|
||||||
@ -286,16 +286,16 @@ export class ResumeService {
|
|||||||
if (!publicUrl || publicUrl === '') return;
|
if (!publicUrl || publicUrl === '') return;
|
||||||
|
|
||||||
if (this.s3Enabled) {
|
if (this.s3Enabled) {
|
||||||
const urlPrefix = this.configService.get<string>('storage.urlPrefix');
|
const urlPrefix = this.configService.get('storage.urlPrefix');
|
||||||
const key = publicUrl.replace(urlPrefix, '');
|
const key = publicUrl.replace(urlPrefix, '');
|
||||||
await this.s3Client.send(
|
await this.s3Client.send(
|
||||||
new DeleteObjectCommand({
|
new DeleteObjectCommand({
|
||||||
Key: key,
|
Key: key,
|
||||||
Bucket: this.configService.get<string>('storage.bucket'),
|
Bucket: this.configService.get('storage.bucket'),
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
const serverUrl = this.configService.get<string>('app.serverUrl');
|
const serverUrl = this.configService.get('app.serverUrl');
|
||||||
const filePath = __dirname + '/..' + resume.basics.photo.url.replace(serverUrl, '');
|
const filePath = __dirname + '/..' + resume.basics.photo.url.replace(serverUrl, '');
|
||||||
|
|
||||||
const isValidFile = (await fs.stat(filePath)).isFile();
|
const isValidFile = (await fs.stat(filePath)).isFile();
|
||||||
|
|||||||
Reference in New Issue
Block a user