Skip to content

Commit 7a36846

Browse files
feat(indiekit): client metadata endpoint
1 parent dc4ed25 commit 7a36846

File tree

4 files changed

+45
-2
lines changed

4 files changed

+45
-2
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
export const get = async (request, response) => {
2+
const { name: client_name, url: client_uri } = request.app.locals.application;
3+
const { href: client_id } = new URL("id", client_uri);
4+
const { href: logo_uri } = new URL("assets/app-icon-512-any.png", client_uri);
5+
6+
response.set("Cache-Control", "public, max-age=604800"); // 7 days
7+
return response.type("application/json").json({
8+
client_id,
9+
client_name,
10+
client_uri,
11+
logo_uri,
12+
});
13+
};

packages/indiekit/lib/indieauth.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -79,14 +79,16 @@ export const IndieAuth = class {
7979
return async (request, response) => {
8080
try {
8181
const { application } = request.app.locals;
82-
this.clientId = getCanonicalUrl(application.url);
82+
const applicationUrl = getCanonicalUrl(application.url);
83+
const { href: clientId } = new URL("id", applicationUrl);
84+
const { href: callbackUrl } = new URL("session/auth", applicationUrl);
8385

84-
const callbackUrl = `${application.url}/session/auth`;
8586
const { redirect } = request.query;
8687
this.redirectUri = redirect
8788
? `${callbackUrl}?redirect=${redirect}`
8889
: `${callbackUrl}`;
8990

91+
this.clientId = clientId;
9092
const state = generateState(this.clientId, this.iv);
9193
const authUrl = await this.getAuthUrl(
9294
application.authorizationEndpoint,

packages/indiekit/lib/routes.js

+4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import express from "express";
33
import { assetsPath } from "@indiekit/frontend";
44
import rateLimit from "express-rate-limit";
55
import * as assetsController from "./controllers/assets.js";
6+
import * as clientController from "./controllers/client.js";
67
import * as feedController from "./controllers/feed.js";
78
import * as homepageController from "./controllers/homepage.js";
89
import * as manifestController from "./controllers/manifest.js";
@@ -70,6 +71,9 @@ export const routes = (indiekitConfig) => {
7071
// Web App Manifest
7172
router.get("/app.webmanifest", manifestController.get);
7273

74+
// Client metadata
75+
router.get("/id", clientController.get);
76+
7377
// Session
7478
router.get("/session/login", limit, sessionController.login);
7579
router.post("/session/login", limit, indieauth.login());
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { strict as assert } from "node:assert";
2+
import { after, describe, it } from "node:test";
3+
import supertest from "supertest";
4+
import { testServer } from "@indiekit-test/server";
5+
6+
const server = await testServer();
7+
const request = supertest.agent(server);
8+
9+
describe("indiekit GET /id", () => {
10+
it("Returns client metadata", async () => {
11+
const result = await request.get("/id");
12+
13+
assert.equal(result.status, 200);
14+
assert.equal(result.type, "application/json");
15+
assert.equal(result.body.client_id.includes("/id"), true);
16+
assert.equal(result.body.client_name, "Test configuration");
17+
assert.ok(result.body.client_uri);
18+
assert.equal(result.body.logo_uri.includes("app-icon-512-any.png"), true);
19+
});
20+
21+
after(() => {
22+
server.close(() => process.exit(0));
23+
});
24+
});

0 commit comments

Comments
 (0)