@onelyid/express 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +45 -0
- package/dist/index.js +246 -0
- package/dist/index.js.map +1 -0
- package/package.json +58 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Environment } from '@onelyid/common';
|
|
2
|
+
import { RequestHandler } from 'express';
|
|
3
|
+
|
|
4
|
+
type Logger = {
|
|
5
|
+
info: Function;
|
|
6
|
+
warn: Function;
|
|
7
|
+
error: Function;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
type RequestMode = `${Environment}`
|
|
11
|
+
type AuthMiddlewareConfig = {
|
|
12
|
+
loginRedirect?: string;
|
|
13
|
+
logger?: Logger;
|
|
14
|
+
mode?: RequestMode;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
type UserInfo = {
|
|
18
|
+
did: string;
|
|
19
|
+
handle: string;
|
|
20
|
+
email: string;
|
|
21
|
+
emailTrusted: boolean;
|
|
22
|
+
displayName?: string;
|
|
23
|
+
avatar?: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Express request augmentation
|
|
27
|
+
declare global {
|
|
28
|
+
namespace Express {
|
|
29
|
+
interface Request {
|
|
30
|
+
auth: UserInfo | null
|
|
31
|
+
authFlow: () => Promise<void>
|
|
32
|
+
getAuth: () => Promise<UserInfo | null>
|
|
33
|
+
mode: Environment
|
|
34
|
+
}
|
|
35
|
+
interface Response {
|
|
36
|
+
clearAuth: () => Promise<void>
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
declare const authMiddleware: (config?: AuthMiddlewareConfig) => RequestHandler;
|
|
42
|
+
declare const setAuth: RequestHandler;
|
|
43
|
+
declare const redirect: (path: string) => RequestHandler;
|
|
44
|
+
|
|
45
|
+
export { type AuthMiddlewareConfig, type UserInfo, authMiddleware, redirect, setAuth };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
|
+
authMiddleware: () => authMiddleware,
|
|
34
|
+
redirect: () => redirect,
|
|
35
|
+
setAuth: () => setAuth
|
|
36
|
+
});
|
|
37
|
+
module.exports = __toCommonJS(index_exports);
|
|
38
|
+
|
|
39
|
+
// src/middleware.ts
|
|
40
|
+
var import_express = __toESM(require("express"));
|
|
41
|
+
var import_common3 = require("@onelyid/common");
|
|
42
|
+
|
|
43
|
+
// src/auth.ts
|
|
44
|
+
var import_common = require("@onelyid/common");
|
|
45
|
+
async function initAuthFlow(req, res, config) {
|
|
46
|
+
const searchParams = new URLSearchParams(req.query);
|
|
47
|
+
const redirectUrl = searchParams.get("continue") || "/";
|
|
48
|
+
if (await req.getAuth()) {
|
|
49
|
+
return res.redirect(redirectUrl);
|
|
50
|
+
}
|
|
51
|
+
const authOriginObj = (0, import_common.getAuthOrigin)(req);
|
|
52
|
+
const authClientMountPath2 = (0, import_common.getAuthClientMountPath)();
|
|
53
|
+
const { isMainAuthDomainVariant } = (0, import_common.getMainAuthDomainVariants)(req);
|
|
54
|
+
if (authOriginObj && !isMainAuthDomainVariant) {
|
|
55
|
+
const authOrigin = authOriginObj.authOrigin;
|
|
56
|
+
let continueUrl = config?.loginRedirect;
|
|
57
|
+
if (!continueUrl) {
|
|
58
|
+
continueUrl = req.get("referer");
|
|
59
|
+
}
|
|
60
|
+
if (!continueUrl) {
|
|
61
|
+
continueUrl = `${(0, import_common.getOrigin)(req)}${req.originalUrl}`;
|
|
62
|
+
}
|
|
63
|
+
const redirectUrl2 = new URL(`${authOrigin}${authClientMountPath2}/login/redirect`);
|
|
64
|
+
redirectUrl2.searchParams.set("continue", continueUrl);
|
|
65
|
+
if (req.mode) {
|
|
66
|
+
redirectUrl2.searchParams.set("request_mode", req.mode);
|
|
67
|
+
}
|
|
68
|
+
return res.redirect(redirectUrl2.href);
|
|
69
|
+
}
|
|
70
|
+
res.redirect("/");
|
|
71
|
+
}
|
|
72
|
+
async function authSessionApi(route, req, res, body) {
|
|
73
|
+
const isPost = typeof body !== "undefined";
|
|
74
|
+
const authClientMountPath2 = (0, import_common.getAuthClientMountPath)();
|
|
75
|
+
const customHeaders = (0, import_common.getCustomHeaderNames)();
|
|
76
|
+
const authOriginObj = (0, import_common.getAuthOrigin)(req);
|
|
77
|
+
if (!authOriginObj) {
|
|
78
|
+
return { ok: true };
|
|
79
|
+
}
|
|
80
|
+
const routePath = (0, import_common.assertPath)(route);
|
|
81
|
+
if (authOriginObj && routePath) {
|
|
82
|
+
const authOrigin = authOriginObj.authOrigin;
|
|
83
|
+
const apiUrl = `${authOrigin}${authClientMountPath2}${routePath}`;
|
|
84
|
+
try {
|
|
85
|
+
const resp = await fetch(apiUrl, {
|
|
86
|
+
method: isPost ? "POST" : "GET",
|
|
87
|
+
headers: {
|
|
88
|
+
Cookie: req.headers.cookie ?? "",
|
|
89
|
+
Accept: "application/json",
|
|
90
|
+
[customHeaders.requestMode]: req.mode || import_common.Environment.Prod
|
|
91
|
+
},
|
|
92
|
+
...body ? { body: JSON.stringify(body) } : {}
|
|
93
|
+
});
|
|
94
|
+
if (res) {
|
|
95
|
+
const setCookie = resp.headers.getSetCookie().find((v) => v.startsWith("sid="));
|
|
96
|
+
if (setCookie) {
|
|
97
|
+
res.setHeader("set-cookie", setCookie);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
let data = null;
|
|
101
|
+
try {
|
|
102
|
+
data = await resp.json();
|
|
103
|
+
} catch (e) {
|
|
104
|
+
}
|
|
105
|
+
if (typeof data?.ok !== "undefined") {
|
|
106
|
+
return data;
|
|
107
|
+
} else {
|
|
108
|
+
return { error: `Invalid response for api call for ${apiUrl} [${req.path}]` };
|
|
109
|
+
}
|
|
110
|
+
} catch (err) {
|
|
111
|
+
console.error(err);
|
|
112
|
+
return { error: `Error during auth session api call for ${apiUrl} [${req.path}]` };
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return { error: `Invalid auth session api call for ${authOriginObj?.authOrigin} [${routePath}]` };
|
|
116
|
+
}
|
|
117
|
+
async function getSessionUser(req) {
|
|
118
|
+
return authSessionApi("/userinfo", req);
|
|
119
|
+
}
|
|
120
|
+
async function destroySession(req, res) {
|
|
121
|
+
return authSessionApi("/logout", req, res, null);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// src/proxy-middleware.ts
|
|
125
|
+
var import_node_https = __toESM(require("https"));
|
|
126
|
+
var import_node_http = __toESM(require("http"));
|
|
127
|
+
var import_common2 = require("@onelyid/common");
|
|
128
|
+
var authClientMountPath = (0, import_common2.getAuthClientMountPath)();
|
|
129
|
+
var authProxyPaths = [
|
|
130
|
+
// '/',
|
|
131
|
+
// '/public/styles.css',
|
|
132
|
+
// '/login',
|
|
133
|
+
// '/logout',
|
|
134
|
+
"/oauth-client-metadata.json",
|
|
135
|
+
`${authClientMountPath}/login/redirect`,
|
|
136
|
+
`${authClientMountPath}/login`,
|
|
137
|
+
`${authClientMountPath}/callback`,
|
|
138
|
+
`${authClientMountPath}/transfer-local-session`,
|
|
139
|
+
`${authClientMountPath}/userinfo`,
|
|
140
|
+
`${authClientMountPath}/logout`
|
|
141
|
+
];
|
|
142
|
+
var authProxyMiddleware = (req, res, next) => {
|
|
143
|
+
const origin = (0, import_common2.getOrigin)(req);
|
|
144
|
+
const authOriginObj = (0, import_common2.getAuthOrigin)(req);
|
|
145
|
+
const useProxy = origin && origin === authOriginObj?.authOrigin || authOriginObj?.isLocalhost;
|
|
146
|
+
if (!useProxy) {
|
|
147
|
+
return next();
|
|
148
|
+
}
|
|
149
|
+
const mainAuthDomain = (0, import_common2.getMainAuthDomain)(req);
|
|
150
|
+
const authProxyTargetOrigin = `https://${mainAuthDomain}`;
|
|
151
|
+
if (!authProxyPaths.includes(req.path)) {
|
|
152
|
+
return next();
|
|
153
|
+
} else {
|
|
154
|
+
console.log(`[Proxy] ${req.method} ${req.url}`);
|
|
155
|
+
}
|
|
156
|
+
const targetUrl = new URL(req.url, authProxyTargetOrigin);
|
|
157
|
+
const client = targetUrl.protocol === "https:" ? import_node_https.default : import_node_http.default;
|
|
158
|
+
const customHeaders = (0, import_common2.getCustomHeaderNames)();
|
|
159
|
+
const options = {
|
|
160
|
+
hostname: targetUrl.hostname,
|
|
161
|
+
// TCP target
|
|
162
|
+
servername: targetUrl.hostname,
|
|
163
|
+
// TLS SNI (optional, otherwise defaults to headers.host)
|
|
164
|
+
port: targetUrl.port,
|
|
165
|
+
path: targetUrl.pathname + targetUrl.search,
|
|
166
|
+
method: req.method,
|
|
167
|
+
headers: {
|
|
168
|
+
...req.headers,
|
|
169
|
+
host: targetUrl.hostname,
|
|
170
|
+
// Override host header
|
|
171
|
+
[customHeaders.proxyOrigin]: `${req.protocol}://${req.get("host")}`
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
const proxyReq = client.request(options, (proxyRes) => {
|
|
175
|
+
res.status(proxyRes.statusCode ?? 500);
|
|
176
|
+
Object.keys(proxyRes.headers).forEach((key) => {
|
|
177
|
+
res.setHeader(key, proxyRes.headers[key]);
|
|
178
|
+
});
|
|
179
|
+
proxyRes.pipe(res);
|
|
180
|
+
});
|
|
181
|
+
proxyReq.on("error", (err) => {
|
|
182
|
+
console.error("Proxy error:", err);
|
|
183
|
+
res.status(500).send("Proxy error");
|
|
184
|
+
});
|
|
185
|
+
req.pipe(proxyReq);
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
// src/middleware.ts
|
|
189
|
+
var authMiddleware = (config) => {
|
|
190
|
+
const router = import_express.default.Router();
|
|
191
|
+
router.use(async (req, res, next) => {
|
|
192
|
+
req.mode = (0, import_common3.assertRequestMode)(config?.mode) || import_common3.Environment.Prod;
|
|
193
|
+
req.authFlow = () => initAuthFlow(req, res, config);
|
|
194
|
+
req.getAuth = () => setReqAuth(req);
|
|
195
|
+
res.clearAuth = () => deleteSession(req, res);
|
|
196
|
+
res.json = (data) => sendJson(res, data);
|
|
197
|
+
next();
|
|
198
|
+
});
|
|
199
|
+
router.use(authProxyMiddleware);
|
|
200
|
+
return router;
|
|
201
|
+
};
|
|
202
|
+
var setAuth = async (req, _res, next) => {
|
|
203
|
+
await setReqAuth(req);
|
|
204
|
+
next();
|
|
205
|
+
};
|
|
206
|
+
var redirect = (redirectPath) => (async (req, res, next) => {
|
|
207
|
+
await setReqAuth(req);
|
|
208
|
+
if (!req.auth) {
|
|
209
|
+
const path = (0, import_common3.assertPath)(redirectPath ?? "/");
|
|
210
|
+
return res.redirect(path);
|
|
211
|
+
}
|
|
212
|
+
next();
|
|
213
|
+
});
|
|
214
|
+
async function setReqAuth(req) {
|
|
215
|
+
if (req.auth) {
|
|
216
|
+
return req.auth;
|
|
217
|
+
}
|
|
218
|
+
const { user, error } = await getSessionUser(req);
|
|
219
|
+
if (error) {
|
|
220
|
+
console.error("[setReqAuth]", error);
|
|
221
|
+
}
|
|
222
|
+
if (!error && user) {
|
|
223
|
+
req.auth = user;
|
|
224
|
+
}
|
|
225
|
+
if (!req.auth) {
|
|
226
|
+
req.auth = null;
|
|
227
|
+
}
|
|
228
|
+
return req.auth;
|
|
229
|
+
}
|
|
230
|
+
async function deleteSession(req, res) {
|
|
231
|
+
const { ok, error } = await destroySession(req, res);
|
|
232
|
+
if (!ok || error) {
|
|
233
|
+
console.error("[deleteSession]", { ok, error });
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
function sendJson(res, data) {
|
|
237
|
+
const dataStr = JSON.stringify(data, null, 2);
|
|
238
|
+
return res.type("json").send(dataStr);
|
|
239
|
+
}
|
|
240
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
241
|
+
0 && (module.exports = {
|
|
242
|
+
authMiddleware,
|
|
243
|
+
redirect,
|
|
244
|
+
setAuth
|
|
245
|
+
});
|
|
246
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/middleware.ts","../src/auth.ts","../src/proxy-middleware.ts"],"sourcesContent":["import './types/globals.d.ts'\nexport { authMiddleware, redirect, setAuth } from './middleware'\nexport type { AuthMiddlewareConfig, UserInfo } from './types/common'\n","import express from 'express';\nimport type { Request, Response, RequestHandler } from 'express'\nimport { Environment, assertPath, assertRequestMode } from '@onelyid/common'\nimport { destroySession, getSessionUser, initAuthFlow } from './auth';\nimport { authProxyMiddleware } from './proxy-middleware';\nimport { AuthMiddlewareConfig, UserInfo } from './types/common';\n\nexport const authMiddleware = (config?: AuthMiddlewareConfig): RequestHandler => {\n const router = express.Router()\n\n // gate middleware\n router.use(async (req, res, next) => {\n req.mode = assertRequestMode(config?.mode) || Environment.Prod\n\n req.authFlow = () => initAuthFlow(req, res, config)\n req.getAuth = () => setReqAuth(req)\n\n res.clearAuth = () => deleteSession(req, res)\n\n // custom json response\n res.json = (data: unknown) => sendJson(res, data)\n\n next()\n })\n\n router.use(authProxyMiddleware)\n\n return router\n}\n\nexport const setAuth: RequestHandler = async (req, _res, next) => {\n await setReqAuth(req)\n next()\n};\n\nexport const redirect: (path: string) => RequestHandler = (redirectPath: string) => (async (req, res, next) => {\n await setReqAuth(req)\n if (!req.auth) {\n const path = assertPath(redirectPath ?? '/');\n return res.redirect(path)\n }\n next()\n}) satisfies RequestHandler;\n\nasync function setReqAuth(req: Request): Promise<UserInfo | null> {\n if (req.auth) {\n return req.auth\n }\n\n const { user, error } = await getSessionUser(req)\n if (error) {\n console.error('[setReqAuth]', error)\n }\n\n if (!error && user) {\n req.auth = user\n }\n if (!req.auth) {\n req.auth = null\n }\n return req.auth\n}\n\nasync function deleteSession(req: Request, res: Response) {\n const { ok, error } = await destroySession(req, res)\n if (!ok || error) {\n console.error('[deleteSession]', { ok, error });\n }\n}\n\nfunction sendJson(res: Response, data: unknown) {\n const dataStr = JSON.stringify(data, null, 2)\n return res.type('json').send(dataStr)\n}\n","import type { Request, Response } from 'express'\nimport { Environment, assertPath, getAuthClientMountPath, getAuthOrigin, getCustomHeaderNames, getMainAuthDomainVariants, getOrigin } from '@onelyid/common'\nimport { AuthMiddlewareConfig, UserInfo } from './types/common';\n\nexport async function initAuthFlow(req: Request, res: Response, config: AuthMiddlewareConfig | undefined) {\n const searchParams = new URLSearchParams(req.query as Record<string, string>)\n const redirectUrl = searchParams.get('continue') || '/'\n if (await req.getAuth()) {\n return res.redirect(redirectUrl)\n }\n\n const authOriginObj = getAuthOrigin(req)\n const authClientMountPath = getAuthClientMountPath()\n const { isMainAuthDomainVariant } = getMainAuthDomainVariants(req)\n\n if (authOriginObj && !isMainAuthDomainVariant) {\n const authOrigin = authOriginObj.authOrigin\n let continueUrl = config?.loginRedirect\n if (!continueUrl) {\n continueUrl = req.get('referer')\n }\n if (!continueUrl) {\n continueUrl = `${getOrigin(req)}${req.originalUrl}`\n }\n const redirectUrl = new URL(`${authOrigin}${authClientMountPath}/login/redirect`)\n redirectUrl.searchParams.set('continue', continueUrl)\n if (req.mode) {\n redirectUrl.searchParams.set('request_mode', req.mode)\n }\n return res.redirect(redirectUrl.href)\n }\n res.redirect('/')\n}\n\nasync function authSessionApi<T extends object>(route: string, req: Request, res?: Response, body?: object | null) {\n type RetType = Partial<T & { ok?: boolean, error?: string }>\n\n const isPost = typeof body !== 'undefined'\n const authClientMountPath = getAuthClientMountPath()\n const customHeaders = getCustomHeaderNames()\n\n const authOriginObj = getAuthOrigin(req);\n if (!authOriginObj) {\n return { ok: true } as RetType\n }\n\n const routePath = assertPath(route)\n if (authOriginObj && routePath) {\n const authOrigin = authOriginObj.authOrigin\n const apiUrl = `${authOrigin}${authClientMountPath}${routePath}`\n try {\n const resp = await fetch(apiUrl, {\n method: isPost ? 'POST' : 'GET',\n headers: {\n Cookie: req.headers.cookie ?? '',\n Accept: 'application/json',\n [customHeaders.requestMode]: req.mode || Environment.Prod,\n },\n ...(body ? { body: JSON.stringify(body) } : {}),\n })\n if (res) {\n const setCookie = resp.headers.getSetCookie().find(v => v.startsWith('sid='))\n if (setCookie) {\n res.setHeader('set-cookie', setCookie)\n }\n }\n\n let data: RetType | null = null;\n try {\n data = (await resp.json()) as RetType\n } catch(e) {}\n\n if (typeof data?.ok !== 'undefined') {\n return data\n } else {\n return { error: `Invalid response for api call for ${apiUrl} [${req.path}]` } as RetType\n }\n } catch(err: any) {\n console.error(err);\n // console.error(`${err.name}: ${err.message}`);\n return { error: `Error during auth session api call for ${apiUrl} [${req.path}]` } as RetType\n }\n }\n\n return { error: `Invalid auth session api call for ${authOriginObj?.authOrigin} [${routePath}]` } as RetType\n}\n\nexport async function getSessionUser(req: Request) {\n return authSessionApi<{ user?: UserInfo | null }>('/userinfo', req)\n}\n\nexport async function destroySession(req: Request, res: Response) {\n return authSessionApi<{}>('/logout', req, res, null)\n}\n","import type { Request, Response, NextFunction} from 'express';\nimport https from 'node:https';\nimport http from 'node:http';\nimport { getAuthClientMountPath, getAuthOrigin, getCustomHeaderNames, getMainAuthDomain, getOrigin } from '@onelyid/common';\n\nconst authClientMountPath = getAuthClientMountPath()\nconst authProxyPaths = [\n // '/',\n // '/public/styles.css',\n // '/login',\n // '/logout',\n '/oauth-client-metadata.json',\n `${authClientMountPath}/login/redirect`,\n `${authClientMountPath}/login`,\n `${authClientMountPath}/callback`,\n `${authClientMountPath}/transfer-local-session`,\n `${authClientMountPath}/userinfo`,\n `${authClientMountPath}/logout`,\n];\n\nexport const authProxyMiddleware = (req: Request, res: Response, next: NextFunction) => {\n const origin = getOrigin(req)\n const authOriginObj = getAuthOrigin(req)\n const useProxy = (origin && origin === authOriginObj?.authOrigin) || authOriginObj?.isLocalhost\n if (!useProxy) {\n return next()\n } \n\n const mainAuthDomain = getMainAuthDomain(req)\n const authProxyTargetOrigin = `https://${mainAuthDomain}`;\n\n if (!authProxyPaths.includes(req.path)) {\n // console.log(`[OK] No Proxy`);\n return next();\n } else {\n console.log(`[Proxy] ${req.method} ${req.url}`);\n }\n\n // Parse the target URL\n const targetUrl = new URL(req.url, authProxyTargetOrigin);\n \n // Choose http or https module based on 'target url' protocol\n const client = targetUrl.protocol === 'https:' ? https : http;\n\n const customHeaders = getCustomHeaderNames()\n \n // Prepare request options\n const options = {\n hostname: targetUrl.hostname, // TCP target\n servername: targetUrl.hostname, // TLS SNI (optional, otherwise defaults to headers.host)\n port: targetUrl.port,\n path: targetUrl.pathname + targetUrl.search,\n method: req.method,\n headers: {\n ...req.headers,\n host: targetUrl.hostname, // Override host header\n [customHeaders.proxyOrigin]: `${req.protocol}://${req.get('host')}`\n },\n };\n \n // Make the request to the target server\n const proxyReq = client.request(options, (proxyRes) => {\n // Forward status code\n res.status(proxyRes.statusCode ?? 500);\n \n // Forward headers\n Object.keys(proxyRes.headers).forEach(key => {\n res.setHeader(key, proxyRes.headers[key] as string);\n });\n \n // Pipe the response back to client\n proxyRes.pipe(res);\n });\n \n // Handle errors\n proxyReq.on('error', (err) => {\n console.error('Proxy error:', err);\n res.status(500).send('Proxy error');\n });\n \n // Pipe the request body (for POST, PUT, etc.)\n req.pipe(proxyReq);\n};\n"],"mappings":"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","names":["import_common","authClientMountPath","redirectUrl","import_common","https","http","express"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@onelyid/express",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "ATProto OAuth provider",
|
|
5
|
+
"author": "abraj",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"publishConfig": {
|
|
8
|
+
"access": "public"
|
|
9
|
+
},
|
|
10
|
+
"main": "dist/index.js",
|
|
11
|
+
"types": "dist/index.d.ts",
|
|
12
|
+
"type": "commonjs",
|
|
13
|
+
"files": [
|
|
14
|
+
"dist"
|
|
15
|
+
],
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "git+https://github.com/baadal/onelyid.git"
|
|
19
|
+
},
|
|
20
|
+
"keywords": [
|
|
21
|
+
"onelyid",
|
|
22
|
+
"atproto",
|
|
23
|
+
"login",
|
|
24
|
+
"auth",
|
|
25
|
+
"authentication",
|
|
26
|
+
"express",
|
|
27
|
+
"bluesky",
|
|
28
|
+
"oauth",
|
|
29
|
+
"oauth2",
|
|
30
|
+
"server",
|
|
31
|
+
"node",
|
|
32
|
+
"backend"
|
|
33
|
+
],
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"@onelyid/common": "0.1.0"
|
|
36
|
+
},
|
|
37
|
+
"peerDependencies": {
|
|
38
|
+
"express": "^4.17.2"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@types/express": "^4.17.13",
|
|
42
|
+
"express": "^4.17.2"
|
|
43
|
+
},
|
|
44
|
+
"tsup": {
|
|
45
|
+
"entry": [
|
|
46
|
+
"src/index.ts"
|
|
47
|
+
],
|
|
48
|
+
"splitting": false,
|
|
49
|
+
"sourcemap": true,
|
|
50
|
+
"clean": true
|
|
51
|
+
},
|
|
52
|
+
"scripts": {
|
|
53
|
+
"tsc": "tsc -b",
|
|
54
|
+
"build": "tsup --dts",
|
|
55
|
+
"build:server": "tsup",
|
|
56
|
+
"clean": "rm -rf node_modules dist tsconfig.tsbuildinfo"
|
|
57
|
+
}
|
|
58
|
+
}
|