add gh app

This commit is contained in:
2026-04-03 15:17:00 -04:00
parent 5315f1b188
commit 936000b32a
2 changed files with 101 additions and 0 deletions

27
functions/api/api.ts Normal file
View File

@@ -0,0 +1,27 @@
export async function onRequest(context: any) {
const {
request, // same as existing Worker API
env, // same as existing Worker API
} = context;
const client_id = (env as any).GITHUB_CLIENT_ID;
try {
const url = new URL(request.url);
const redirectUrl = new URL('https://github.com/login/oauth/authorize');
redirectUrl.searchParams.set('client_id', client_id);
redirectUrl.searchParams.set('redirect_uri', url.origin + '/api/callback');
redirectUrl.searchParams.set('scope', 'repo user');
redirectUrl.searchParams.set(
'state',
crypto.getRandomValues(new Uint8Array(12)).join(''),
);
return Response.redirect(redirectUrl.href, 301);
} catch (error: any) {
console.error(error);
return new Response(error.message, {
status: 500,
});
}
}

74
functions/api/callback.ts Normal file
View File

@@ -0,0 +1,74 @@
function renderBody(status: string, content: any) {
const html = `
<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>
`;
const blob = new Blob([html]);
return blob;
}
export async function onRequest(context: any) {
const {
request, // same as existing Worker API
env, // same as existing Worker API
} = context;
const client_id = env.GITHUB_CLIENT_ID;
const client_secret = env.GITHUB_CLIENT_SECRET;
try {
const url = new URL(request.url);
const code = url.searchParams.get('code');
const response = await fetch(
'https://github.com/login/oauth/access_token',
{
method: 'POST',
headers: {
'content-type': 'application/json',
'user-agent': 'cloudflare-functions-github-oauth-login-demo',
'accept': 'application/json',
},
body: JSON.stringify({ client_id, client_secret, code }),
},
);
const result = (await response.json()) as any;
if (result.error) {
return new Response(renderBody('error', result), {
headers: {
'content-type': 'text/html;charset=UTF-8',
},
status: 401
});
}
const token = result.access_token;
const provider = 'github';
const responseBody = renderBody('success', {
token,
provider,
});
return new Response(responseBody, {
headers: {
'content-type': 'text/html;charset=UTF-8',
},
status: 200
});
} catch (error: any) {
console.error(error);
return new Response(error.message, {
headers: {
'content-type': 'text/html;charset=UTF-8',
},
status: 500,
});
}
}