diff --git a/packages/skin-database/api/graphql/ModernSkinsConnection.ts b/packages/skin-database/api/graphql/ModernSkinsConnection.ts index 76f91a85..c709cdfd 100644 --- a/packages/skin-database/api/graphql/ModernSkinsConnection.ts +++ b/packages/skin-database/api/graphql/ModernSkinsConnection.ts @@ -2,7 +2,7 @@ import { Int } from "grats"; import SkinModel from "../../data/SkinModel"; import { knex } from "../../db"; import ModernSkinResolver from "./resolvers/ModernSkinResolver"; -import { Ctx } from "."; +import UserContext from "../../data/UserContext.js"; /** * A collection of "modern" Winamp skins @@ -30,7 +30,7 @@ export default class ModernSkinsConnection { /** * The list of skins * @gqlField */ - async nodes({ ctx }: Ctx): Promise> { + async nodes(ctx: UserContext): Promise> { const skins = await this._getQuery() .select() .limit(this._first) diff --git a/packages/skin-database/api/graphql/SkinsConnection.ts b/packages/skin-database/api/graphql/SkinsConnection.ts index eb16d26e..761c0e9f 100644 --- a/packages/skin-database/api/graphql/SkinsConnection.ts +++ b/packages/skin-database/api/graphql/SkinsConnection.ts @@ -5,7 +5,7 @@ import SkinResolver from "./resolvers/SkinResolver"; import LRU from "lru-cache"; import { Int } from "grats"; import { ISkin } from "./resolvers/CommonSkinResolver"; -import { Ctx } from "."; +import UserContext from "../../data/UserContext.js"; const options = { max: 100, @@ -102,7 +102,7 @@ export default class SkinsConnection { * The list of skins * @gqlField */ - async nodes({ ctx }: Ctx): Promise> { + async nodes(ctx: UserContext): Promise> { if (this._sort === "MUSEUM") { if (this._filter) { throw new Error( diff --git a/packages/skin-database/api/graphql/index.ts b/packages/skin-database/api/graphql/index.ts index 8b711646..3af1ba56 100644 --- a/packages/skin-database/api/graphql/index.ts +++ b/packages/skin-database/api/graphql/index.ts @@ -3,10 +3,16 @@ import { createHandler } from "graphql-http/lib/use/express"; // import DEFAULT_QUERY from "./defaultQuery"; import { getSchema } from "./schema"; +import UserContext from "../../data/UserContext.js"; /** @gqlContext */ export type Ctx = Express.Request; +/** @gqlContext */ +export function getUserContext(ctx: Ctx): UserContext { + return ctx.ctx; +} + const router = Router(); router.use( diff --git a/packages/skin-database/api/graphql/resolvers/NodeResolver.ts b/packages/skin-database/api/graphql/resolvers/NodeResolver.ts index b1e5a9dc..e2f689e4 100644 --- a/packages/skin-database/api/graphql/resolvers/NodeResolver.ts +++ b/packages/skin-database/api/graphql/resolvers/NodeResolver.ts @@ -1,8 +1,7 @@ import { ID } from "grats"; -import { Query } from "./QueryResolver"; -import { Ctx } from ".."; import SkinModel from "../../../data/SkinModel"; import SkinResolver from "./SkinResolver"; +import UserContext from "../../../data/UserContext.js"; /** * A globally unique object. The `id` here is intended only for use within @@ -36,7 +35,10 @@ export function fromId(base64Id: string): { graphqlType: string; id: string } { * https://graphql.org/learn/global-object-identification/ * @gqlQueryField */ -export async function node(id: ID, { ctx }: Ctx): Promise { +export async function node( + id: ID, + ctx: UserContext +): Promise { const { graphqlType, id: localId } = fromId(id); // TODO Use typeResolver switch (graphqlType) { diff --git a/packages/skin-database/api/graphql/resolvers/ReviewResolver.ts b/packages/skin-database/api/graphql/resolvers/ReviewResolver.ts index a0d54558..a7a232a3 100644 --- a/packages/skin-database/api/graphql/resolvers/ReviewResolver.ts +++ b/packages/skin-database/api/graphql/resolvers/ReviewResolver.ts @@ -1,4 +1,5 @@ import { Ctx } from ".."; +import UserContext from "../../../data/UserContext.js"; import { Rating, ReviewRow } from "../../../types"; import { ISkin } from "./CommonSkinResolver"; import SkinResolver from "./SkinResolver"; @@ -17,7 +18,7 @@ export default class ReviewResolver { * The skin that was reviewed * @gqlField */ - skin({ ctx }: Ctx): Promise { + skin(ctx: UserContext): Promise { return SkinResolver.fromMd5(ctx, this._model.skin_md5); } diff --git a/packages/skin-database/api/graphql/resolvers/SkinResolver.ts b/packages/skin-database/api/graphql/resolvers/SkinResolver.ts index e46a309b..46171ab2 100644 --- a/packages/skin-database/api/graphql/resolvers/SkinResolver.ts +++ b/packages/skin-database/api/graphql/resolvers/SkinResolver.ts @@ -38,7 +38,7 @@ export default class SkinResolver { */ export async function fetch_skin_by_md5( md5: string, - { ctx }: Ctx + ctx: UserContext ): Promise { const skin = await SkinModel.fromMd5(ctx, md5); if (skin == null) { @@ -59,7 +59,7 @@ export async function search_skins( first = 10, offset = 0, }: { query: string; first?: Int; offset?: Int }, - { ctx }: Ctx + ctx: UserContext ): Promise> { if (first > 1000) { throw new Error("Can only query 1000 records via search."); @@ -81,7 +81,7 @@ export async function search_skins( /** * A random skin that needs to be reviewed * @gqlQueryField */ -export async function skin_to_review({ ctx }: Ctx): Promise { +export async function skin_to_review(ctx: UserContext): Promise { if (!ctx.authed()) { return null; } diff --git a/packages/skin-database/api/graphql/resolvers/SkinUpload.ts b/packages/skin-database/api/graphql/resolvers/SkinUpload.ts index 2a02ea1e..9a5392bf 100644 --- a/packages/skin-database/api/graphql/resolvers/SkinUpload.ts +++ b/packages/skin-database/api/graphql/resolvers/SkinUpload.ts @@ -1,4 +1,3 @@ -import { Ctx } from ".."; import SkinModel from "../../../data/SkinModel"; import UserContext from "../../../data/UserContext"; import { knex } from "../../../db"; @@ -11,8 +10,8 @@ import SkinResolver from "./SkinResolver"; * @deprecated Prefer `upload_statuses` instead, were we operate on ids. */ export async function upload_statuses_by_md5( - { md5s }: { md5s: string[] }, - { ctx }: Ctx + md5s: string[], + ctx: UserContext ): Promise> { return _upload_statuses({ keyName: "skin_md5", keys: md5s }, ctx); } @@ -22,7 +21,7 @@ export async function upload_statuses_by_md5( * @gqlQueryField */ export async function upload_statuses( ids: string[], - { ctx }: Ctx + ctx: UserContext ): Promise> { return _upload_statuses({ keyName: "id", keys: ids }, ctx); } diff --git a/packages/skin-database/api/graphql/resolvers/UploadMutation.ts b/packages/skin-database/api/graphql/resolvers/UploadMutation.ts index 2cf120a5..42efa0dd 100644 --- a/packages/skin-database/api/graphql/resolvers/UploadMutation.ts +++ b/packages/skin-database/api/graphql/resolvers/UploadMutation.ts @@ -4,6 +4,7 @@ import * as S3 from "../../../s3"; import * as Skins from "../../../data/skins"; import { processUserUploads } from "../../processUserUploads"; import { Ctx } from ".."; +import UserContext from "../../../data/UserContext.js"; // We don't use a resolver here, just return the value directly. /** @@ -45,8 +46,8 @@ class UploadMutationResolver { * @gqlField */ async get_upload_urls( - { files }: { files: UploadUrlRequest[] }, - { ctx }: Ctx + files: UploadUrlRequest[], + ctx: UserContext ): Promise> { const missing: UploadUrl[] = []; await Parallel.each( @@ -69,7 +70,8 @@ class UploadMutationResolver { * @gqlField */ async report_skin_uploaded( - { id, md5 }: { id: string; md5: string }, + id: string, + md5: string, req: Ctx ): Promise { // TODO: Validate md5 and id; diff --git a/packages/skin-database/api/graphql/resolvers/UserResolver.ts b/packages/skin-database/api/graphql/resolvers/UserResolver.ts index eaa37a74..3042a909 100644 --- a/packages/skin-database/api/graphql/resolvers/UserResolver.ts +++ b/packages/skin-database/api/graphql/resolvers/UserResolver.ts @@ -1,9 +1,9 @@ -import { Ctx } from ".."; +import UserContext from "../../../data/UserContext.js"; /** @gqlType User */ export default class UserResolver { /** @gqlField */ - username({ ctx }: Ctx): string | null { + username(ctx: UserContext): string | null { return ctx.username; } } diff --git a/packages/skin-database/api/graphql/schema.ts b/packages/skin-database/api/graphql/schema.ts index 8ac24cbc..32c53e8e 100644 --- a/packages/skin-database/api/graphql/schema.ts +++ b/packages/skin-database/api/graphql/schema.ts @@ -3,6 +3,7 @@ * Do not manually edit. Regenerate by running `npx grats`. */ import { defaultFieldResolver, GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLBoolean, GraphQLInt, GraphQLInterfaceType, GraphQLList, GraphQLNonNull, GraphQLID, GraphQLEnumType, GraphQLInputObjectType } from "graphql"; +import { getUserContext as getUserContext } from "./index"; import { fetch_archive_file_by_md5 as queryFetch_archive_file_by_md5Resolver } from "./../../data/ArchiveFileModel"; import { fetch_internet_archive_item_by_identifier as queryFetch_internet_archive_item_by_identifierResolver } from "./../../data/IaItemModel"; import { fetch_skin_by_md5 as queryFetch_skin_by_md5Resolver, search_skins as querySearch_skinsResolver, skin_to_review as querySkin_to_reviewResolver } from "./resolvers/SkinResolver"; @@ -118,7 +119,7 @@ export function getSchema(): GraphQLSchema { name: "skin", type: SkinType, resolve(source, _args, context) { - return source.skin(context); + return source.skin(getUserContext(context)); } } }; @@ -329,7 +330,7 @@ export function getSchema(): GraphQLSchema { name: "username", type: GraphQLString, resolve(source, _args, context) { - return source.username(context); + return source.username(getUserContext(context)); } } }; @@ -504,7 +505,7 @@ export function getSchema(): GraphQLSchema { name: "nodes", type: new GraphQLList(ModernSkinType), resolve(source, _args, context) { - return assertNonNull(source.nodes(context)); + return assertNonNull(source.nodes(getUserContext(context))); } } }; @@ -528,7 +529,7 @@ export function getSchema(): GraphQLSchema { name: "nodes", type: new GraphQLList(SkinType), resolve(source, _args, context) { - return assertNonNull(source.nodes(context)); + return assertNonNull(source.nodes(getUserContext(context))); } } }; @@ -753,7 +754,7 @@ export function getSchema(): GraphQLSchema { } }, resolve(_source, args, context) { - return queryFetch_archive_file_by_md5Resolver(args.md5, context); + return queryFetch_archive_file_by_md5Resolver(args.md5, getUserContext(context)); } }, fetch_internet_archive_item_by_identifier: { @@ -767,7 +768,7 @@ export function getSchema(): GraphQLSchema { } }, resolve(_source, args, context) { - return queryFetch_internet_archive_item_by_identifierResolver(args.identifier, context); + return queryFetch_internet_archive_item_by_identifierResolver(args.identifier, getUserContext(context)); } }, fetch_skin_by_md5: { @@ -781,7 +782,7 @@ export function getSchema(): GraphQLSchema { } }, resolve(_source, args, context) { - return queryFetch_skin_by_md5Resolver(args.md5, context); + return queryFetch_skin_by_md5Resolver(args.md5, getUserContext(context)); } }, fetch_tweet_by_url: { @@ -795,7 +796,7 @@ export function getSchema(): GraphQLSchema { } }, resolve(_source, args, context) { - return queryFetch_tweet_by_urlResolver(args.url, context); + return queryFetch_tweet_by_urlResolver(args.url, getUserContext(context)); } }, me: { @@ -837,7 +838,7 @@ export function getSchema(): GraphQLSchema { } }, resolve(_source, args, context) { - return queryNodeResolver(args.id, context); + return queryNodeResolver(args.id, getUserContext(context)); } }, search_skins: { @@ -861,7 +862,7 @@ export function getSchema(): GraphQLSchema { } }, resolve(_source, args, context) { - return assertNonNull(querySearch_skinsResolver(args, context)); + return assertNonNull(querySearch_skinsResolver(args, getUserContext(context))); } }, skin_to_review: { @@ -869,7 +870,7 @@ export function getSchema(): GraphQLSchema { name: "skin_to_review", type: SkinType, resolve(_source, _args, context) { - return querySkin_to_reviewResolver(context); + return querySkin_to_reviewResolver(getUserContext(context)); } }, skins: { @@ -943,7 +944,7 @@ export function getSchema(): GraphQLSchema { } }, resolve(_source, args, context) { - return assertNonNull(queryUpload_statusesResolver(args.ids, context)); + return assertNonNull(queryUpload_statusesResolver(args.ids, getUserContext(context))); } }, upload_statuses_by_md5: { @@ -958,7 +959,7 @@ export function getSchema(): GraphQLSchema { } }, resolve(_source, args, context) { - return assertNonNull(queryUpload_statuses_by_md5Resolver(args, context)); + return assertNonNull(queryUpload_statuses_by_md5Resolver(args.md5s, getUserContext(context))); } } }; @@ -1025,7 +1026,7 @@ export function getSchema(): GraphQLSchema { } }, resolve(source, args, context) { - return assertNonNull(source.get_upload_urls(args, context)); + return assertNonNull(source.get_upload_urls(args.files, getUserContext(context))); } }, report_skin_uploaded: { @@ -1043,7 +1044,7 @@ export function getSchema(): GraphQLSchema { } }, resolve(source, args, context) { - return assertNonNull(source.report_skin_uploaded(args, context)); + return assertNonNull(source.report_skin_uploaded(args.id, args.md5, context)); } } }; diff --git a/packages/skin-database/data/ArchiveFileModel.ts b/packages/skin-database/data/ArchiveFileModel.ts index 4bc9e61b..1a75b722 100644 --- a/packages/skin-database/data/ArchiveFileModel.ts +++ b/packages/skin-database/data/ArchiveFileModel.ts @@ -153,7 +153,7 @@ export default class ArchiveFileModel { */ export async function fetch_archive_file_by_md5( md5: string, - { ctx }: Ctx + ctx: UserContext ): Promise { return ArchiveFileModel.fromFileMd5(ctx, md5); } diff --git a/packages/skin-database/data/IaItemModel.ts b/packages/skin-database/data/IaItemModel.ts index f171a494..e3bdf6a5 100644 --- a/packages/skin-database/data/IaItemModel.ts +++ b/packages/skin-database/data/IaItemModel.ts @@ -222,7 +222,7 @@ export default class IaItemModel { */ export async function fetch_internet_archive_item_by_identifier( identifier: string, - { ctx }: Ctx + ctx: UserContext ): Promise { return IaItemModel.fromIdentifier(ctx, identifier); } diff --git a/packages/skin-database/data/TweetModel.ts b/packages/skin-database/data/TweetModel.ts index 0835a651..1f7d57b1 100644 --- a/packages/skin-database/data/TweetModel.ts +++ b/packages/skin-database/data/TweetModel.ts @@ -112,7 +112,7 @@ export default class TweetModel { */ export async function fetch_tweet_by_url( url: string, - { ctx }: Ctx + ctx: UserContext ): Promise { return TweetModel.fromAnything(ctx, url); } diff --git a/packages/skin-database/package.json b/packages/skin-database/package.json index 45929c5e..d03c58f0 100644 --- a/packages/skin-database/package.json +++ b/packages/skin-database/package.json @@ -23,7 +23,6 @@ "fast-xml-parser": "^4.2.2", "graphql": "^16.8.1", "graphql-http": "^1.22.1", - "grats": "^0.0.30", "imagemin": "^7.0.0", "imagemin-optipng": "^7.0.0", "knex": "^0.21.1", @@ -68,7 +67,7 @@ "@types/supertest": "^2.0.10", "@typescript-eslint/eslint-plugin": "^7.1.0", "@typescript-eslint/parser": "^7.1.0", - "grats": "^0.0.25", + "grats": "^0.0.31", "supertest": "^6.0.1", "typescript": "^5.3.3" }, diff --git a/yarn.lock b/yarn.lock index 02dfe152..ce5a669f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -15144,10 +15144,10 @@ graphql@^16.9.0: resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.10.0.tgz#24c01ae0af6b11ea87bf55694429198aaa8e220c" integrity sha512-AjqGKbDGUFRKIRCP9tCKiIGHyriz2oHEbPIbEtcSLSs4YjReZOIPQQWek4+6hjw62H9QShXHyaGivGiYVLeYFQ== -grats@^0.0.30: - version "0.0.30" - resolved "https://registry.yarnpkg.com/grats/-/grats-0.0.30.tgz#42d048d9d651a4873d741ad38f5b41c5b399719f" - integrity sha512-F+DBYBQHyOoUVA1jH8oAzz5hQPlZSgAfGvdbfo22N5s+1Ae3EXnF5NtcSPbmHPeWhIQ6D+Lo/VHrkNWayVcJpA== +grats@^0.0.31: + version "0.0.31" + resolved "https://registry.yarnpkg.com/grats/-/grats-0.0.31.tgz#f094786584a0f2fb345b38e6c37330d3f4f391cd" + integrity sha512-nTxRZYWgi+s8xj06QfcqtZ4nReXKyZhYHd9+9pLLthorvBSr4hbHBdl5L9HpHBqaxatWx98I6wdS5+8c+FQuxA== dependencies: commander "^10.0.0" graphql "^16.9.0"