Skip to content
api.ts 1.61 KiB
Newer Older
Grant's avatar
Grant committed
import { Router } from "express";
import { prisma } from "./lib/prisma";
Grant's avatar
Grant committed
import { OpenID } from "./lib/oidc";
Grant's avatar
Grant committed

const app = Router();

app.get("/me", (req, res) => {
  res.json(req.session);
});

Grant's avatar
Grant committed
app.get("/login", (req, res) => {
Grant's avatar
Grant committed
  res.redirect(
    OpenID.client.authorizationUrl({
      prompt: "consent",
      scope: "openid instance",
    })
  );
Grant's avatar
Grant committed
});

Grant's avatar
Grant committed
// TODO: logout endpoint
Grant's avatar
Grant committed

Grant's avatar
Grant committed
app.get("/callback", async (req, res) => {
  // const { code } = req.query;
Grant's avatar
Grant committed

Grant's avatar
Grant committed
  const params = OpenID.client.callbackParams(req);
  const exchange = await OpenID.client.callback(
    OpenID.getRedirectUrl(),
    params
  );
  if (!exchange || !exchange.access_token) {
    return res.status(400).json({
      success: false,
      error: "FAILED TOKEN EXCHANGE",
Grant's avatar
Grant committed
  const whoami = await OpenID.client.userinfo<{
    instance: {
      software: {
        name: string;
        version: string;
        logo_uri?: string;
        repository?: string;
        homepage?: string;
      };
      instance: {
        logo_uri?: string;
        banner_uri?: string;
        name?: string;
      };
    };
  }>(exchange.access_token);

  const [username, hostname] = whoami.sub.split("@");
Grant's avatar
Grant committed

  await prisma.user.upsert({
    where: {
      sub: [username, hostname].join("@"),
    },
    update: {},
    create: {
      sub: [username, hostname].join("@"),
    },
  });

  req.session.user = {
    service: {
Grant's avatar
Grant committed
      ...whoami.instance,
Grant's avatar
Grant committed
      instance: {
Grant's avatar
Grant committed
        ...whoami.instance.instance,
Grant's avatar
Grant committed
        hostname,
      },
    },
    user: {
Grant's avatar
Grant committed
      picture_url: whoami.picture,
Grant's avatar
Grant committed
      username,
    },
  };
  req.session.save();
  res.redirect("/");
});

export default app;