From 25bd4467c1f7219d740bd8f6b6f4a528f82ffa2a Mon Sep 17 00:00:00 2001 From: Oliver Barnwell Date: Sat, 27 Apr 2024 00:33:52 +0100 Subject: [PATCH] setup oauth flow via github for decap --- .gitignore | 2 + public/admin/config.yml | 3 ++ public/admin/index.html | 13 ----- src/pages/api/admin.page.tsx | 23 +++++++++ src/pages/api/decap-oauth/callback.page.ts | 59 ++++++++++++++++++++++ src/pages/api/decap-oauth/config.ts | 5 ++ src/pages/api/decap-oauth/index.page.ts | 6 +++ 7 files changed, 98 insertions(+), 13 deletions(-) delete mode 100644 public/admin/index.html create mode 100644 src/pages/api/admin.page.tsx create mode 100644 src/pages/api/decap-oauth/callback.page.ts create mode 100644 src/pages/api/decap-oauth/config.ts create mode 100644 src/pages/api/decap-oauth/index.page.ts diff --git a/.gitignore b/.gitignore index f70c4d540..3c497fef9 100644 --- a/.gitignore +++ b/.gitignore @@ -50,3 +50,5 @@ generated # DecapCMS out/ + +certificates \ No newline at end of file diff --git a/public/admin/config.yml b/public/admin/config.yml index 6936b1ce7..45a4cc645 100644 --- a/public/admin/config.yml +++ b/public/admin/config.yml @@ -1,6 +1,9 @@ backend: name: github repo: public-convenience-ltd/toiletmap + site_domain: toiletmap.org.uk + base_url: https://toiletmap.org.uk + auth_endpoint: api/decap-oauth site_url: https://toiletmap.org.uk/ display_url: https://toiletmap.org.uk/ publish_mode: editorial_workflow diff --git a/public/admin/index.html b/public/admin/index.html deleted file mode 100644 index 2bf7314aa..000000000 --- a/public/admin/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - Content Manager - - - - - - - diff --git a/src/pages/api/admin.page.tsx b/src/pages/api/admin.page.tsx new file mode 100644 index 000000000..97232ba49 --- /dev/null +++ b/src/pages/api/admin.page.tsx @@ -0,0 +1,23 @@ +import { NextApiRequest, NextApiResponse } from 'next'; + +async function handler(req: NextApiRequest, res: NextApiResponse) { + res.setHeader('Content-Type', 'text/html'); + return res.send(` + + + + + + + + Content Manager + + + + + + + `); +} + +export default handler; diff --git a/src/pages/api/decap-oauth/callback.page.ts b/src/pages/api/decap-oauth/callback.page.ts new file mode 100644 index 000000000..db7370707 --- /dev/null +++ b/src/pages/api/decap-oauth/callback.page.ts @@ -0,0 +1,59 @@ +import { NextApiRequest, NextApiResponse } from 'next'; +import { clientId, clientSecret, tokenUrl } from './config'; + +export default async function handler( + req: NextApiRequest, + res: NextApiResponse, +) { + const data = { + code: req.query?.code as string, + client_id: clientId, + client_secret: clientSecret, + }; + + try { + const accessTokenResponse = await fetch(tokenUrl, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + }, + body: JSON.stringify(data), + }); + + if (!accessTokenResponse.ok) { + throw new Error( + `Failed to fetch access token: ${accessTokenResponse.statusText}`, + ); + } + + const body = await accessTokenResponse.json(); + + const authContent = { + token: body.access_token, + provider: 'github', + }; + + const script = ` + + `; + + res.setHeader('Content-Type', 'text/html'); + return res.send(script); + } catch (err) { + console.log(err); + return res.redirect('/?error=decap_oauth_error'); + } +} diff --git a/src/pages/api/decap-oauth/config.ts b/src/pages/api/decap-oauth/config.ts new file mode 100644 index 000000000..3739587b7 --- /dev/null +++ b/src/pages/api/decap-oauth/config.ts @@ -0,0 +1,5 @@ +export const clientId = process.env.DECAP_OAUTH_GITHUB_CLIENT_ID; +export const clientSecret = process.env.DECAP_OAUTH_GITHUB_CLIENT_SECRET; + +export const authUrl = `https://github.com/login/oauth/authorize?client_id=${clientId}&scope=repo,user`; +export const tokenUrl = 'https://github.com/login/oauth/access_token'; diff --git a/src/pages/api/decap-oauth/index.page.ts b/src/pages/api/decap-oauth/index.page.ts new file mode 100644 index 000000000..582b73a56 --- /dev/null +++ b/src/pages/api/decap-oauth/index.page.ts @@ -0,0 +1,6 @@ +import { authUrl } from './config'; +import type { NextApiRequest, NextApiResponse } from 'next'; + +export default function handler(_: NextApiRequest, res: NextApiResponse) { + res.redirect(authUrl); +}