diff --git a/database/entities/Application.ts b/database/entities/Application.ts index 8268c14a..5f23c9ae 100644 --- a/database/entities/Application.ts +++ b/database/entities/Application.ts @@ -42,6 +42,7 @@ export class Application extends BaseEntity { where: { access_token: token, }, + relations: ["application"], }); return dbToken?.application || null; diff --git a/server/api/[username]/inbox/index.ts b/server/api/[username]/inbox/index.ts index d6f639fa..54febea9 100644 --- a/server/api/[username]/inbox/index.ts +++ b/server/api/[username]/inbox/index.ts @@ -68,7 +68,6 @@ export default async ( const activity = await RawActivity.addIfNotExists(body, object); if (activity instanceof Response) { - console.log(await activity.text()); return activity; } diff --git a/server/api/api/v1/apps/verify_credentials/index.ts b/server/api/api/v1/apps/verify_credentials/index.ts new file mode 100644 index 00000000..bfdd6766 --- /dev/null +++ b/server/api/api/v1/apps/verify_credentials/index.ts @@ -0,0 +1,28 @@ +import { getUserByToken } from "@auth"; +import { errorResponse, jsonResponse } from "@response"; +import { Application } from "~database/entities/Application"; + +/** + * Returns OAuth2 credentials + */ +export default async (req: Request): Promise => { + // Check auth token + const token = req.headers.get("Authorization")?.split(" ")[1] || null; + + if (!token) + return errorResponse("This method requires an authenticated user", 422); + + const user = await getUserByToken(token); + const application = await Application.getFromToken(token); + + if (!user) return errorResponse("Unauthorized", 401); + if (!application) return errorResponse("Unauthorized", 401); + + return jsonResponse({ + name: application.name, + website: application.website, + vapid_key: application.vapid_key, + redirect_uris: application.redirect_uris, + scopes: application.scopes, + }); +}; diff --git a/tests/oauth.test.ts b/tests/oauth.test.ts index 023f024f..6b0e7cfb 100644 --- a/tests/oauth.test.ts +++ b/tests/oauth.test.ts @@ -10,6 +10,7 @@ const config = getConfig(); let client_id: string; let client_secret: string; let code: string; +let token: Token; beforeAll(async () => { if (!AppDataSource.isInitialized) await AppDataSource.initialize(); @@ -116,6 +117,34 @@ describe("POST /oauth/token/", () => { scope: "read write", created_at: expect.any(String), }); + + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access + token = json; + }); +}); + +describe("GET /api/v1/apps/verify_credentials", () => { + test("should return the authenticated application's credentials", async () => { + const response = await fetch( + `${config.http.base_url}:${config.http.port}/api/v1/apps/verify_credentials`, + { + method: "GET", + headers: { + Authorization: `Bearer ${token.access_token}`, + "Content-Type": "application/json", + }, + } + ); + + expect(response.status).toBe(200); + expect(response.headers.get("content-type")).toBe("application/json"); + + const credentials: Partial = await response.json(); + + expect(credentials.name).toBe("Test Application"); + expect(credentials.website).toBe("https://example.com"); + expect(credentials.redirect_uris).toBe("https://example.com"); + expect(credentials.scopes).toBe("read write"); }); });