authhero 0.0.1 → 0.2.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/CHANGELOG.md +13 -0
- package/README.md +1 -1
- package/package.json +2 -2
- package/src/bun.ts +16 -0
- package/src/index.ts +25 -4
- package/src/routes/oauth2/index.ts +1 -0
- package/src/routes/oauth2/well-known.ts +179 -0
- package/src/types/Bindings.ts +3 -0
- package/src/types/JWKS.ts +37 -0
- package/src/types/Variables.ts +1 -0
- package/src/types/index.ts +3 -0
- package/vite.config.ts +36 -6
- package/dist/authhero.js +0 -4912
- package/dist/index.d.ts +0 -4
- package/dist/index.d.ts.map +0 -1
- package/dist/types/Bindings.d.ts +0 -5
- package/dist/types/Bindings.d.ts.map +0 -1
package/CHANGELOG.md
ADDED
package/README.md
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "authhero",
|
|
3
|
-
"version": "0.0
|
|
4
|
-
"type": "module",
|
|
3
|
+
"version": "0.2.0",
|
|
5
4
|
"main": "dist/index.js",
|
|
6
5
|
"types": "dist/index.d.ts",
|
|
7
6
|
"bin": {
|
|
@@ -18,6 +17,7 @@
|
|
|
18
17
|
"hono": "^4.4.10"
|
|
19
18
|
},
|
|
20
19
|
"scripts": {
|
|
20
|
+
"dev": "bun --watch src/bun.ts",
|
|
21
21
|
"build": "vite build",
|
|
22
22
|
"start": "pnpm build && node dist/index.js"
|
|
23
23
|
}
|
package/src/bun.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { OpenAPIHono } from "@hono/zod-openapi";
|
|
2
|
+
import { Bindings } from "./types/Bindings";
|
|
3
|
+
import { Context } from "hono";
|
|
4
|
+
import { init } from "./";
|
|
5
|
+
|
|
6
|
+
const app = new OpenAPIHono<{ Bindings: Bindings }>();
|
|
7
|
+
|
|
8
|
+
const authhero = init();
|
|
9
|
+
|
|
10
|
+
app.get("/test", (ctx: Context) => {
|
|
11
|
+
return ctx.text("Hello, world!");
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
app.route("/", authhero);
|
|
15
|
+
|
|
16
|
+
export default app;
|
package/src/index.ts
CHANGED
|
@@ -1,13 +1,34 @@
|
|
|
1
1
|
import { OpenAPIHono } from "@hono/zod-openapi";
|
|
2
2
|
import { Context } from "hono";
|
|
3
|
-
import { Bindings } from "./types
|
|
3
|
+
import { Bindings, Variables } from "./types";
|
|
4
|
+
import { wellKnownRoutes } from "./routes/oauth2";
|
|
4
5
|
|
|
5
6
|
export interface AuthHeroConfig {}
|
|
6
7
|
|
|
7
8
|
export function init() {
|
|
8
|
-
const
|
|
9
|
+
const rootApp = new OpenAPIHono<{ Bindings: Bindings }>();
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
return ctx.text("Hello,
|
|
11
|
+
rootApp.get("/", (ctx: Context) => {
|
|
12
|
+
return ctx.text("Hello, authhero!");
|
|
12
13
|
});
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* The oauth routes
|
|
17
|
+
*/
|
|
18
|
+
const oauthApp = new OpenAPIHono<{
|
|
19
|
+
Bindings: Bindings;
|
|
20
|
+
Variables: Variables;
|
|
21
|
+
}>().route("/.well-known", wellKnownRoutes);
|
|
22
|
+
|
|
23
|
+
oauthApp.doc("/spec", {
|
|
24
|
+
openapi: "3.0.0",
|
|
25
|
+
info: {
|
|
26
|
+
version: "1.0.0",
|
|
27
|
+
title: "Oauth endpoints",
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
rootApp.route("/", oauthApp);
|
|
32
|
+
|
|
33
|
+
return rootApp;
|
|
13
34
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./well-known";
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Bindings,
|
|
3
|
+
jwksKeySchema,
|
|
4
|
+
// jwksSchema,
|
|
5
|
+
openIDConfigurationSchema,
|
|
6
|
+
} from "../../types";
|
|
7
|
+
import { OpenAPIHono, createRoute } from "@hono/zod-openapi";
|
|
8
|
+
|
|
9
|
+
export const wellKnownRoutes = new OpenAPIHono<{ Bindings: Bindings }>()
|
|
10
|
+
// --------------------------------
|
|
11
|
+
// GET /.well-known/jwks.json
|
|
12
|
+
// --------------------------------
|
|
13
|
+
.openapi(
|
|
14
|
+
createRoute({
|
|
15
|
+
tags: ["jwks"],
|
|
16
|
+
method: "get",
|
|
17
|
+
path: "/jwks.json",
|
|
18
|
+
request: {},
|
|
19
|
+
responses: {
|
|
20
|
+
200: {
|
|
21
|
+
content: {
|
|
22
|
+
"application/json": {
|
|
23
|
+
schema: jwksKeySchema,
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
description: "List of tenants",
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
}),
|
|
30
|
+
async (ctx) => {
|
|
31
|
+
const { env } = ctx;
|
|
32
|
+
|
|
33
|
+
// const certificates = await env.data.keys.list();
|
|
34
|
+
// const keys = certificates.map((cert) => {
|
|
35
|
+
// const { alg, n, e, kty } = JSON.parse(cert.public_key);
|
|
36
|
+
// if (!alg || !e || !kty || !n) {
|
|
37
|
+
// throw new Error("Invalid public key");
|
|
38
|
+
// }
|
|
39
|
+
|
|
40
|
+
// return jwksSchema.parse({
|
|
41
|
+
// kid: cert.kid,
|
|
42
|
+
// alg,
|
|
43
|
+
// n,
|
|
44
|
+
// e,
|
|
45
|
+
// kty,
|
|
46
|
+
// });
|
|
47
|
+
// });
|
|
48
|
+
|
|
49
|
+
// TODO: This is a stub implementation. Replace with the actual implementation
|
|
50
|
+
const keys = [
|
|
51
|
+
{
|
|
52
|
+
alg: "RS256",
|
|
53
|
+
e: "AQAB",
|
|
54
|
+
kid: "hZ42TWGWLdmyKfwGVA6c2",
|
|
55
|
+
kty: "RSA",
|
|
56
|
+
n: "nUd-mktFZQNfVwmXufxcVcvJo6Lkb-jDuymtfQunmEhWCctOccWx9e7LX7_9uN15ZnRS7XJInPMRs9KLYdZ0GCnE2HM_QbrEoHpdkCRgyTE-KzmoaEv_AOVGE_Kg0-0ct3r9Z7aJLDVAsxXl1C9y8Gr7ZYkq0c4DyZr9VT8nQiwZQERbfxXdXw-5RLj21S_Lm-LL-AjKvry_TDBLpfUFJV18SVsM07lY_V45TwykNewRdaGLspFIeGdG5j5eByV8ifzBqvzOSptSCsmOTtW-ceWUk0FPD7g_KKzjjbzenoB0TC8mBb_4vWZlHnuGIAs2YoTFglp9uNu7t_OVl3Svo6ZE6alzUnaNfZNeAi78KPHYQ4tDWPjpYNfGynsiD0nojkDSPCIak56jWNYjj614cPEBiv9MVQRiSbBxpiGhMoHlW_QCCPMcXygLAaRs_tUksqoH4QB80krifG2yHPgGDPjXK1_0cYzV80iOcQIeoceqhkSSc6YxzzgDrQcsV2k3bizRQSL83GWkpdHhTZn-Q_JzsW_bDY_f9fjigYbRnoDSgS7038VFIPc92StE41MdgvIQMomcyEE4lYK1uv1Mo6cnXbCZhm8tvddo7VKNorOB4nsiv8DGrWPlzQBca9VN4C1oE2mH-3WLFR7XEkBHWVouOdTWM2S3K9F10YtahkM",
|
|
57
|
+
},
|
|
58
|
+
];
|
|
59
|
+
|
|
60
|
+
return ctx.json(
|
|
61
|
+
{ keys },
|
|
62
|
+
{
|
|
63
|
+
headers: {
|
|
64
|
+
"access-control-allow-origin": "*",
|
|
65
|
+
"access-control-allow-method": "GET",
|
|
66
|
+
"cache-control": `public, max-age=${env.JWKS_CACHE_TIMEOUT_IN_SECONDS}, stale-while-revalidate=${
|
|
67
|
+
env.JWKS_CACHE_TIMEOUT_IN_SECONDS * 2
|
|
68
|
+
}, stale-if-error=86400`,
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
);
|
|
72
|
+
},
|
|
73
|
+
)
|
|
74
|
+
// --------------------------------
|
|
75
|
+
// GET /.well-known/openid-configuration
|
|
76
|
+
// --------------------------------
|
|
77
|
+
.openapi(
|
|
78
|
+
createRoute({
|
|
79
|
+
tags: ["well known"],
|
|
80
|
+
method: "get",
|
|
81
|
+
path: "/openid-configuration",
|
|
82
|
+
request: {},
|
|
83
|
+
responses: {
|
|
84
|
+
200: {
|
|
85
|
+
content: {
|
|
86
|
+
"application/json": {
|
|
87
|
+
schema: openIDConfigurationSchema,
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
description: "List of tenants",
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
}),
|
|
94
|
+
async (ctx) => {
|
|
95
|
+
const { env } = ctx;
|
|
96
|
+
const { ISSUER } = env;
|
|
97
|
+
|
|
98
|
+
const result = openIDConfigurationSchema.parse({
|
|
99
|
+
issuer: ISSUER,
|
|
100
|
+
authorization_endpoint: `${ISSUER}authorize`,
|
|
101
|
+
token_endpoint: `${ISSUER}oauth/token`,
|
|
102
|
+
device_authorization_endpoint: `${ISSUER}oauth/device/code`,
|
|
103
|
+
userinfo_endpoint: `${ISSUER}userinfo`,
|
|
104
|
+
mfa_challenge_endpoint: `${ISSUER}mfa/challenge`,
|
|
105
|
+
jwks_uri: `${ISSUER}.well-known/jwks.json`,
|
|
106
|
+
registration_endpoint: `${ISSUER}oidc/register`,
|
|
107
|
+
revocation_endpoint: `${ISSUER}oauth/revoke`,
|
|
108
|
+
scopes_supported: [
|
|
109
|
+
"openid",
|
|
110
|
+
"profile",
|
|
111
|
+
"offline_access",
|
|
112
|
+
"name",
|
|
113
|
+
"given_name",
|
|
114
|
+
"family_name",
|
|
115
|
+
"nickname",
|
|
116
|
+
"email",
|
|
117
|
+
"email_verified",
|
|
118
|
+
"picture",
|
|
119
|
+
"created_at",
|
|
120
|
+
"identities",
|
|
121
|
+
"phone",
|
|
122
|
+
"address",
|
|
123
|
+
],
|
|
124
|
+
response_types_supported: [
|
|
125
|
+
"code",
|
|
126
|
+
"token",
|
|
127
|
+
"id_token",
|
|
128
|
+
"code token",
|
|
129
|
+
"code id_token",
|
|
130
|
+
"token id_token",
|
|
131
|
+
"code token id_token",
|
|
132
|
+
],
|
|
133
|
+
code_challenge_methods_supported: ["S256", "plain"],
|
|
134
|
+
response_modes_supported: ["query", "fragment", "form_post"],
|
|
135
|
+
subject_types_supported: ["public"],
|
|
136
|
+
id_token_signing_alg_values_supported: ["HS256", "RS256"],
|
|
137
|
+
token_endpoint_auth_methods_supported: [
|
|
138
|
+
"client_secret_basic",
|
|
139
|
+
"client_secret_post",
|
|
140
|
+
"private_key_jwt",
|
|
141
|
+
],
|
|
142
|
+
claims_supported: [
|
|
143
|
+
"aud",
|
|
144
|
+
"auth_time",
|
|
145
|
+
"created_at",
|
|
146
|
+
"email",
|
|
147
|
+
"email_verified",
|
|
148
|
+
"exp",
|
|
149
|
+
"family_name",
|
|
150
|
+
"given_name",
|
|
151
|
+
"iat",
|
|
152
|
+
"identities",
|
|
153
|
+
"iss",
|
|
154
|
+
"name",
|
|
155
|
+
"nickname",
|
|
156
|
+
"phone_number",
|
|
157
|
+
"picture",
|
|
158
|
+
"sub",
|
|
159
|
+
],
|
|
160
|
+
request_uri_parameter_supported: false,
|
|
161
|
+
request_parameter_supported: false,
|
|
162
|
+
token_endpoint_auth_signing_alg_values_supported: [
|
|
163
|
+
"RS256",
|
|
164
|
+
"RS384",
|
|
165
|
+
"PS256",
|
|
166
|
+
],
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
return ctx.json(result, {
|
|
170
|
+
headers: {
|
|
171
|
+
"access-control-allow-origin": "*",
|
|
172
|
+
"access-control-allow-method": "GET",
|
|
173
|
+
"cache-control": `public, max-age=${env.JWKS_CACHE_TIMEOUT_IN_SECONDS}, stale-while-revalidate=${
|
|
174
|
+
env.JWKS_CACHE_TIMEOUT_IN_SECONDS * 2
|
|
175
|
+
}, stale-if-error=86400`,
|
|
176
|
+
},
|
|
177
|
+
});
|
|
178
|
+
},
|
|
179
|
+
);
|
package/src/types/Bindings.ts
CHANGED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { z } from "@hono/zod-openapi";
|
|
2
|
+
|
|
3
|
+
export const jwksSchema = z.object({
|
|
4
|
+
alg: z.string(),
|
|
5
|
+
e: z.string(),
|
|
6
|
+
kid: z.string(),
|
|
7
|
+
kty: z.string(),
|
|
8
|
+
n: z.string(),
|
|
9
|
+
use: z.string().optional(),
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
export const jwksKeySchema = z.object({
|
|
13
|
+
keys: z.array(jwksSchema),
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
export const openIDConfigurationSchema = z.object({
|
|
17
|
+
issuer: z.string(),
|
|
18
|
+
authorization_endpoint: z.string(),
|
|
19
|
+
token_endpoint: z.string(),
|
|
20
|
+
device_authorization_endpoint: z.string(),
|
|
21
|
+
userinfo_endpoint: z.string(),
|
|
22
|
+
mfa_challenge_endpoint: z.string(),
|
|
23
|
+
jwks_uri: z.string(),
|
|
24
|
+
registration_endpoint: z.string(),
|
|
25
|
+
revocation_endpoint: z.string(),
|
|
26
|
+
scopes_supported: z.array(z.string()),
|
|
27
|
+
response_types_supported: z.array(z.string()),
|
|
28
|
+
code_challenge_methods_supported: z.array(z.string()),
|
|
29
|
+
response_modes_supported: z.array(z.string()),
|
|
30
|
+
subject_types_supported: z.array(z.string()),
|
|
31
|
+
id_token_signing_alg_values_supported: z.array(z.string()),
|
|
32
|
+
token_endpoint_auth_methods_supported: z.array(z.string()),
|
|
33
|
+
claims_supported: z.array(z.string()),
|
|
34
|
+
request_uri_parameter_supported: z.boolean(),
|
|
35
|
+
request_parameter_supported: z.boolean(),
|
|
36
|
+
token_endpoint_auth_signing_alg_values_supported: z.array(z.string()),
|
|
37
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type Variables = {};
|
package/vite.config.ts
CHANGED
|
@@ -1,11 +1,41 @@
|
|
|
1
|
+
import path from "path";
|
|
1
2
|
import { defineConfig } from "vite";
|
|
2
|
-
import { resolve } from "path";
|
|
3
|
-
import dts from "vite-plugin-dts";
|
|
4
3
|
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
const getPackageName = () => {
|
|
5
|
+
return "authhero";
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
const getPackageNameCamelCase = () => {
|
|
9
|
+
try {
|
|
10
|
+
return getPackageName().replace(/-./g, (char) => char[1].toUpperCase());
|
|
11
|
+
} catch (err) {
|
|
12
|
+
throw new Error("Name property in package.json is missing.");
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const fileName = {
|
|
17
|
+
es: `${getPackageName()}.mjs`,
|
|
18
|
+
cjs: `${getPackageName()}.cjs`,
|
|
19
|
+
iife: `${getPackageName()}.iife.js`,
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const formats = Object.keys(fileName) as Array<keyof typeof fileName>;
|
|
23
|
+
|
|
24
|
+
module.exports = defineConfig({
|
|
25
|
+
base: "./",
|
|
7
26
|
build: {
|
|
8
|
-
|
|
27
|
+
outDir: "./build/dist",
|
|
28
|
+
lib: {
|
|
29
|
+
entry: path.resolve(__dirname, "src/index.ts"),
|
|
30
|
+
name: getPackageNameCamelCase(),
|
|
31
|
+
formats,
|
|
32
|
+
fileName: (format) => fileName[format],
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
resolve: {
|
|
36
|
+
alias: [
|
|
37
|
+
{ find: "@", replacement: path.resolve(__dirname, "src") },
|
|
38
|
+
{ find: "@@", replacement: path.resolve(__dirname) },
|
|
39
|
+
],
|
|
9
40
|
},
|
|
10
|
-
plugins: [dts()],
|
|
11
41
|
});
|