diff --git a/package.json b/package.json index d9a4e9d..80acfde 100644 --- a/package.json +++ b/package.json @@ -8,16 +8,16 @@ }, "scripts": { "dev": "nodemon -r tsconfig-paths/register src/main.ts", - "build": "npm run build:pre && npm run build:compile", + "build": "pnpm run build:pre && pnpm run build:compile", "start": "node dist/main.js", "lint": "eslint --ext .ts,.js,.json,.tsx src/", "lint:fix": "eslint --fix --ext .ts,.js,.json,.tsx src/", "build:pre": "rimraf dist/", "build:compile": "tsc && tsc-alias", "preinstall": "npx -y only-allow pnpm", - "migration:create": "npx -y mikro-orm migration:create", - "migration:up": "npx -y mikro-orm migration:up", - "migration:down": "npx -y mikro-orm migration:down" + "migration:create": "pnpm exec mikro-orm migration:create", + "migration:up": "pnpm exec mikro-orm migration:up", + "migration:down": "pnpm exec mikro-orm migration:down" }, "mikro-orm": { "useTsNode": true, diff --git a/src/config/orm.ts b/src/config/orm.ts index 7412ee7..bfbe038 100644 --- a/src/config/orm.ts +++ b/src/config/orm.ts @@ -12,6 +12,8 @@ export const ormConfigSchema = z.object({ postgres: z.object({ // connection URL for postgres database connection: z.string(), + // whether to use SSL for the connection + ssl: z.coerce.boolean().default(false), }), }); diff --git a/src/config/schema.ts b/src/config/schema.ts index b4ad626..d42327e 100644 --- a/src/config/schema.ts +++ b/src/config/schema.ts @@ -48,6 +48,9 @@ export const configSchema = z.object({ // Enable debug logging for MikroORM - Outputs queries and entity management logs // Do NOT use in production, leaks all sensitive data debugLogging: z.coerce.boolean().default(false), + + // Enable SSL for the postgres connection + ssl: z.coerce.boolean().default(false), }), crypto: z.object({ // session secret. used for signing session tokens diff --git a/src/db/migrations/.snapshot-postgres.json b/src/db/migrations/.snapshot-postgres.json index b4204ac..7588bcf 100644 --- a/src/db/migrations/.snapshot-postgres.json +++ b/src/db/migrations/.snapshot-postgres.json @@ -483,6 +483,15 @@ "primary": false, "nullable": true, "mappedType": "string" + }, + "proxy_urls": { + "name": "proxy_urls", + "type": "text[]", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "mappedType": "array" } }, "name": "user_settings", diff --git a/src/db/migrations/Migration20231229214215.ts b/src/db/migrations/Migration20231229214215.ts new file mode 100644 index 0000000..d5149db --- /dev/null +++ b/src/db/migrations/Migration20231229214215.ts @@ -0,0 +1,13 @@ +import { Migration } from '@mikro-orm/migrations'; + +export class Migration20231229214215 extends Migration { + + async up(): Promise { + this.addSql('alter table "user_settings" add column "proxy_urls" text[] null;'); + } + + async down(): Promise { + this.addSql('alter table "user_settings" drop column "proxy_urls";'); + } + +} diff --git a/src/db/models/UserSettings.ts b/src/db/models/UserSettings.ts index 4014255..14911b4 100644 --- a/src/db/models/UserSettings.ts +++ b/src/db/models/UserSettings.ts @@ -1,4 +1,4 @@ -import { Entity, PrimaryKey, Property } from '@mikro-orm/core'; +import { ArrayType, Entity, PrimaryKey, Property } from '@mikro-orm/core'; @Entity({ tableName: 'user_settings' }) export class UserSettings { @@ -13,6 +13,9 @@ export class UserSettings { @Property({ name: 'default_subtitle_language', nullable: true }) defaultSubtitleLanguage?: string | null; + + @Property({ name: 'proxy_urls', type: ArrayType, nullable: true }) + proxyUrls?: string[] | null; } export interface UserSettingsDTO { @@ -20,6 +23,7 @@ export interface UserSettingsDTO { applicationTheme?: string | null; applicationLanguage?: string | null; defaultSubtitleLanguage?: string | null; + proxyUrls?: string[] | null; } export function formatUserSettings( @@ -30,5 +34,6 @@ export function formatUserSettings( applicationTheme: userSettings.applicationTheme, applicationLanguage: userSettings.applicationLanguage, defaultSubtitleLanguage: userSettings.defaultSubtitleLanguage, + proxyUrls: userSettings.proxyUrls, }; } diff --git a/src/mikro-orm.config.ts b/src/mikro-orm.config.ts index e27bb97..1fd778f 100644 --- a/src/mikro-orm.config.ts +++ b/src/mikro-orm.config.ts @@ -1,4 +1,4 @@ import { ormConf } from '@/config/orm'; import { makeOrmConfig } from '@/modules/mikro/orm'; -export default makeOrmConfig(ormConf.postgres.connection); +export default makeOrmConfig(ormConf.postgres.connection, ormConf.postgres.ssl); diff --git a/src/modules/metrics/index.ts b/src/modules/metrics/index.ts index e6f798f..da35f11 100644 --- a/src/modules/metrics/index.ts +++ b/src/modules/metrics/index.ts @@ -67,6 +67,7 @@ export async function setupMetrics(app: FastifyInstance) { promClient.register.registerMetric(metrics.providerHostnames); promClient.register.registerMetric(metrics.providerStatuses); promClient.register.registerMetric(metrics.watchMetrics); + promClient.register.registerMetric(metrics.captchaSolves); const orm = getORM(); const em = orm.em.fork(); diff --git a/src/modules/mikro/index.ts b/src/modules/mikro/index.ts index 415b835..7ff89c7 100644 --- a/src/modules/mikro/index.ts +++ b/src/modules/mikro/index.ts @@ -18,6 +18,7 @@ export async function setupMikroORM() { conf.postgres.connection, conf.postgres.debugLogging, (msg) => log.info(msg), + conf.postgres.ssl, ); if (conf.postgres.syncSchema) { diff --git a/src/modules/mikro/orm.ts b/src/modules/mikro/orm.ts index 3987b46..a0d0d3c 100644 --- a/src/modules/mikro/orm.ts +++ b/src/modules/mikro/orm.ts @@ -2,7 +2,10 @@ import { Options } from '@mikro-orm/core'; import { MikroORM, PostgreSqlDriver } from '@mikro-orm/postgresql'; import path from 'path'; -export function makeOrmConfig(url: string): Options { +export function makeOrmConfig( + url: string, + ssl: boolean, +): Options { return { type: 'postgresql', clientUrl: url, @@ -13,6 +16,11 @@ export function makeOrmConfig(url: string): Options { pathTs: './migrations', path: './migrations', }, + driverOptions: { + connection: { + ssl, + }, + }, }; } @@ -20,9 +28,10 @@ export async function createORM( url: string, debug: boolean, log: (msg: string) => void, + ssl: boolean, ) { return await MikroORM.init({ - ...makeOrmConfig(url), + ...makeOrmConfig(url, ssl), logger: log, debug, }); diff --git a/src/routes/users/settings.ts b/src/routes/users/settings.ts index de315ee..6a11d03 100644 --- a/src/routes/users/settings.ts +++ b/src/routes/users/settings.ts @@ -41,6 +41,7 @@ export const userSettingsRouter = makeRouter((app) => { applicationLanguage: z.string().nullable().optional(), applicationTheme: z.string().nullable().optional(), defaultSubtitleLanguage: z.string().nullable().optional(), + proxyUrls: z.string().array().nullable().optional(), }), }, }, @@ -64,6 +65,7 @@ export const userSettingsRouter = makeRouter((app) => { settings.defaultSubtitleLanguage = body.defaultSubtitleLanguage; if (body.applicationTheme !== undefined) settings.applicationTheme = body.applicationTheme; + if (body.proxyUrls !== undefined) settings.proxyUrls = body.proxyUrls; await em.persistAndFlush(settings); return formatUserSettings(settings);