diff --git a/package-lock.json b/package-lock.json index 1740457..18ecbb2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -33,6 +33,7 @@ "@supabase/supabase-js": "^2.47.10", "@types/express": "^5.0.0", "@types/jest": "^29.5.14", + "@types/leo-profanity": "^1.5.4", "@types/node": "^20.3.1", "@types/supertest": "^6.0.2", "@types/uuid": "^10.0.0", @@ -42,6 +43,7 @@ "eslint-config-prettier": "^9.0.0", "eslint-plugin-prettier": "^5.0.0", "jest": "^29.7.0", + "leo-profanity": "^1.7.0", "prettier": "^3.0.0", "source-map-support": "^0.5.21", "supertest": "^7.0.0", @@ -2415,6 +2417,12 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/leo-profanity": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/leo-profanity/-/leo-profanity-1.5.4.tgz", + "integrity": "sha512-f6PiIeXhT14VM6P06MIuzEG9JpcZ3CgjDbV8Rx5fQPkL1A8Zk3dFQRqFr/x1eQlshRFfBorpuzVnfDC042KY8A==", + "dev": true + }, "node_modules/@types/methods": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/@types/methods/-/methods-1.1.4.tgz", @@ -5203,6 +5211,13 @@ "node": ">= 0.6" } }, + "node_modules/french-badwords-list": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/french-badwords-list/-/french-badwords-list-1.0.7.tgz", + "integrity": "sha512-H1ziKs2PJh2+UXZ9oCGJ/rRQpsI9NBykGf2Sc7WaKaj1OnWFuBXfsvANTdRcfVmOghGQaUmRyZ1hJOPbDpy04Q==", + "dev": true, + "optional": true + }, "node_modules/fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", @@ -6786,6 +6801,16 @@ "node": ">=6" } }, + "node_modules/leo-profanity": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/leo-profanity/-/leo-profanity-1.7.0.tgz", + "integrity": "sha512-88j1R08jrQzOib9Yxk4nxrzMlrHJi3DzFzAmv0L4APQ+ciGEfJ1rftVEvFjoqL0m+0KGFL3csQGRlxXGnYrA7w==", + "dev": true, + "optionalDependencies": { + "french-badwords-list": "^1.0.6", + "russian-bad-words": "^0.5.0" + } + }, "node_modules/leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -8119,6 +8144,16 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/russian-bad-words": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/russian-bad-words/-/russian-bad-words-0.5.0.tgz", + "integrity": "sha512-euNvEYki6iYYpkNbeudW+lEMMYGEmN7EBwVF8ezlbv0bZoQpVYB7W10cCeUIGV7Ed50sJynLQ0c559q5iI0ejQ==", + "dev": true, + "optional": true, + "engines": { + "node": ">=10" + } + }, "node_modules/rxjs": { "version": "7.8.1", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", diff --git a/src/github/github.module.ts b/src/github/github.module.ts index 0661c29..a7109ce 100644 --- a/src/github/github.module.ts +++ b/src/github/github.module.ts @@ -1,5 +1,3 @@ -// src/github/github.module.ts - import { Module } from '@nestjs/common'; import { GitHubService } from './github.service'; import { ConfigModule } from '@nestjs/config'; diff --git a/src/rices/rices.controller.ts b/src/rices/rices.controller.ts index 710602d..d2ef19b 100644 --- a/src/rices/rices.controller.ts +++ b/src/rices/rices.controller.ts @@ -34,7 +34,7 @@ export class RicesController { }) @ApiHeader({ name: 'User-Agent', - description: 'User-Agent in the format ZenBrowser/ ()', + description: 'User-Agent', required: true, }) @Post() @@ -75,7 +75,7 @@ export class RicesController { }) @ApiHeader({ name: 'User-Agent', - description: 'User-Agent in the format ZenBrowser/ ()', + description: 'User-Agent', required: true, }) @Put(':slug') diff --git a/src/rices/rices.service.ts b/src/rices/rices.service.ts index daa7ac5..f647f9f 100644 --- a/src/rices/rices.service.ts +++ b/src/rices/rices.service.ts @@ -10,6 +10,8 @@ import { generateSlug } from './utils/slug.util'; import { GitHubService } from '../github/github.service'; import { SupabaseService } from '../supabase/supabase.service'; +const userAgentRegex = /ZenBrowser\/(\d+\.\d\w?\.\d) \((.+)\)/; + @Injectable() export class RicesService { constructor( @@ -25,9 +27,7 @@ export class RicesService { const userAgent = headers['user-agent']; if (!name || !author || !userAgent) { - throw new BadRequestException( - 'Missing required headers: X-Zen-Rice-Name, X-Zen-Rice-Author, and User-Agent are mandatory.', - ); + throw new BadRequestException('Rice name and author are required!'); } // Validate content @@ -56,7 +56,6 @@ export class RicesService { } // Parse version and OS from User-Agent - const userAgentRegex = /ZenBrowser\/(\d+\.\d+\.\d.\d+) \((.+)\)/; const match = userAgent.match(userAgentRegex); if (!match) { @@ -157,7 +156,7 @@ export class RicesService { ) { try { // Extract fields from headers - const userAgent = headers['user-agent']; + const userAgent = headers['User-Agent']; if (!userAgent) { throw new BadRequestException( @@ -166,7 +165,8 @@ export class RicesService { } // Parse version and OS from User-Agent - const userAgentRegex = /ZenBrowser\/(\d+\.\d+\.\d.\d+) \((.+)\)/; + // It must have the following format: + // example version: 1.0.2-b.1 const match = userAgent.match(userAgentRegex); if (!match) { diff --git a/test/restclient/01_create_rice.http b/test/restclient/01_create_rice.http index f17486f..cd7ce87 100644 --- a/test/restclient/01_create_rice.http +++ b/test/restclient/01_create_rice.http @@ -4,7 +4,7 @@ POST {{baseUrl}}/rices Content-Type: application/json X-Zen-Rice-Name: cool-zenrice-aurora2 X-Zen-Rice-Author: jhon@doe.com -User-Agent: ZenBrowser/1.0.0.0 (EndeavourOS x86_64) +User-Agent: ZenBrowser/1.2b.0 (EndeavourOS x86_64) { "userChrome": "", diff --git a/test/restclient/03_update_rice.http b/test/restclient/03_update_rice.http index 3d9a9fc..8387318 100644 --- a/test/restclient/03_update_rice.http +++ b/test/restclient/03_update_rice.http @@ -7,7 +7,7 @@ Content-Type: application/json x-zen-rices-token: {{previous_token}} X-Zen-Rice-Name: cool-zenrice-aurora2 X-Zen-Rice-Author: jhon@doe.com -User-Agent: ZenBrowser/1.0.0.0 (EndeavourOS x86_64) +User-Agent: ZenBrowser/1.2b.0 (EndeavourOS x86_64) { "userChrome": "",