First upload version 0.0.1

This commit is contained in:
Neyra
2026-02-05 15:27:49 +08:00
commit 8e9b7201ed
4182 changed files with 593136 additions and 0 deletions

View File

@@ -0,0 +1,15 @@
function addEventHandler(state, eventName, eventHandler) {
if (Array.isArray(eventName)) {
for (const singleEventName of eventName) {
addEventHandler(state, singleEventName, eventHandler);
}
return;
}
if (!state.eventHandlers[eventName]) {
state.eventHandlers[eventName] = [];
}
state.eventHandlers[eventName].push(eventHandler);
}
export {
addEventHandler
};

16
node_modules/@octokit/oauth-app/dist-src/emit-event.js generated vendored Normal file
View File

@@ -0,0 +1,16 @@
async function emitEvent(state, context) {
const { name, action } = context;
if (state.eventHandlers[`${name}.${action}`]) {
for (const eventHandler of state.eventHandlers[`${name}.${action}`]) {
await eventHandler(context);
}
}
if (state.eventHandlers[name]) {
for (const eventHandler of state.eventHandlers[name]) {
await eventHandler(context);
}
}
}
export {
emitEvent
};

131
node_modules/@octokit/oauth-app/dist-src/index.js generated vendored Normal file
View File

@@ -0,0 +1,131 @@
import { createOAuthAppAuth } from "@octokit/auth-oauth-app";
import { VERSION } from "./version.js";
import { addEventHandler } from "./add-event-handler.js";
import { OAuthAppOctokit } from "./oauth-app-octokit.js";
import {
getUserOctokitWithState
} from "./methods/get-user-octokit.js";
import {
getWebFlowAuthorizationUrlWithState
} from "./methods/get-web-flow-authorization-url.js";
import {
createTokenWithState
} from "./methods/create-token.js";
import {
checkTokenWithState
} from "./methods/check-token.js";
import {
resetTokenWithState
} from "./methods/reset-token.js";
import {
refreshTokenWithState
} from "./methods/refresh-token.js";
import {
scopeTokenWithState
} from "./methods/scope-token.js";
import {
deleteTokenWithState
} from "./methods/delete-token.js";
import {
deleteAuthorizationWithState
} from "./methods/delete-authorization.js";
import { handleRequest } from "./middleware/handle-request.js";
import { unknownRouteResponse } from "./middleware/unknown-route-response.js";
import { createNodeMiddleware } from "./middleware/node/index.js";
import { sendResponse } from "./middleware/node/send-response.js";
import { createWebWorkerHandler } from "./middleware/web-worker/index.js";
import { createAWSLambdaAPIGatewayV2Handler } from "./middleware/aws-lambda/api-gateway-v2.js";
class OAuthApp {
static VERSION = VERSION;
static defaults(defaults) {
const OAuthAppWithDefaults = class extends this {
constructor(...args) {
super({
...defaults,
...args[0]
});
}
};
return OAuthAppWithDefaults;
}
constructor(options) {
const Octokit = options.Octokit || OAuthAppOctokit;
this.type = options.clientType || "oauth-app";
const octokit = new Octokit({
authStrategy: createOAuthAppAuth,
auth: {
clientType: this.type,
clientId: options.clientId,
clientSecret: options.clientSecret
}
});
const state = {
clientType: this.type,
clientId: options.clientId,
clientSecret: options.clientSecret,
// @ts-expect-error defaultScopes not permitted for GitHub Apps
defaultScopes: options.defaultScopes || [],
allowSignup: options.allowSignup,
baseUrl: options.baseUrl,
redirectUrl: options.redirectUrl,
log: options.log,
Octokit,
octokit,
eventHandlers: {}
};
this.on = addEventHandler.bind(null, state);
this.octokit = octokit;
this.getUserOctokit = getUserOctokitWithState.bind(
null,
state
);
this.getWebFlowAuthorizationUrl = getWebFlowAuthorizationUrlWithState.bind(
null,
state
);
this.createToken = createTokenWithState.bind(
null,
state
);
this.checkToken = checkTokenWithState.bind(
null,
state
);
this.resetToken = resetTokenWithState.bind(
null,
state
);
this.refreshToken = refreshTokenWithState.bind(
null,
state
);
this.scopeToken = scopeTokenWithState.bind(
null,
state
);
this.deleteToken = deleteTokenWithState.bind(null, state);
this.deleteAuthorization = deleteAuthorizationWithState.bind(null, state);
}
// assigned during constructor
type;
on;
octokit;
getUserOctokit;
getWebFlowAuthorizationUrl;
createToken;
checkToken;
resetToken;
refreshToken;
scopeToken;
deleteToken;
deleteAuthorization;
}
export {
OAuthApp,
createAWSLambdaAPIGatewayV2Handler,
createNodeMiddleware,
createWebWorkerHandler,
handleRequest,
sendResponse as sendNodeResponse,
unknownRouteResponse
};

