22 Commits
1.3.0 ... dev

Author SHA1 Message Date
William Oldham
f5cec7ba24 Merge pull request #40 from qtchaos/index-OK
Add a success message to the base path
2024-02-26 12:41:12 +00:00
qtchaos
db00030df0 feat: add a success message to the base path 2024-02-26 14:13:59 +02:00
mrjvs
2fe48d24d7 Merge branch 'master' into dev 2024-01-25 22:33:24 +01:00
William Oldham
b0f5b28084 Merge pull request #38 from movie-web/scrapetools
Add tool metrics
2024-01-25 21:29:24 +00:00
mrjvs
b5ee9f1f7a Merge branch 'dev' into scrapetools 2024-01-25 22:28:33 +01:00
mrjvs
eb0f47ba53 Bump version 2024-01-25 22:28:08 +01:00
mrjvs
26b46876c5 fix linting 2024-01-25 22:27:54 +01:00
mrjvs
f58c2c86e5 Merge pull request #37 from gsi-kevincarrera/fix/backend-always-return-true
Fix: Implement function to correctly handle boolean strings with zod
2024-01-25 22:27:15 +01:00
mrjvs
4af2d32b72 Add tool metrics 2024-01-25 22:24:58 +01:00
Kevin Carrera Calzado
a911e52ddb Add default false value to boolean schema 2024-01-24 12:54:24 -05:00
Kevin Carrera Calzado
7b26b029de Fix:Implement function to handle boolean strings 2024-01-24 12:34:01 -05:00
William Oldham
06ad2249d6 Merge pull request #35 from movie-web/remove-arm
Remove ARM 32-bit from Docker Build
2024-01-09 21:36:01 +00:00
William Oldham
14601b9010 Remove ARM 32-bit from Docker Build 2024-01-09 21:01:52 +00:00
William Oldham
b1eeb21ba4 Merge pull request #34 from weeryan17/feature/arm-build
Update workflows to support arm
2024-01-07 17:58:15 +00:00
weeryan17
5855943a56 Update .github/workflows/linting_testing.yml
Co-authored-by: William Oldham <github@binaryoverload.co.uk>
2024-01-07 12:55:30 -05:00
weeryan17
9073010f4c Update .github/workflows/linting_testing.yml
Co-authored-by: William Oldham <github@binaryoverload.co.uk>
2024-01-07 12:55:24 -05:00
weeryan17
78e6b6443f Update CODEOWNERS file 2024-01-07 12:51:09 -05:00
weeryan17
e7c5d93cc3 Update workflows to support arm 2024-01-07 12:42:45 -05:00
mrjvs
9fe8cb4877 Merge pull request #31 from Caio-Nogueira/fix-backend-captcha
update deprecated composer syntax; change body format in API request
2024-01-05 21:04:32 +01:00
mrjvs
66840d7894 Merge branch 'dev' into fix-backend-captcha 2024-01-05 20:19:26 +01:00
mrjvs
1632f138b0 Merge branch 'dev' into fix-backend-captcha 2023-12-31 14:10:18 +01:00
caio_nogueira_27
0c3de831fb update deprecated composer syntax; change body format in API request 2023-12-31 13:03:32 +00:00
12 changed files with 68 additions and 36 deletions

View File

@@ -41,7 +41,7 @@ services:
links:
- postgres:postgres
environment:
- DATABASE_URL=postgres://postgres:postgres@postgres:5432/postgres?sslmode=disable
- PGWEB_DATABASE_URL=postgres://postgres:postgres@postgres:5432/postgres?sslmode=disable
depends_on:
- postgres

4
.github/CODEOWNERS vendored
View File

@@ -1,3 +1 @@
* @movie-web/core
.github @binaryoverload
* @movie-web/project-leads

View File

@@ -14,16 +14,16 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@v3
uses: actions/checkout@v4
- uses: pnpm/action-setup@v2
with:
version: 8
- name: Install Node.js
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: 18
node-version: 20
cache: 'pnpm'
- name: Install packages
@@ -38,16 +38,16 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@v3
uses: actions/checkout@v4
- uses: pnpm/action-setup@v2
with:
version: 8
- name: Install Node.js
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: 18
node-version: 20
cache: 'pnpm'
- name: Install packages
@@ -62,10 +62,10 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
uses: docker/setup-buildx-action@v3
- name: Build
uses: docker/build-push-action@v4
uses: docker/build-push-action@v5

View File

@@ -12,7 +12,7 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Get version
id: package-version
@@ -42,10 +42,10 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Setup Docker buildx
uses: docker/setup-buildx-action@v2
uses: docker/setup-buildx-action@v3
- name: Get version
id: package-version
@@ -70,9 +70,12 @@ jobs:
- name: Build and push Docker image
id: build-and-push
uses: docker/build-push-action@v4
uses: docker/build-push-action@v5
with:
push: true
platforms: linux/amd64,linux/arm64
context: .
labels: ${{ steps.meta.outputs.labels }}
tags: ${{ steps.meta.outputs.tags }}
cache-from: type=gha
cache-to: type=gha,mode=max

View File

