Read `preferOriginal from jwt settings

This commit is contained in:
Zoe Roux 2025-04-08 00:54:23 +02:00
parent 9991da4fe1
commit c8742605ff
No known key found for this signature in database
9 changed files with 49 additions and 33 deletions

View File

@ -1,7 +1,9 @@
import { TypeCompiler } from "@sinclair/typebox/compiler";
import { Value } from "@sinclair/typebox/value";
import Elysia, { t } from "elysia";
import { createRemoteJWKSet, jwtVerify } from "jose";
import { KError } from "./models/error";
import type { Prettify } from "./utils";
const jwtSecret = process.env.JWT_SECRET
? new TextEncoder().encode(process.env.JWT_SECRET)
@ -13,12 +15,22 @@ const jwks = createRemoteJWKSet(
),
);
const Settings = t.Object(
{
preferOriginal: t.Boolean({ default: true }),
},
{ additionalProperties: true },
);
type Settings = typeof Settings.static;
const Jwt = t.Object({
sub: t.String({ description: "User id" }),
sid: t.String({ description: "Session id" }),
username: t.String(),
permissions: t.Array(t.String()),
settings: t.Optional(t.Partial(Settings, { default: {} })),
});
type Jwt = typeof Jwt.static;
const validator = TypeCompiler.Compile(Jwt);
export const auth = new Elysia({ name: "auth" })
@ -44,7 +56,10 @@ export const auth = new Elysia({ name: "auth" })
const { payload } = await jwtVerify(bearer, jwtSecret ?? jwks, {
issuer: process.env.JWT_ISSUER,
});
const jwt = validator.Decode(payload);
const raw = validator.Decode(payload);
const jwt = Value.Default(Jwt, raw) as Prettify<
Jwt & { settings: Settings }
>;
return { jwt };
} catch (err) {

View File

@ -100,7 +100,7 @@ export const watchlistH = new Elysia({ tags: ["profiles"] })
query: { limit, after, query, sort, filter, preferOriginal },
headers: { "accept-language": languages },
request: { url },
jwt: { sub },
jwt: { sub, settings },
}) => {
const langs = processLanguages(languages);
const items = await getShows({
@ -114,7 +114,7 @@ export const watchlistH = new Elysia({ tags: ["profiles"] })
filter,
),
languages: langs,
preferOriginal,
preferOriginal: preferOriginal ?? settings.preferOriginal,
userId: sub,
});
return createPage(items, { url, sort, limit });
@ -138,6 +138,7 @@ export const watchlistH = new Elysia({ tags: ["profiles"] })
async ({
params: { id },
query: { limit, after, query, sort, filter, preferOriginal },
jwt: { settings },
headers: { "accept-language": languages, authorization },
request: { url },
error,
@ -157,7 +158,7 @@ export const watchlistH = new Elysia({ tags: ["profiles"] })
filter,
),
languages: langs,
preferOriginal,
preferOriginal: preferOriginal ?? settings.preferOriginal,
userId: uInfo.id,
});
return createPage(items, { url, sort, limit });

View File

@ -40,7 +40,7 @@ export const collections = new Elysia({
params: { id },
headers: { "accept-language": languages },
query: { preferOriginal, with: relations },
jwt: { sub },
jwt: { sub, settings },
error,
set,
}) => {
@ -53,7 +53,7 @@ export const collections = new Elysia({
),
languages: langs,
fallbackLanguage: langs.includes("*"),
preferOriginal,
preferOriginal: preferOriginal ?? settings.preferOriginal,
relations,
userId: sub,
});
@ -144,7 +144,7 @@ export const collections = new Elysia({
async ({
query: { limit, after, query, sort, filter, preferOriginal },
headers: { "accept-language": languages },
jwt: { sub },
jwt: { sub, settings },
request: { url },
}) => {
const langs = processLanguages(languages);
@ -155,7 +155,7 @@ export const collections = new Elysia({
sort,
filter: and(eq(shows.kind, "collection"), filter),
languages: langs,
preferOriginal,
preferOriginal: preferOriginal ?? settings.preferOriginal,
userId: sub,
});
return createPage(items, { url, sort, limit });
@ -228,7 +228,7 @@ export const collections = new Elysia({
params: { id },
query: { limit, after, query, sort, filter, preferOriginal },
headers: { "accept-language": languages },
jwt: { sub },
jwt: { sub, settings },
request: { url },
error,
}) => {
@ -262,7 +262,7 @@ export const collections = new Elysia({
filter,
),
languages: langs,
preferOriginal,
preferOriginal: preferOriginal ?? settings.preferOriginal,
userId: sub,
});
return createPage(items, { url, sort, limit });
@ -285,7 +285,7 @@ export const collections = new Elysia({
params: { id },
query: { limit, after, query, sort, filter, preferOriginal },
headers: { "accept-language": languages },
jwt: { sub },
jwt: { sub, settings },
request: { url },
error,
}) => {
@ -319,7 +319,7 @@ export const collections = new Elysia({
filter,
),
languages: langs,
preferOriginal,
preferOriginal: preferOriginal ?? settings.preferOriginal,
userId: sub,
});
return createPage(items, { url, sort, limit });
@ -342,7 +342,7 @@ export const collections = new Elysia({
params: { id },
query: { limit, after, query, sort, filter, preferOriginal },
headers: { "accept-language": languages },
jwt: { sub },
jwt: { sub, settings },
request: { url },
error,
}) => {
@ -372,7 +372,7 @@ export const collections = new Elysia({
sort,
filter: and(eq(shows.collectionPk, collection.pk), filter),
languages: langs,
preferOriginal,
preferOriginal: preferOriginal ?? settings.preferOriginal,
userId: sub,
});
return createPage(items, { url, sort, limit });

View File

@ -30,7 +30,7 @@ export const movies = new Elysia({ prefix: "/movies", tags: ["movies"] })
params: { id },
headers: { "accept-language": languages },
query: { preferOriginal, with: relations },
jwt: { sub },
jwt: { sub, settings },
error,
set,
}) => {
@ -43,7 +43,7 @@ export const movies = new Elysia({ prefix: "/movies", tags: ["movies"] })
),
languages: langs,
fallbackLanguage: langs.includes("*"),
preferOriginal,
preferOriginal: preferOriginal ?? settings.preferOriginal,
relations,
userId: sub,
});
@ -135,7 +135,7 @@ export const movies = new Elysia({ prefix: "/movies", tags: ["movies"] })
query: { limit, after, query, sort, filter, preferOriginal },
headers: { "accept-language": languages },
request: { url },
jwt: { sub },
jwt: { sub, settings },
}) => {
const langs = processLanguages(languages);
const items = await getShows({
@ -145,7 +145,7 @@ export const movies = new Elysia({ prefix: "/movies", tags: ["movies"] })
sort,
filter: and(eq(shows.kind, "movie"), filter),
languages: langs,
preferOriginal,
preferOriginal: preferOriginal ?? settings.preferOriginal,
userId: sub,
});
return createPage(items, { url, sort, limit });

View File

@ -30,7 +30,7 @@ export const series = new Elysia({ prefix: "/series", tags: ["series"] })
params: { id },
headers: { "accept-language": languages },
query: { preferOriginal, with: relations },
jwt: { sub },
jwt: { sub, settings },
error,
set,
}) => {
@ -43,7 +43,7 @@ export const series = new Elysia({ prefix: "/series", tags: ["series"] })
),
languages: langs,
fallbackLanguage: langs.includes("*"),
preferOriginal,
preferOriginal: preferOriginal ?? settings.preferOriginal,
relations,
userId: sub,
});
@ -138,7 +138,7 @@ export const series = new Elysia({ prefix: "/series", tags: ["series"] })
query: { limit, after, query, sort, filter, preferOriginal },
headers: { "accept-language": languages },
request: { url },
jwt: { sub },
jwt: { sub, settings },
}) => {
const langs = processLanguages(languages);
const items = await getShows({
@ -148,7 +148,7 @@ export const series = new Elysia({ prefix: "/series", tags: ["series"] })
sort,
filter: and(eq(shows.kind, "serie"), filter),
languages: langs,
preferOriginal,
preferOriginal: preferOriginal ?? settings.preferOriginal,
userId: sub,
});
return createPage(items, { url, sort, limit });

View File

@ -65,7 +65,7 @@ export const showsH = new Elysia({ prefix: "/shows", tags: ["shows"] })
},
headers: { "accept-language": languages },
request: { url },
jwt: { sub },
jwt: { sub, settings },
}) => {
const langs = processLanguages(languages);
const items = await getShows({
@ -78,7 +78,7 @@ export const showsH = new Elysia({ prefix: "/shows", tags: ["shows"] })
filter,
),
languages: langs,
preferOriginal,
preferOriginal: preferOriginal ?? settings.preferOriginal,
userId: sub,
});
return createPage(items, { url, sort, limit });

View File

@ -191,7 +191,7 @@ export const staffH = new Elysia({ tags: ["staff"] })
query: { limit, after, query, sort, filter, preferOriginal },
headers: { "accept-language": languages },
request: { url },
jwt: { sub },
jwt: { sub, settings },
error,
}) => {
const [member] = await db
@ -243,7 +243,7 @@ export const staffH = new Elysia({ tags: ["staff"] })
kind: sql<any>`${shows.kind}`,
isAvailable: sql<boolean>`${shows.availableCount} != 0`,
...(preferOriginal && {
...((preferOriginal ?? settings.preferOriginal) && {
poster: sql<Image>`coalesce(nullif(${shows.original}->'poster', 'null'::jsonb), ${transQ.poster})`,
thumbnail: sql<Image>`coalesce(nullif(${shows.original}->'thumbnail', 'null'::jsonb), ${transQ.thumbnail})`,
banner: sql<Image>`coalesce(nullif(${shows.original}->'banner', 'null'::jsonb), ${transQ.banner})`,

View File

@ -303,7 +303,7 @@ export const studiosH = new Elysia({ prefix: "/studios", tags: ["studios"] })
params: { id },
query: { limit, after, query, sort, filter, preferOriginal },
headers: { "accept-language": languages },
jwt: { sub },
jwt: { sub, settings },
request: { url },
error,
}) => {
@ -341,7 +341,7 @@ export const studiosH = new Elysia({ prefix: "/studios", tags: ["studios"] })
filter,
),
languages: langs,
preferOriginal,
preferOriginal: preferOriginal ?? settings.preferOriginal,
userId: sub,
});
return createPage(items, { url, sort, limit });
@ -364,7 +364,7 @@ export const studiosH = new Elysia({ prefix: "/studios", tags: ["studios"] })
params: { id },
query: { limit, after, query, sort, filter, preferOriginal },
headers: { "accept-language": languages },
jwt: { sub },
jwt: { sub, settings },
request: { url },
error,
}) => {
@ -403,7 +403,7 @@ export const studiosH = new Elysia({ prefix: "/studios", tags: ["studios"] })
filter,
),
languages: langs,
preferOriginal,
preferOriginal: preferOriginal ?? settings.preferOriginal,
userId: sub,
});
return createPage(items, { url, sort, limit });
@ -426,7 +426,7 @@ export const studiosH = new Elysia({ prefix: "/studios", tags: ["studios"] })
params: { id },
query: { limit, after, query, sort, filter, preferOriginal },
headers: { "accept-language": languages },
jwt: { sub },
jwt: { sub, settings },
request: { url },
error,
}) => {
@ -465,7 +465,7 @@ export const studiosH = new Elysia({ prefix: "/studios", tags: ["studios"] })
filter,
),
languages: langs,
preferOriginal,
preferOriginal: preferOriginal ?? settings.preferOriginal,
userId: sub,
});
return createPage(items, { url, sort, limit });

View File

@ -126,7 +126,7 @@ describe("Set & get history", () => {
});
});
// extras, unknowns
// TODO: extras, unknowns
it("Update watchlist", async () => {
const [resp, body] = await getWatchlist("me", {});