View File

@@ -0,0 +1,16 @@
import * as OAuthMethods from "@octokit/oauth-methods";
async function checkTokenWithState(state, options) {
const result = await OAuthMethods.checkToken({
// @ts-expect-error not worth the extra code to appease TS
clientType: state.clientType,
clientId: state.clientId,
clientSecret: state.clientSecret,
request: state.octokit.request,
...options
});
Object.assign(result.authentication, { type: "token", tokenType: "oauth" });
return result;
}
export {
checkTokenWithState
};

View File

@@ -0,0 +1,32 @@
import * as OAuthAppAuth from "@octokit/auth-oauth-app";
import { emitEvent } from "../emit-event.js";
async function createTokenWithState(state, options) {
const authentication = await state.octokit.auth({
type: "oauth-user",
...options
});
await emitEvent(state, {
name: "token",
action: "created",
token: authentication.token,
scopes: authentication.scopes,
authentication,
octokit: new state.Octokit({
authStrategy: OAuthAppAuth.createOAuthUserAuth,
auth: {
clientType: state.clientType,
clientId: state.clientId,
clientSecret: state.clientSecret,
token: authentication.token,
scopes: authentication.scopes,
refreshToken: authentication.refreshToken,
expiresAt: authentication.expiresAt,
refreshTokenExpiresAt: authentication.refreshTokenExpiresAt
}
})
});
return { authentication };
}
export {
createTokenWithState
};

View File

@@ -0,0 +1,47 @@
import * as OAuthMethods from "@octokit/oauth-methods";
import { createUnauthenticatedAuth } from "@octokit/auth-unauthenticated";
import { emitEvent } from "../emit-event.js";
async function deleteAuthorizationWithState(state, options) {
const optionsWithDefaults = {
clientId: state.clientId,
clientSecret: state.clientSecret,
request: state.octokit.request,
...options
};
const response = state.clientType === "oauth-app" ? await OAuthMethods.deleteAuthorization({
clientType: "oauth-app",
...optionsWithDefaults
}) : (
/* v8 ignore next 4 */
await OAuthMethods.deleteAuthorization({
clientType: "github-app",
...optionsWithDefaults
})
);
await emitEvent(state, {
name: "token",
action: "deleted",
token: options.token,
octokit: new state.Octokit({
authStrategy: createUnauthenticatedAuth,
auth: {
reason: `Handling "token.deleted" event. The access for the token has been revoked.`
}
})
});
await emitEvent(state, {
name: "authorization",
action: "deleted",
token: options.token,
octokit: new state.Octokit({
authStrategy: createUnauthenticatedAuth,
auth: {
reason: `Handling "authorization.deleted" event. The access for the app has been revoked.`
}
})
});
return response;
}
export {
deleteAuthorizationWithState
};

View File

