mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-31 04:04:21 -04:00
Handle watchstatus on movies/series
This commit is contained in:
parent
22754442ad
commit
11e1c59698
@ -96,7 +96,7 @@ RABBITMQ_DEFAULT_PASS=aohohunuhouhuhhoahothonseuhaoensuthoaentsuhha
|
|||||||
|
|
||||||
|
|
||||||
# v5 stuff, does absolutely nothing on master (aka: you can delete this)
|
# v5 stuff, does absolutely nothing on master (aka: you can delete this)
|
||||||
EXTRA_CLAIMS='{"permissions": [], "verified": false}'
|
EXTRA_CLAIMS='{"permissions": ["core.read"], "verified": false}'
|
||||||
FIRST_USER_CLAIMS='{"permissions": ["user.read", "users.write", "users.delete"], "verified": true}'
|
FIRST_USER_CLAIMS='{"permissions": ["user.read", "users.write", "users.delete", "core.read"], "verified": true}'
|
||||||
GUEST_CLAIMS='{"permissions": []}'
|
GUEST_CLAIMS='{"permissions": ["core.read"]}'
|
||||||
PROTECTED_CLAIMS="permissions,verified"
|
PROTECTED_CLAIMS="permissions,verified"
|
||||||
|
@ -26,35 +26,36 @@ export const auth = new Elysia({ name: "auth" })
|
|||||||
authorization: t.TemplateLiteral("Bearer ${string}"),
|
authorization: t.TemplateLiteral("Bearer ${string}"),
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
|
.resolve(async ({ headers: { authorization }, error }) => {
|
||||||
|
const bearer = authorization?.slice(7);
|
||||||
|
if (!bearer) {
|
||||||
|
return error(500, {
|
||||||
|
status: 500,
|
||||||
|
message: "No jwt, auth server configuration error.",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// @ts-expect-error ts can't understand that there's two overload idk why
|
||||||
|
const { payload } = await jwtVerify(bearer, jwtSecret ?? jwks, {
|
||||||
|
issuer: process.env.JWT_ISSUER,
|
||||||
|
});
|
||||||
|
const jwt = validator.Decode(payload);
|
||||||
|
|
||||||
|
return { jwt };
|
||||||
|
})
|
||||||
.macro({
|
.macro({
|
||||||
permissions(perms: string[]) {
|
permissions(perms: string[]) {
|
||||||
return {
|
return {
|
||||||
resolve: async ({ headers: { authorization }, error }) => {
|
beforeHandle: ({ jwt, error }) => {
|
||||||
const bearer = authorization?.slice(7);
|
|
||||||
if (!bearer) {
|
|
||||||
return error(500, {
|
|
||||||
status: 500,
|
|
||||||
message: "No jwt, auth server configuration error.",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// @ts-expect-error ts can't understand that there's two overload idk why
|
|
||||||
const { payload } = await jwtVerify(bearer, jwtSecret ?? jwks, {
|
|
||||||
issuer: process.env.JWT_ISSUER,
|
|
||||||
});
|
|
||||||
const jwt = validator.Decode(payload);
|
|
||||||
|
|
||||||
for (const perm of perms) {
|
for (const perm of perms) {
|
||||||
if (!jwt.permissions.includes(perm)) {
|
if (!jwt!.permissions.includes(perm)) {
|
||||||
return error(403, {
|
return error(403, {
|
||||||
status: 403,
|
status: 403,
|
||||||
message: `Missing permission: '${perm}'.`,
|
message: `Missing permission: '${perm}'.`,
|
||||||
details: { current: jwt.permissions, required: perms },
|
details: { current: jwt!.permissions, required: perms },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return { jwt };
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
@ -6,6 +6,7 @@ import {
|
|||||||
entryTranslations,
|
entryTranslations,
|
||||||
entryVideoJoin,
|
entryVideoJoin,
|
||||||
history,
|
history,
|
||||||
|
profiles,
|
||||||
showStudioJoin,
|
showStudioJoin,
|
||||||
showTranslations,
|
showTranslations,
|
||||||
shows,
|
shows,
|
||||||
@ -36,7 +37,7 @@ import {
|
|||||||
sortToSql,
|
sortToSql,
|
||||||
} from "~/models/utils";
|
} from "~/models/utils";
|
||||||
import type { EmbeddedVideo } from "~/models/video";
|
import type { EmbeddedVideo } from "~/models/video";
|
||||||
import { entryVideosQ, getEntryProgressQ } from "../entries";
|
import { entryVideosQ, getEntryProgressQ, mapProgress } from "../entries";
|
||||||
|
|
||||||
export const showFilters: FilterDef = {
|
export const showFilters: FilterDef = {
|
||||||
genres: {
|
genres: {
|
||||||
@ -151,7 +152,7 @@ const showRelations = {
|
|||||||
firstEntry: ({
|
firstEntry: ({
|
||||||
languages,
|
languages,
|
||||||
userId,
|
userId,
|
||||||
}: { languages: string[]; userId: number }) => {
|
}: { languages: string[]; userId: string }) => {
|
||||||
const transQ = db
|
const transQ = db
|
||||||
.selectDistinctOn([entryTranslations.pk])
|
.selectDistinctOn([entryTranslations.pk])
|
||||||
.from(entryTranslations)
|
.from(entryTranslations)
|
||||||
@ -171,7 +172,7 @@ const showRelations = {
|
|||||||
...transCol,
|
...transCol,
|
||||||
number: entries.episodeNumber,
|
number: entries.episodeNumber,
|
||||||
videos: entryVideosQ.videos,
|
videos: entryVideosQ.videos,
|
||||||
progress: getColumns(progressQ),
|
progress: mapProgress(progressQ),
|
||||||
}).as("firstEntry"),
|
}).as("firstEntry"),
|
||||||
})
|
})
|
||||||
.from(entries)
|
.from(entries)
|
||||||
@ -189,7 +190,7 @@ const showRelations = {
|
|||||||
watchStatusQ,
|
watchStatusQ,
|
||||||
}: {
|
}: {
|
||||||
languages: string[];
|
languages: string[];
|
||||||
userId: number;
|
userId: string;
|
||||||
watchStatusQ: PgSelect<typeof watchlist>;
|
watchStatusQ: PgSelect<typeof watchlist>;
|
||||||
}) => {
|
}) => {
|
||||||
const transQ = db
|
const transQ = db
|
||||||
@ -211,7 +212,7 @@ const showRelations = {
|
|||||||
...transCol,
|
...transCol,
|
||||||
number: entries.episodeNumber,
|
number: entries.episodeNumber,
|
||||||
videos: entryVideosQ.videos,
|
videos: entryVideosQ.videos,
|
||||||
progress: getColumns(progressQ),
|
progress: mapProgress(progressQ),
|
||||||
}).as("nextEntry"),
|
}).as("nextEntry"),
|
||||||
})
|
})
|
||||||
.from(entries)
|
.from(entries)
|
||||||
@ -244,7 +245,7 @@ export async function getShows({
|
|||||||
fallbackLanguage?: boolean;
|
fallbackLanguage?: boolean;
|
||||||
preferOriginal?: boolean;
|
preferOriginal?: boolean;
|
||||||
relations?: (keyof typeof showRelations)[];
|
relations?: (keyof typeof showRelations)[];
|
||||||
userId: number;
|
userId: string;
|
||||||
}) {
|
}) {
|
||||||
const transQ = db
|
const transQ = db
|
||||||
.selectDistinctOn([showTranslations.pk])
|
.selectDistinctOn([showTranslations.pk])
|
||||||
@ -263,10 +264,11 @@ export async function getShows({
|
|||||||
const watchStatusQ = db
|
const watchStatusQ = db
|
||||||
.select({
|
.select({
|
||||||
...getColumns(watchlist),
|
...getColumns(watchlist),
|
||||||
percent: watchlist.seenCount,
|
percent: sql`${watchlist.seenCount}`.as("percent"),
|
||||||
})
|
})
|
||||||
.from(watchlist)
|
.from(watchlist)
|
||||||
.where(eq(watchlist.profilePk, userId))
|
.leftJoin(profiles, eq(watchlist.profilePk, profiles.pk))
|
||||||
|
.where(eq(profiles.id, userId))
|
||||||
.as("watchstatus");
|
.as("watchstatus");
|
||||||
|
|
||||||
return await db
|
return await db
|
||||||
|
@ -56,7 +56,7 @@ export const Movie = t.Intersect([
|
|||||||
t.Object({
|
t.Object({
|
||||||
original: Original,
|
original: Original,
|
||||||
isAvailable: t.Boolean(),
|
isAvailable: t.Boolean(),
|
||||||
watchStatus: t.Omit(WatchStatus, ["seenCount"]),
|
watchStatus: t.Nullable(t.Omit(WatchStatus, ["seenCount"])),
|
||||||
}),
|
}),
|
||||||
]);
|
]);
|
||||||
export type Movie = Prettify<typeof Movie.static>;
|
export type Movie = Prettify<typeof Movie.static>;
|
||||||
|
@ -71,7 +71,7 @@ export const Serie = t.Intersect([
|
|||||||
availableCount: t.Integer({
|
availableCount: t.Integer({
|
||||||
description: "The number of episodes that can be played right away",
|
description: "The number of episodes that can be played right away",
|
||||||
}),
|
}),
|
||||||
watchStatus: t.Omit(WatchStatus, ["percent"]),
|
watchStatus: t.Nullable(t.Omit(WatchStatus, ["percent"])),
|
||||||
}),
|
}),
|
||||||
]);
|
]);
|
||||||
export type Serie = Prettify<typeof Serie.static>;
|
export type Serie = Prettify<typeof Serie.static>;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user