mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2026-07-12 22:14:54 +10:00
Merge pull request #906 from dvd741-a/main
Add File based Storage toggle for Photos
This commit is contained in:
@@ -2,6 +2,36 @@
|
||||
|
||||
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
||||
|
||||
### [3.6.1](https://github.com/dvd741-a/Reactive-Resume/compare/v3.6.0...v3.6.1) (2022-06-05)
|
||||
|
||||
## [3.6.0](https://github.com/dvd741-a/Reactive-Resume/compare/v3.3.4...v3.6.0) (2022-06-05)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **all:** upgrade to v3.4.0 ([87d381f](https://github.com/dvd741-a/Reactive-Resume/commit/87d381fe8eab9ca4624df5de6e8b9ab18a072b67))
|
||||
* **i18n:** add Hungrarian (Magyar) language ([35fe4e2](https://github.com/dvd741-a/Reactive-Resume/commit/35fe4e27744b6f7325b25db2cf3b626ed8598623))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **i18n:** fix language mismatch in exported pdf ([62fd63e](https://github.com/dvd741-a/Reactive-Resume/commit/62fd63e41fe10fba843a40fb08191f5944f2b2fc))
|
||||
* **typeorm:** update typeorm to latest 0.2.x for secpatch ([5bdb92b](https://github.com/dvd741-a/Reactive-Resume/commit/5bdb92b1cff9e56879f9bbf31801d6554a00a8d5))
|
||||
|
||||
## [3.5.0](https://github.com/dvd741-a/Reactive-Resume/compare/v3.3.4...v3.5.0) (2022-06-05)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **all:** upgrade to v3.4.0 ([87d381f](https://github.com/dvd741-a/Reactive-Resume/commit/87d381fe8eab9ca4624df5de6e8b9ab18a072b67))
|
||||
* **i18n:** add Hungrarian (Magyar) language ([35fe4e2](https://github.com/dvd741-a/Reactive-Resume/commit/35fe4e27744b6f7325b25db2cf3b626ed8598623))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **i18n:** fix language mismatch in exported pdf ([62fd63e](https://github.com/dvd741-a/Reactive-Resume/commit/62fd63e41fe10fba843a40fb08191f5944f2b2fc))
|
||||
* **typeorm:** update typeorm to latest 0.2.x for secpatch ([5bdb92b](https://github.com/dvd741-a/Reactive-Resume/commit/5bdb92b1cff9e56879f9bbf31801d6554a00a8d5))
|
||||
|
||||
### [3.4.5](https://github.com/AmruthPillai/Reactive-Resume/compare/v3.4.4...v3.4.5) (2022-05-24)
|
||||
|
||||
|
||||
|
||||
Generated
+49813
File diff suppressed because it is too large
Load Diff
@@ -34,6 +34,9 @@
|
||||
"start": "env-cmd --silent concurrently --kill-others \"pnpm run start:*\""
|
||||
},
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-s3": "^3.100.0",
|
||||
"@docusaurus/core": "^2.0.0-beta.21",
|
||||
"@docusaurus/preset-classic": "^2.0.0-beta.21",
|
||||
"concurrently": "^7.1.0",
|
||||
"env-cmd": "^10.1.0"
|
||||
},
|
||||
|
||||
Generated
+3420
-212
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -43,6 +43,8 @@ RUN pnpm install -F server --frozen-lockfile --prod
|
||||
|
||||
COPY --from=builder /app/server/dist ./server/dist
|
||||
|
||||
VOLUME /app/server/dist/assets/uploads
|
||||
|
||||
EXPOSE 3100
|
||||
|
||||
ENV PORT 3100
|
||||
|
||||
@@ -7,4 +7,5 @@ export default registerAs('storage', () => ({
|
||||
urlPrefix: process.env.STORAGE_URL_PREFIX,
|
||||
accessKey: process.env.STORAGE_ACCESS_KEY,
|
||||
secretKey: process.env.STORAGE_SECRET_KEY,
|
||||
s3Enabled: process.env.STORAGE_S3_ENABLED,
|
||||
}));
|
||||
|
||||
@@ -35,8 +35,6 @@ export class ResumeController {
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@Get()
|
||||
async findAllByUser(@User('id') userId: number) {
|
||||
console.log('findAllByUser', userId);
|
||||
|
||||
return this.resumeService.findAllByUser(userId);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Resume as ResumeSchema } from '@reactive-resume/schema';
|
||||
import fs from 'fs';
|
||||
import { pick, sample, set } from 'lodash';
|
||||
import { nanoid } from 'nanoid';
|
||||
import { extname } from 'path';
|
||||
@@ -23,20 +24,24 @@ export const SHORT_ID_LENGTH = 8;
|
||||
@Injectable()
|
||||
export class ResumeService {
|
||||
private s3Client: S3Client;
|
||||
private s3Enabled: boolean;
|
||||
|
||||
constructor(
|
||||
@InjectRepository(Resume) private resumeRepository: Repository<Resume>,
|
||||
private configService: ConfigService,
|
||||
private usersService: UsersService
|
||||
) {
|
||||
this.s3Client = new S3({
|
||||
endpoint: configService.get<string>('storage.endpoint'),
|
||||
region: configService.get<string>('storage.region'),
|
||||
credentials: {
|
||||
accessKeyId: configService.get<string>('storage.accessKey'),
|
||||
secretAccessKey: configService.get<string>('storage.secretKey'),
|
||||
},
|
||||
});
|
||||
this.s3Enabled = configService.get<string>('storage.s3Enabled') !== 'false';
|
||||
if (this.s3Enabled) {
|
||||
this.s3Client = new S3({
|
||||
endpoint: configService.get<string>('storage.endpoint'),
|
||||
region: configService.get<string>('storage.region'),
|
||||
credentials: {
|
||||
accessKeyId: configService.get<string>('storage.accessKey'),
|
||||
secretAccessKey: configService.get<string>('storage.secretKey'),
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async create(createResumeDto: CreateResumeDto, userId: number) {
|
||||
@@ -230,40 +235,62 @@ export class ResumeService {
|
||||
async uploadPhoto(id: number, userId: number, file: Express.Multer.File) {
|
||||
const resume = await this.findOne(id, userId);
|
||||
|
||||
const urlPrefix = this.configService.get<string>('storage.urlPrefix');
|
||||
const filename = new Date().getTime() + extname(file.originalname);
|
||||
const key = `uploads/${userId}/${id}/${filename}`;
|
||||
|
||||
await this.s3Client.send(
|
||||
new PutObjectCommand({
|
||||
Bucket: this.configService.get<string>('storage.bucket'),
|
||||
Key: key,
|
||||
Body: file.buffer,
|
||||
ACL: 'public-read',
|
||||
})
|
||||
);
|
||||
|
||||
const publicUrl = urlPrefix + key;
|
||||
|
||||
const updatedResume = set(resume, 'basics.photo.url', publicUrl);
|
||||
let updatedResume = null;
|
||||
if (this.s3Enabled) {
|
||||
const urlPrefix = this.configService.get<string>('storage.urlPrefix');
|
||||
const key = `uploads/${userId}/${id}/${filename}`;
|
||||
const publicUrl = urlPrefix + key;
|
||||
await this.s3Client.send(
|
||||
new PutObjectCommand({
|
||||
Bucket: this.configService.get<string>('storage.bucket'),
|
||||
Key: key,
|
||||
Body: file.buffer,
|
||||
ACL: 'public-read',
|
||||
})
|
||||
);
|
||||
updatedResume = set(resume, 'basics.photo.url', publicUrl);
|
||||
} else {
|
||||
const path = `${__dirname}/../assets/uploads/${userId}/${id}/`;
|
||||
fs.mkdir(path, { recursive: true }, (err) => {
|
||||
if (err) {
|
||||
console.log(err);
|
||||
}
|
||||
fs.writeFile(path + filename, file.buffer, (err) => {
|
||||
if (err) {
|
||||
console.log(err);
|
||||
}
|
||||
});
|
||||
});
|
||||
updatedResume = set(resume, 'basics.photo.url', `/api/assets/uploads/${userId}/${id}/` + filename);
|
||||
}
|
||||
|
||||
return this.resumeRepository.save<Resume>(updatedResume);
|
||||
}
|
||||
|
||||
async deletePhoto(id: number, userId: number) {
|
||||
const resume = await this.findOne(id, userId);
|
||||
|
||||
const urlPrefix = this.configService.get<string>('storage.urlPrefix');
|
||||
const publicUrl = resume.basics.photo.url;
|
||||
const key = publicUrl.replace(urlPrefix, '');
|
||||
|
||||
await this.s3Client.send(
|
||||
new DeleteObjectCommand({
|
||||
Bucket: this.configService.get<string>('storage.bucket'),
|
||||
Key: key,
|
||||
})
|
||||
);
|
||||
if (this.s3Enabled) {
|
||||
const urlPrefix = this.configService.get<string>('storage.urlPrefix');
|
||||
const key = publicUrl.replace(urlPrefix, '');
|
||||
|
||||
await this.s3Client.send(
|
||||
new DeleteObjectCommand({
|
||||
Bucket: this.configService.get<string>('storage.bucket'),
|
||||
Key: key,
|
||||
})
|
||||
);
|
||||
} else {
|
||||
const filePath = __dirname + '/../' + resume.basics.photo.url.replace('/api/', '');
|
||||
if (fs.existsSync(filePath)) {
|
||||
fs.unlink(filePath, (err) => {
|
||||
if (err) {
|
||||
console.log(err);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
const updatedResume = set(resume, 'basics.photo.url', '');
|
||||
|
||||
return this.resumeRepository.save<Resume>(updatedResume);
|
||||
|
||||
Reference in New Issue
Block a user