1import { issuer } from "npm:@openauthjs/openauth@^0.3.7";
2import { GithubProvider } from "npm:/@openauthjs/openauth@^0.3.7/provider/github";
3import { Octokit } from "npm:octokit@^4.1.0";
4import { THEME_SST } from "npm:/@openauthjs/openauth@^0.3.7/ui/theme";
5import { MemoryStorage } from "npm:/@openauthjs/openauth@^0.3.7/storage/memory";
6import { createSubjects } from "npm:@openauthjs/openauth@^0.3.7/subject";
7import { object, string } from "npm:valibot@1.0.0"
8import { oicd } from "jsr:@pomdtr/openauth-oidc@0.1.1";
9
10const { GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET } = Deno.env.toObject();
11if (!GITHUB_CLIENT_ID || !GITHUB_CLIENT_SECRET) {
12 throw new Error("Missing GITHUB_CLIENT_ID or GITHUB_CLIENT_SECRET");
13}
14
15const storage = MemoryStorage({
16 persist: "./data/db.json",
17})
18
19const iss = issuer({
20 theme: THEME_SST,
21 providers: {
22 github: GithubProvider({
23 clientID: GITHUB_CLIENT_ID,
24 clientSecret: GITHUB_CLIENT_SECRET,
25 scopes: ["user:email"],
26 }),
27 },
28 storage,
29 subjects: createSubjects({
30 user: object({
31 email: string(),
32 })
33 }),
34 success: async (res, input) => {
35 switch (input.provider) {
36 case "github": {
37 const octokit = new Octokit({
38 auth: input.tokenset.access,
39 });
40
41 const emails = await octokit.rest.users
42 .listEmailsForAuthenticatedUser();
43 const email = emails.data.find((email) => email.primary)
44 ?.email;
45
46 if (!email) throw new Error("No primary email");
47 return res.subject("user", {
48 email,
49 });
50 }
51 }
52 },
53})
54
55
56export default oicd(iss, storage)