@@ -1,6 +1,6 @@
{
"name": "backend",
"version": "1.3.0",
"version": "1.3.1",
"private": true,
"homepage": "https://github.com/movie-web/backend",
"engines": {

View File

@@ -2,6 +2,7 @@ import { devFragment } from '@/config/fragments/dev';
import { dockerFragment } from '@/config/fragments/docker';
import { createConfigLoader } from 'neat-config';
import { z } from 'zod';
import { booleanSchema } from './schema';
const fragments = {
dev: devFragment,
@@ -13,7 +14,7 @@ export const ormConfigSchema = z.object({
// connection URL for postgres database
connection: z.string(),
// whether to use SSL for the connection
ssl: z.coerce.boolean().default(false),
ssl: booleanSchema.default(false),
}),
});

View File

@@ -1,5 +1,7 @@
import { z } from 'zod';
export const booleanSchema = z.preprocess((val) => val === 'true', z.boolean());
export const configSchema = z.object({
server: z
.object({
@@ -11,13 +13,13 @@ export const configSchema = z.object({
// disable cross origin restrictions, allow any site.
// overwrites the cors option above
allowAnySite: z.coerce.boolean().default(false),
allowAnySite: booleanSchema.default(false),
// should it trust reverse proxy headers? (for ip gathering)
trustProxy: z.coerce.boolean().default(false),
trustProxy: booleanSchema.default(false),
// should it trust cloudflare headers? (for ip gathering, cloudflare has priority)
trustCloudflare: z.coerce.boolean().default(false),
trustCloudflare: booleanSchema.default(false),
// prefix for where the instance is run on. for example set it to /backend if you're hosting it on example.com/backend
// if this is set, do not apply url rewriting before proxing
@@ -30,7 +32,7 @@ export const configSchema = z.object({
format: z.enum(['json', 'pretty']).default('pretty'),
// show debug logs?
debug: z.coerce.boolean().default(false),
debug: booleanSchema.default(false),
})
.default({}),
postgres: z.object({
@@ -38,19 +40,19 @@ export const configSchema = z.object({
connection: z.string(),
// run all migrations on boot of the application
migrateOnBoot: z.coerce.boolean().default(false),
migrateOnBoot: booleanSchema.default(false),
// try to sync the schema on boot, useful for development
// will always keep the database schema in sync with the connected database
// it is extremely destructive, do not use it EVER in production
syncSchema: z.coerce.boolean().default(false),
syncSchema: booleanSchema.default(false),
// 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),
debugLogging: booleanSchema.default(false),
// Enable SSL for the postgres connection
ssl: z.coerce.boolean().default(false),
ssl: booleanSchema.default(false),
}),
crypto: z.object({
// session secret. used for signing session tokens
@@ -65,7 +67,7 @@ export const configSchema = z.object({
captcha: z
.object({
// enabled captchas on register
enabled: z.coerce.boolean().default(false),
enabled: booleanSchema.default(false),
// captcha secret
secret: z.string().min(1).optional(),
@@ -76,7 +78,7 @@ export const configSchema = z.object({
ratelimits: z
.object({
// enabled captchas on register
enabled: z.coerce.boolean().default(false),
enabled: booleanSchema.default(false),
redisUrl: z.string().optional(),
})
.default({}),

View File

@@ -1,3 +1,4 @@
import { indexRouter } from '@/routes';
import { loginAuthRouter } from '@/routes/auth/login';
import { manageAuthRouter } from '@/routes/auth/manage';
import { metaRouter } from '@/routes/meta';
@@ -25,4 +26,5 @@ export async function setupRoutes(app: FastifyInstance) {
await app.register(userSettingsRouter.register);
await app.register(userGetRouter.register);
await app.register(metricsRouter.register);
await app.register(indexRouter.register);
}

View File

@@ -13,6 +13,7 @@ export type Metrics = {
providerHostnames: Counter<'hostname'>;
providerStatuses: Counter<'provider_id' | 'status'>;
watchMetrics: Counter<'title' | 'tmdb_full_id' | 'provider_id' | 'success'>;
toolMetrics: Counter<'tool'>;
};
let metrics: null | Metrics = null;
@@ -59,6 +60,11 @@ export async function setupMetrics(app: FastifyInstance) {
help: 'mw_media_watch_count',
labelNames: ['title', 'tmdb_full_id', 'provider_id', 'success'],
}),
toolMetrics: new Counter({
name: 'mw_provider_tool_count',
help: 'mw_provider_tool_count',
labelNames: ['tool'],
}),
};
const promClient = app.metrics.client;
@@ -68,6 +74,7 @@ export async function setupMetrics(app: FastifyInstance) {
promClient.register.registerMetric(metrics.providerStatuses);
promClient.register.registerMetric(metrics.watchMetrics);
promClient.register.registerMetric(metrics.captchaSolves);
promClient.register.registerMetric(metrics.toolMetrics);
const orm = getORM();
const em = orm.em.fork();

14
src/routes/index.ts Normal file
View File

@@ -0,0 +1,14 @@
import { version } from '@/config';
import { handle } from '@/services/handler';
import { makeRouter } from '@/services/router';
export const indexRouter = makeRouter((app) => {
app.get(
'/',
handle(async () => {
return {
message: `Backend is working as expected (${version})`,
};
}),
);
});

View File

@@ -19,6 +19,7 @@ const metricsProviderSchema = z.object({
const metricsProviderInputSchema = z.object({
items: z.array(metricsProviderSchema).max(10).min(1),
tool: z.string().optional(),
});
export const metricsRouter = makeRouter((app) => {
@@ -65,6 +66,12 @@ export const metricsRouter = makeRouter((app) => {
});
}
if (body.tool) {
getMetrics().toolMetrics.inc({
tool: body.tool,
});
}
return true;
}),
);

View File

@@ -4,16 +4,14 @@ import { StatusError } from '@/services/error';
export async function isValidCaptcha(token: string): Promise<boolean> {
if (!conf.captcha.secret)
throw new Error('isValidCaptcha() is called but no secret set');
const formData = new URLSearchParams();
formData.append('secret', conf.captcha.secret);
formData.append('response', token);
const res = await fetch('https://www.google.com/recaptcha/api/siteverify', {
method: 'POST',
body: JSON.stringify({
secret: conf.captcha.secret,
response: token,
}),
headers: {
'content-type': 'application/json',
},
body: formData,
});
const json = await res.json();
return !!json.success;
}