Skip to content
This repository has been archived by the owner on Dec 19, 2024. It is now read-only.

fix: live admin page authenticates with github #87

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
30 changes: 30 additions & 0 deletions api/_lib/oauth2.ts
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can probably move this code into the src directory. I think this folder was left over from the next template

Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import * as simpleOauthModule from "simple-oauth2"

export const create = () =>
simpleOauthModule.create({
client: {
id: process.env.OAUTH_CLIENT_ID || "",
secret: process.env.OAUTH_CLIENT_SECRET || "",
},
auth: {
tokenHost: `https://github.com`,
tokenPath: `/login/oauth/access_token`,
authorizePath: `/login/oauth/authorize`,
},
})

export const renderBody = (status: string, content: object) => `
<script>
const receiveMessage = (message) => {
window.opener.postMessage(
'authorization:github:${status}:${JSON.stringify(content)}',
message.origin
);

window.removeEventListener("message", receiveMessage, false);
}
window.addEventListener("message", receiveMessage, false);

window.opener.postMessage("authorizing:github", "*");
</script>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this needs to go in the auth.astro page

`
9 changes: 7 additions & 2 deletions astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,16 @@ import { defineConfig } from "astro/config";
import mdx from "@astrojs/mdx";
import sitemap from "@astrojs/sitemap";
import tailwind from "@astrojs/tailwind";

import react from "@astrojs/react";

import node from "@astrojs/node";

// https://astro.build/config
export default defineConfig({
site: "https://example.com",
integrations: [mdx(), sitemap(), tailwind(), react()]
output: "hybrid",
integrations: [mdx(), sitemap(), tailwind(), react()],
adapter: node({
mode: "standalone"
})
Comment on lines +12 to +16
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is probably why firebase is upset

});
127 changes: 127 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"dependencies": {
"@astrojs/check": "^0.5.3",
"@astrojs/mdx": "^2.1.1",
"@astrojs/node": "^8.3.3",
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What did you need node for?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Astro requires an ssr adapter in order to enable server side rendering : https://docs.astro.build/en/guides/server-side-rendering

"@astrojs/react": "^3.1.0",
"@astrojs/rss": "^4.0.5",
"@astrojs/sitemap": "^3.0.5",
Expand All @@ -36,11 +37,13 @@
"react-dom": "^18.2.0",
"react-hook-form": "^7.51.3",
"react-select": "^5.8.0",
"simple-oauth2": "2.5.2",
"tailwindcss": "^3.4.1",
"typescript": "^5.3.3"
},
"devDependencies": {
"@brown-ccv/eslint-config": "^0.3.0",
"@types/simple-oauth2": "^2.5.2",
"eslint": "^8.56.0",
"eslint-plugin-astro": "^0.31.4",
"prettier": "^3.2.5",
Expand Down
3 changes: 2 additions & 1 deletion public/admin/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ local_backend: true
backend:
name: github
repo: brown-ccv/mmp
base_url: /
base_url: https://mmp-site-b1c9b.web.app/
auth_endpoint: api/auth
media_folder: public/images
media_library:
max_file_size: 734003200
Expand Down
8 changes: 8 additions & 0 deletions src/pages/api/auth.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
import Layout from "../../layouts/Layout.astro"
import { GET } from "./auth"

const auth = await GET(Astro.url.origin)
---

<Layout title="Authenticate" description="" />
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you need this if the thing is calling GET?

16 changes: 16 additions & 0 deletions src/pages/api/auth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import crypto from "crypto"
import { create } from "../../../api/_lib/oauth2.ts"

export const prerender = false

export const GET = (host: string) => {
const randomString = () => crypto.randomBytes(4).toString(`hex`)
const oauth2 = create()

const url = oauth2.authorizationCode.authorizeURL({
redirect_uri: `${host}/api/callback`,
scope: `repo,user`,
state: randomString(),
})
return Response.redirect(url, 301)
}
8 changes: 8 additions & 0 deletions src/pages/api/callback.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
import Layout from "../../layouts/Layout.astro"
import { GetCallback } from "./callback"

const callback = GetCallback(Astro.request, Astro.url.origin)
---

<Layout title="Callback" description="" />
26 changes: 26 additions & 0 deletions src/pages/api/callback.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { create, renderBody } from "../../../api/_lib/oauth2.ts"

export const prerender = false

export const GetCallback = async (req: Request, host: string) => {
const params = new URLSearchParams(req.url)
const code = params.get("code") || ""
const oauth2 = create()

try {
const accessToken = await oauth2.authorizationCode.getToken({
code,
redirect_uri: `${host}/api/callback`,
})
const { token } = oauth2.accessToken.create(accessToken)
return new Response(
renderBody("success", {
token: token.access_token,
provider: "github",
}),
{ status: 200 }
)
} catch (e: any) {
return new Response(renderBody("error", e.message), { status: 200 })
}
}