Add junk-drawer history by IP

This commit is contained in:
2024-10-30 10:21:38 -06:00
parent c854a1540a
commit 3df355f045
8 changed files with 79 additions and 7 deletions

View File

@@ -85,7 +85,6 @@ import { ContactModule } from './contact/contact.module';
app: 'us.dev api', app: 'us.dev api',
}, },
}), }),
CacheModule.register({ isGlobal: true }),
ParkioModule, ParkioModule,
IswordModule, IswordModule,
AuthModule, AuthModule,

View File

@@ -6,6 +6,7 @@ import {
Post, Post,
Redirect, Redirect,
Render, Render,
Req,
Res, Res,
UploadedFile, UploadedFile,
UploadedFiles, UploadedFiles,
@@ -16,7 +17,7 @@ import { ApiConsumes, ApiTags } from '@nestjs/swagger';
import { FilesInterceptor } from '@nestjs/platform-express'; import { FilesInterceptor } from '@nestjs/platform-express';
import { generateUniqueSlug } from 'src/utils/slug'; import { generateUniqueSlug } from 'src/utils/slug';
import { JunkDrawerMetadata } from './types'; import { JunkDrawerMetadata } from './types';
import { Response } from 'express'; import { Request, Response } from 'express';
@Controller('junk-drawer') @Controller('junk-drawer')
@ApiTags('junk-drawer') @ApiTags('junk-drawer')
@@ -25,8 +26,12 @@ export class JunkDrawerController {
@Get('') @Get('')
@Render('junk-drawer/upload') @Render('junk-drawer/upload')
generateUploadForm() { async generateUploadForm(@Req() req: Request) {
return {}; let items: string[] = [];
if (req.ip) {
items = await this.junkDrawerService.getItemsForIp(req.ip);
}
return { items };
} }
@Get(':slug.json') @Get(':slug.json')
@@ -80,8 +85,10 @@ export class JunkDrawerController {
@UseInterceptors(FilesInterceptor('files')) @UseInterceptors(FilesInterceptor('files'))
async handleFileUpload( async handleFileUpload(
@UploadedFiles() files: Express.Multer.File[], @UploadedFiles() files: Express.Multer.File[],
@Req() request: Request,
@Body('description') description: string, @Body('description') description: string,
@Body('private-ish') privateIsh: boolean, @Body('private-ish') privateIsh: boolean,
@Body('remember') remember: boolean,
): Promise<any> { ): Promise<any> {
const uniqueSlug = generateUniqueSlug({ const uniqueSlug = generateUniqueSlug({
random: privateIsh, random: privateIsh,
@@ -106,6 +113,9 @@ export class JunkDrawerController {
); );
} }
await this.junkDrawerService.storeJunkDrawerMetadata(metadata); await this.junkDrawerService.storeJunkDrawerMetadata(metadata);
if (remember && request.ip && !privateIsh) {
await this.junkDrawerService.recordItemForIp(request.ip, uniqueSlug);
}
return { url: `/junk-drawer/${uniqueSlug}` }; return { url: `/junk-drawer/${uniqueSlug}` };
} }
} }

View File

@@ -1,4 +1,4 @@
import { Injectable } from '@nestjs/common'; import { Injectable, Logger } from '@nestjs/common';
import { ConfigService } from '@nestjs/config'; import { ConfigService } from '@nestjs/config';
import { MinioService } from 'src/minio/minio.service'; import { MinioService } from 'src/minio/minio.service';
import { JunkDrawerMetadata } from './types'; import { JunkDrawerMetadata } from './types';
@@ -6,6 +6,7 @@ import { generateUniqueSlug } from 'src/utils/slug';
@Injectable() @Injectable()
export class JunkDrawerService { export class JunkDrawerService {
private readonly logger: Logger = new Logger(JunkDrawerService.name);
constructor( constructor(
private readonly minioService: MinioService, private readonly minioService: MinioService,
private readonly configService: ConfigService, private readonly configService: ConfigService,
@@ -92,4 +93,43 @@ export class JunkDrawerService {
this.pathForFile(`${slug}/${filename}`), this.pathForFile(`${slug}/${filename}`),
); );
} }
public async recordItemForIp(ip: string, itemId: string) {
let ipList = Buffer.from(JSON.stringify({}));
try {
ipList = await this.minioService.getBuffer(
this.junkDrawerBucketName(),
this.pathForFile(`ip-list.json`),
);
} catch (error) {
this.logger.warn('IP list is empty');
}
let ipListObject = ipList ? JSON.parse(ipList.toString()) : {};
if (!ipListObject[ip]) {
ipListObject[ip] = {
lastUpload: new Date(),
itemIds: [],
};
}
ipListObject[ip].itemIds.push(itemId);
await this.minioService.uploadBuffer(
this.junkDrawerBucketName(),
this.pathForFile(`ip-list.json`),
Buffer.from(JSON.stringify(ipListObject)),
);
}
public async getItemsForIp(ip: string): Promise<string[]> {
let ipList = Buffer.from(JSON.stringify({}));
try {
ipList = await this.minioService.getBuffer(
this.junkDrawerBucketName(),
this.pathForFile(`ip-list.json`),
);
} catch (error) {
this.logger.warn('IP list is empty');
}
let ipListObject = ipList ? JSON.parse(ipList.toString()) : {};
return ipListObject[ip]?.itemIds || [];
}
} }

View File

@@ -12,3 +12,9 @@ export interface JunkDrawerItem {
lastModified: Date; lastModified: Date;
mimetype: string; mimetype: string;
} }
export interface JunkDrawerIpList {
ip: string;
lastUpload: Date;
itemIds: string[];
}