@@ -0,0 +1,36 @@
import * as OAuthMethods from "@octokit/oauth-methods";
import { createUnauthenticatedAuth } from "@octokit/auth-unauthenticated";
import { emitEvent } from "../emit-event.js";
async function deleteTokenWithState(state, options) {
const optionsWithDefaults = {
clientId: state.clientId,
clientSecret: state.clientSecret,
request: state.octokit.request,
...options
};
const response = state.clientType === "oauth-app" ? await OAuthMethods.deleteToken({
clientType: "oauth-app",
...optionsWithDefaults
}) : (
/* v8 ignore next 4 */
await OAuthMethods.deleteToken({
clientType: "github-app",
...optionsWithDefaults
})
);
await emitEvent(state, {
name: "token",
action: "deleted",
token: options.token,
octokit: new state.Octokit({
authStrategy: createUnauthenticatedAuth,
auth: {
reason: `Handling "token.deleted" event. The access for the token has been revoked.`
}
})
});
return response;
}
export {
deleteTokenWithState
};

View File

@@ -0,0 +1,10 @@
function getOAuthClientCode() {
return `import { Octokit: Core } from "https://esm.sh/@octokit/core";
export const Octokit = Core.defaults({
oauth: {}
})`;
}
export {
getOAuthClientCode
};

View File

@@ -0,0 +1,29 @@
import { createOAuthUserAuth } from "@octokit/auth-oauth-user";
import { emitEvent } from "../emit-event.js";
async function getUserOctokitWithState(state, options) {
return state.octokit.auth({
type: "oauth-user",
...options,
async factory(options2) {
const octokit = new state.Octokit({
authStrategy: createOAuthUserAuth,
auth: options2
});
const authentication = await octokit.auth({
type: "get"
});
await emitEvent(state, {
name: "token",
action: "created",
token: authentication.token,
scopes: authentication.scopes,
authentication,
octokit
});
return octokit;
}
});
}
export {
getUserOctokitWithState
};

View File

@@ -0,0 +1,18 @@
import * as OAuthMethods from "@octokit/oauth-methods";
function getWebFlowAuthorizationUrlWithState(state, options) {
const optionsWithDefaults = {
clientId: state.clientId,
request: state.octokit.request,
...options,
allowSignup: state.allowSignup ?? options.allowSignup,
redirectUrl: options.redirectUrl ?? state.redirectUrl,
scopes: options.scopes ?? state.defaultScopes
};
return OAuthMethods.getWebFlowAuthorizationUrl({
clientType: state.clientType,
...optionsWithDefaults
});
}
export {
getWebFlowAuthorizationUrlWithState
};

View File

@@ -0,0 +1,40 @@
import * as OAuthMethods from "@octokit/oauth-methods";
import { emitEvent } from "../emit-event.js";
import { createOAuthUserAuth } from "@octokit/auth-oauth-user";
async function refreshTokenWithState(state, options) {
if (state.clientType === "oauth-app") {
throw new Error(
"[@octokit/oauth-app] app.refreshToken() is not supported for OAuth Apps"
);
}
const response = await OAuthMethods.refreshToken({
clientType: "github-app",
clientId: state.clientId,
clientSecret: state.clientSecret,
request: state.octokit.request,
refreshToken: options.refreshToken
});
const authentication = Object.assign(response.authentication, {
type: "token",
tokenType: "oauth"
});
await emitEvent(state, {
name: "token",
action: "refreshed",
token: response.authentication.token,
authentication,
octokit: new state.Octokit({
authStrategy: createOAuthUserAuth,
auth: {
clientType: state.clientType,
clientId: state.clientId,
clientSecret: state.clientSecret,
token: response.authentication.token
}
})
});
return { ...response, authentication };
}
export {
refreshTokenWithState
};

View File

