Newer
Older
import { prisma } from "../lib/prisma";
import { OpenID } from "../lib/oidc";
import { TokenSet, errors as OIDC_Errors } from "openid-client";
const app = Router();
app.get("/login", (req, res) => {
res.redirect(
OpenID.client.authorizationUrl({
prompt: "consent",
scope: "openid instance",
})
);
// TODO: return proper UIs for errors intead of raw JSON (#35)
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
let exchange: TokenSet;
try {
const params = OpenID.client.callbackParams(req);
exchange = await OpenID.client.callback(OpenID.getRedirectUrl(), params);
} catch (e) {
if (e instanceof OIDC_Errors.RPError) {
// client error
res.status(400).json({
success: false,
error: e.name,
error_description: e.message,
});
return;
}
if (e instanceof OIDC_Errors.OPError) {
// server error
switch (e.error) {
case "invalid_client":
// this happens when we're configured with invalid credentials
Logger.error(
"OpenID is improperly configured. Cannot exchange tokens, do I have valid credetials?"
);
res.status(500).json({
success: false,
error: "internal server error",
error_description: "I'm misconfigured.",
});
return;
case "invalid_grant":
res.status(400).json({
success: false,
error: "invalid_grant",
error_description: "retry /api/login",
});
return;
}
res.status(400).json({
success: false,
error: e.error,
error_description: e.error_description,
});
return;
}
res.status(500).json({
success: false,
error: "unknown error",
error_description: "report this",
});
return;
}
if (!exchange || !exchange.access_token) {
return res.status(400).json({
success: false,
error: "FAILED TOKEN EXCHANGE",
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("@");
await prisma.user.upsert({
where: {
sub: [username, hostname].join("@"),
},
update: {},
create: {
sub: [username, hostname].join("@"),
},
});
req.session.user = {
service: {