View File

@@ -1,7 +1,8 @@
import { Module } from '@nestjs/common'; import { Module } from '@nestjs/common';
import { MinioService } from './minio.service'; import { MinioService } from './minio.service';
import { CacheModule } from '@nestjs/cache-manager';
@Module({ @Module({
providers: [MinioService] providers: [MinioService],
}) })
export class MinioModule {} export class MinioModule {}

View File

@@ -2,9 +2,10 @@ import { Module } from '@nestjs/common';
import { ParkioService } from './parkio.service'; import { ParkioService } from './parkio.service';
import { ParkioController } from './parkio.controller'; import { ParkioController } from './parkio.controller';
import { IswordService } from 'src/isword/isword.service'; import { IswordService } from 'src/isword/isword.service';
import { CacheModule } from '@nestjs/cache-manager';
@Module({ @Module({
providers: [ParkioService, IswordService], providers: [ParkioService, IswordService],
controllers: [ParkioController] controllers: [ParkioController],
}) })
export class ParkioModule {} export class ParkioModule {}

1
src/users/users.json Normal file
View File

@@ -0,0 +1 @@
[]

View File

@@ -26,6 +26,10 @@
>Private-ish</label> >Private-ish</label>
<input type='checkbox' id='private-ish' name='private-ish' /> <input type='checkbox' id='private-ish' name='private-ish' />
</div> </div>
<div>
<label for='remember'>Remember for my IP</label>
<input type='checkbox' id='remember' name='remember' />
</div>
<div class='flex flex-col max-w-96'> <div class='flex flex-col max-w-96'>
<label for='description'>Description:</label> <label for='description'>Description:</label>
<textarea <textarea
@@ -41,5 +45,15 @@
<button class='border-2 rounded-md border-slate-800 p-1'>Submit</button> <button class='border-2 rounded-md border-slate-800 p-1'>Submit</button>
</div> </div>
</form> </form>
<div>
<h2>Your Items</h2>
<div>
{{#each items}}
<div>
<a class="text-blue-500 underline" href='/junk-drawer/{{.}}'>{{.}}</a>
</div>
{{/each}}
</div>
</div>
</body> </body>
</html> </html>