@@ -0,0 +1,66 @@
import * as OAuthMethods from "@octokit/oauth-methods";
import { emitEvent } from "../emit-event.js";
import { createOAuthUserAuth } from "@octokit/auth-oauth-user";
async function resetTokenWithState(state, options) {
const optionsWithDefaults = {
clientId: state.clientId,
clientSecret: state.clientSecret,
request: state.octokit.request,
...options
};
if (state.clientType === "oauth-app") {
const response2 = await OAuthMethods.resetToken({
clientType: "oauth-app",
...optionsWithDefaults
});
const authentication2 = Object.assign(response2.authentication, {
type: "token",
tokenType: "oauth"
});
await emitEvent(state, {
name: "token",
action: "reset",
token: response2.authentication.token,
scopes: response2.authentication.scopes || void 0,
authentication: authentication2,
octokit: new state.Octokit({
authStrategy: createOAuthUserAuth,
auth: {
clientType: state.clientType,
clientId: state.clientId,
clientSecret: state.clientSecret,
token: response2.authentication.token,
scopes: response2.authentication.scopes
}
})
});
return { ...response2, authentication: authentication2 };
}
const response = await OAuthMethods.resetToken({
clientType: "github-app",
...optionsWithDefaults
});
const authentication = Object.assign(response.authentication, {
type: "token",
tokenType: "oauth"
});
await emitEvent(state, {
name: "token",
action: "reset",
token: response.authentication.token,
authentication,
octokit: new state.Octokit({
authStrategy: createOAuthUserAuth,
auth: {
clientType: state.clientType,
clientId: state.clientId,
clientSecret: state.clientSecret,
token: response.authentication.token
}
})
});
return { ...response, authentication };
}
export {
resetTokenWithState
};

View File

@@ -0,0 +1,40 @@
import * as OAuthMethods from "@octokit/oauth-methods";
import { createOAuthUserAuth } from "@octokit/auth-oauth-user";
import { emitEvent } from "../emit-event.js";
async function scopeTokenWithState(state, options) {
if (state.clientType === "oauth-app") {
throw new Error(
"[@octokit/oauth-app] app.scopeToken() is not supported for OAuth Apps"
);
}
const response = await OAuthMethods.scopeToken({
clientType: "github-app",
clientId: state.clientId,
clientSecret: state.clientSecret,
request: state.octokit.request,
...options
});
const authentication = Object.assign(response.authentication, {
type: "token",
tokenType: "oauth"
});
await emitEvent(state, {
name: "token",
action: "scoped",
token: response.authentication.token,
authentication,
octokit: new state.Octokit({
authStrategy: createOAuthUserAuth,
auth: {
clientType: state.clientType,
clientId: state.clientId,
clientSecret: state.clientSecret,
token: response.authentication.token
}
})
});
return { ...response, authentication };
}
export {
scopeTokenWithState
};

View File

@@ -0,0 +1,13 @@
function parseRequest(request) {
const { method } = request.requestContext.http;
let url = request.rawPath;
const { stage } = request.requestContext;
if (url.startsWith("/" + stage)) url = url.substring(stage.length + 1);
if (request.rawQueryString) url += "?" + request.rawQueryString;
const headers = request.headers;
const text = async () => request.body || "";
return { method, url, headers, text };
}
export {
parseRequest
};

View File

@@ -0,0 +1,10 @@
function sendResponse(octokitResponse) {
return {
statusCode: octokitResponse.status,
headers: octokitResponse.headers,
body: octokitResponse.text
};
}
export {
sendResponse
};

View File

@@ -0,0 +1,13 @@
import { parseRequest } from "./api-gateway-v2-parse-request.js";
import { sendResponse } from "./api-gateway-v2-send-response.js";
import { handleRequest } from "../handle-request.js";
function createAWSLambdaAPIGatewayV2Handler(app, options = {}) {
return async function(event) {
const request = parseRequest(event);
const response = await handleRequest(app, options, request);
return response ? sendResponse(response) : void 0;
};
}
export {
createAWSLambdaAPIGatewayV2Handler
};

View File

