Skip to content

Commit

Permalink
feat(indiekit): client metadata endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
paulrobertlloyd committed Aug 25, 2024
1 parent dc4ed25 commit 7a36846
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 2 deletions.
13 changes: 13 additions & 0 deletions packages/indiekit/lib/controllers/client.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export const get = async (request, response) => {
const { name: client_name, url: client_uri } = request.app.locals.application;
const { href: client_id } = new URL("id", client_uri);
const { href: logo_uri } = new URL("assets/app-icon-512-any.png", client_uri);

response.set("Cache-Control", "public, max-age=604800"); // 7 days
return response.type("application/json").json({
client_id,
client_name,
client_uri,
logo_uri,
});
};
6 changes: 4 additions & 2 deletions packages/indiekit/lib/indieauth.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,14 +79,16 @@ export const IndieAuth = class {
return async (request, response) => {
try {
const { application } = request.app.locals;
this.clientId = getCanonicalUrl(application.url);
const applicationUrl = getCanonicalUrl(application.url);
const { href: clientId } = new URL("id", applicationUrl);
const { href: callbackUrl } = new URL("session/auth", applicationUrl);

const callbackUrl = `${application.url}/session/auth`;
const { redirect } = request.query;
this.redirectUri = redirect
? `${callbackUrl}?redirect=${redirect}`
: `${callbackUrl}`;

this.clientId = clientId;
const state = generateState(this.clientId, this.iv);
const authUrl = await this.getAuthUrl(
application.authorizationEndpoint,
Expand Down
4 changes: 4 additions & 0 deletions packages/indiekit/lib/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import express from "express";
import { assetsPath } from "@indiekit/frontend";
import rateLimit from "express-rate-limit";
import * as assetsController from "./controllers/assets.js";
import * as clientController from "./controllers/client.js";
import * as feedController from "./controllers/feed.js";
import * as homepageController from "./controllers/homepage.js";
import * as manifestController from "./controllers/manifest.js";
Expand Down Expand Up @@ -70,6 +71,9 @@ export const routes = (indiekitConfig) => {
// Web App Manifest
router.get("/app.webmanifest", manifestController.get);

// Client metadata
router.get("/id", clientController.get);

// Session
router.get("/session/login", limit, sessionController.login);
router.post("/session/login", limit, indieauth.login());
Expand Down
24 changes: 24 additions & 0 deletions packages/indiekit/test/integration/200-client.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { strict as assert } from "node:assert";
import { after, describe, it } from "node:test";
import supertest from "supertest";
import { testServer } from "@indiekit-test/server";

const server = await testServer();
const request = supertest.agent(server);

describe("indiekit GET /id", () => {
it("Returns client metadata", async () => {
const result = await request.get("/id");

assert.equal(result.status, 200);
assert.equal(result.type, "application/json");
assert.equal(result.body.client_id.includes("/id"), true);
assert.equal(result.body.client_name, "Test configuration");
assert.ok(result.body.client_uri);
assert.equal(result.body.logo_uri.includes("app-icon-512-any.png"), true);
});

after(() => {
server.close(() => process.exit(0));
});
});

0 comments on commit 7a36846

Please sign in to comment.