@@ -0,0 +1,240 @@
import { OAuthApp } from "../index.js";
import { unknownRouteResponse } from "./unknown-route-response.js";
async function handleRequest(app, { pathPrefix = "/api/github/oauth" }, request) {
let { pathname } = new URL(request.url, "http://localhost");
if (!pathname.startsWith(`${pathPrefix}/`)) {
return void 0;
}
if (request.method === "OPTIONS") {
return {
status: 200,
headers: {
"access-control-allow-origin": "*",
"access-control-allow-methods": "*",
"access-control-allow-headers": "Content-Type, User-Agent, Authorization"
}
};
}
pathname = pathname.slice(pathPrefix.length + 1);
const route = [request.method, pathname].join(" ");
const routes = {
getLogin: `GET login`,
getCallback: `GET callback`,
createToken: `POST token`,
getToken: `GET token`,
patchToken: `PATCH token`,
patchRefreshToken: `PATCH refresh-token`,
scopeToken: `POST token/scoped`,
deleteToken: `DELETE token`,
deleteGrant: `DELETE grant`
};
if (!Object.values(routes).includes(route)) {
return unknownRouteResponse(request);
}
let json;
try {
const text = await request.text();
json = text ? JSON.parse(text) : {};
} catch (error) {
return {
status: 400,
headers: {
"content-type": "application/json",
"access-control-allow-origin": "*"
},
text: JSON.stringify({
error: "[@octokit/oauth-app] request error"
})
};
}
const { searchParams } = new URL(request.url, "http://localhost");
const query = Object.fromEntries(searchParams);
const headers = request.headers;
try {
if (route === routes.getLogin) {
const authOptions = {};
if (query.state) {
Object.assign(authOptions, { state: query.state });
}
if (query.scopes) {
Object.assign(authOptions, { scopes: query.scopes.split(",") });
}
if (query.allowSignup) {
Object.assign(authOptions, {
allowSignup: query.allowSignup === "true"
});
}
if (query.redirectUrl) {
Object.assign(authOptions, { redirectUrl: query.redirectUrl });
}
const { url } = app.getWebFlowAuthorizationUrl(authOptions);
return { status: 302, headers: { location: url } };
}
if (route === routes.getCallback) {
if (query.error) {
throw new Error(
`[@octokit/oauth-app] ${query.error} ${query.error_description}`
);
}
if (!query.code) {
throw new Error('[@octokit/oauth-app] "code" parameter is required');
}
const {
authentication: { token: token2 }
} = await app.createToken({
code: query.code
});
return {
status: 200,
headers: {
"content-type": "text/html"
},
text: `<h1>Token created successfully</h1>
<p>Your token is: <strong>${token2}</strong>. Copy it now as it cannot be shown again.</p>`
};
}
if (route === routes.createToken) {
const { code, redirectUrl } = json;
if (!code) {
throw new Error('[@octokit/oauth-app] "code" parameter is required');
}
const result = await app.createToken({
code,
redirectUrl
});
delete result.authentication.clientSecret;
return {
status: 201,
headers: {
"content-type": "application/json",
"access-control-allow-origin": "*"
},
text: JSON.stringify(result)
};
}
if (route === routes.getToken) {
const token2 = headers.authorization?.substr("token ".length);
if (!token2) {
throw new Error(
'[@octokit/oauth-app] "Authorization" header is required'
);
}
const result = await app.checkToken({
token: token2
});
delete result.authentication.clientSecret;
return {
status: 200,
headers: {
"content-type": "application/json",
"access-control-allow-origin": "*"
},
text: JSON.stringify(result)
};
}
if (route === routes.patchToken) {
const token2 = headers.authorization?.substr("token ".length);
if (!token2) {
throw new Error(
'[@octokit/oauth-app] "Authorization" header is required'
);
}
const result = await app.resetToken({ token: token2 });
delete result.authentication.clientSecret;
return {
status: 200,
headers: {
"content-type": "application/json",
"access-control-allow-origin": "*"
},
text: JSON.stringify(result)
};
}
if (route === routes.patchRefreshToken) {
const token2 = headers.authorization?.substr("token ".length);
if (!token2) {
throw new Error(
'[@octokit/oauth-app] "Authorization" header is required'
);
}
const { refreshToken } = json;
if (!refreshToken) {
throw new Error(
"[@octokit/oauth-app] refreshToken must be sent in request body"
);
}
const result = await app.refreshToken({ refreshToken });
delete result.authentication.clientSecret;
return {
status: 200,
headers: {
"content-type": "application/json",
"access-control-allow-origin": "*"
},
text: JSON.stringify(result)
};
}
if (route === routes.scopeToken) {
const token2 = headers.authorization?.substr("token ".length);
if (!token2) {
throw new Error(
'[@octokit/oauth-app] "Authorization" header is required'
);
}
const result = await app.scopeToken({
token: token2,
...json
});
delete result.authentication.clientSecret;
return {
status: 200,
headers: {
"content-type": "application/json",
"access-control-allow-origin": "*"
},
text: JSON.stringify(result)
};
}
if (route === routes.deleteToken) {
const token2 = headers.authorization?.substr("token ".length);
if (!token2) {
throw new Error(
'[@octokit/oauth-app] "Authorization" header is required'
);
}
await app.deleteToken({
token: token2
});
return {
status: 204,
headers: { "access-control-allow-origin": "*" }
};
}
const token = headers.authorization?.substr("token ".length);
if (!token) {
throw new Error(
'[@octokit/oauth-app] "Authorization" header is required'
);
}
await app.deleteAuthorization({
token
});
return {
status: 204,
headers: { "access-control-allow-origin": "*" }
};
} catch (error) {
return {
status: 400,
headers: {
"content-type": "application/json",
"access-control-allow-origin": "*"
},
text: JSON.stringify({ error: error.message })
};
}
}
export {
handleRequest
};

View File

@@ -0,0 +1,19 @@
import { parseRequest } from "./parse-request.js";
import { sendResponse } from "./send-response.js";
import { handleRequest } from "../handle-request.js";
function createNodeMiddleware(app, options = {}) {
return async function(request, response, next) {
const octokitRequest = await parseRequest(request);
const octokitResponse = await handleRequest(app, options, octokitRequest);
if (octokitResponse) {
sendResponse(octokitResponse, response);
return true;
} else {
next?.();
return false;
}
};
}
export {
createNodeMiddleware
};

View File

@@ -0,0 +1,14 @@
function parseRequest(request) {
const { method, url, headers } = request;
async function text() {
const text2 = await new Promise((resolve, reject) => {
let bodyChunks = [];
request.on("error", reject).on("data", (chunk) => bodyChunks.push(chunk)).on("end", () => resolve(Buffer.concat(bodyChunks).toString()));
});
return text2;
}
return { method, url, headers, text };
}
export {
parseRequest
};

View File

@@ -0,0 +1,7 @@
function sendResponse(octokitResponse, response) {
response.writeHead(octokitResponse.status, octokitResponse.headers);
response.end(octokitResponse.text);
}
export {
sendResponse
};

View File

@@ -0,0 +1,12 @@
function unknownRouteResponse(request) {
return {
status: 404,
headers: { "content-type": "application/json" },
text: JSON.stringify({
error: `Unknown route: ${request.method} ${request.url}`
})
};
}
export {
unknownRouteResponse
};

View File

@@ -0,0 +1,13 @@
import { parseRequest } from "./parse-request.js";
import { sendResponse } from "./send-response.js";
import { handleRequest } from "../handle-request.js";
function createWebWorkerHandler(app, options = {}) {
return async function(request) {
const octokitRequest = await parseRequest(request);
const octokitResponse = await handleRequest(app, options, octokitRequest);
return octokitResponse ? sendResponse(octokitResponse) : void 0;
};
}
export {
createWebWorkerHandler
};

View File

@@ -0,0 +1,12 @@
function parseRequest(request) {
const headers = Object.fromEntries(request.headers.entries());
return {
method: request.method,
url: request.url,
headers,
text: () => request.text()
};
}
export {
parseRequest
};

View File

@@ -0,0 +1,12 @@
function sendResponse(octokitResponse) {
const responseOptions = {
status: octokitResponse.status
};
if (octokitResponse.headers) {
Object.assign(responseOptions, { headers: octokitResponse.headers });
}
return new Response(octokitResponse.text, responseOptions);
}
export {
sendResponse
};

View File

@@ -0,0 +1,9 @@
import { Octokit } from "@octokit/core";
import { getUserAgent } from "universal-user-agent";
import { VERSION } from "./version.js";
const OAuthAppOctokit = Octokit.defaults({
userAgent: `octokit-oauth-app.js/${VERSION} ${getUserAgent()}`
});
export {
OAuthAppOctokit
};

4
node_modules/@octokit/oauth-app/dist-src/version.js generated vendored Normal file
View File

@@ -0,0 +1,4 @@
const VERSION = "8.0.3";
export {
VERSION
};