|
1 | 1 | import { z, createRoute, OpenAPIHono } from "@hono/zod-openapi"; |
2 | 2 | import { serve } from "@hono/node-server"; |
3 | | -import { HTTPException } from "hono/http-exception"; |
4 | 3 | import { getUserTodoStore } from "./todo"; |
5 | 4 | import { cors } from "hono/cors"; |
6 | 5 | import { assert } from "tsafe/assert"; |
7 | | -import { createDecodeAccessToken } from "./oidc"; |
| 6 | +import { getUser, bootstrapAuth } from "./auth"; |
8 | 7 |
|
9 | 8 | (async function main() { |
10 | | - const { decodeAccessToken } = await createDecodeAccessToken({ |
11 | | - issuerUri: (() => { |
12 | | - const value = process.env.OIDC_ISSUER_URI; |
13 | 9 |
|
14 | | - assert(value !== undefined, "OIDC_ISSUER_URI must be defined"); |
| 10 | + const issuerUri = (() => { |
| 11 | + const value = process.env.OIDC_ISSUER_URI; |
15 | 12 |
|
16 | | - return value; |
17 | | - })(), |
18 | | - audience: (() => { |
19 | | - const value = process.env.OIDC_AUDIENCE; |
| 13 | + assert(value !== undefined, "OIDC_ISSUER_URI must be defined"); |
20 | 14 |
|
21 | | - assert(value !== undefined, "OIDC_AUDIENCE must be defined"); |
| 15 | + return value; |
| 16 | + })(); |
22 | 17 |
|
23 | | - return value; |
24 | | - })() |
| 18 | + const audience = (() => { |
| 19 | + const value = process.env.OIDC_AUDIENCE; |
| 20 | + |
| 21 | + assert(value !== undefined, "OIDC_AUDIENCE must be defined"); |
| 22 | + |
| 23 | + return value; |
| 24 | + })(); |
| 25 | + |
| 26 | + bootstrapAuth({ |
| 27 | + implementation: "real", |
| 28 | + issuerUri, |
| 29 | + expectedAudience: audience |
25 | 30 | }); |
26 | 31 |
|
27 | 32 | const app = new OpenAPIHono(); |
@@ -83,16 +88,17 @@ import { createDecodeAccessToken } from "./oidc"; |
83 | 88 | }); |
84 | 89 |
|
85 | 90 | app.openapi(route, async c => { |
86 | | - const decodedAccessToken = await decodeAccessToken({ |
87 | | - authorizationHeaderValue: c.req.header("Authorization") |
88 | | - }); |
| 91 | + |
| 92 | + const user = await getUser(c.req); |
89 | 93 |
|
90 | 94 | const { id } = c.req.valid("param"); |
91 | 95 | const { text, isDone } = c.req.valid("json"); |
92 | 96 |
|
93 | | - const todoStore = getUserTodoStore(decodedAccessToken.sub); |
| 97 | + const todoStore = getUserTodoStore(user.id); |
94 | 98 |
|
95 | | - const todo = todoStore.getAll().find(({ id: todoId }) => todoId === id); |
| 99 | + const todo = todoStore |
| 100 | + .getAll() |
| 101 | + .find(({ id: todoId }) => todoId === id); |
96 | 102 |
|
97 | 103 | assert(todo !== undefined); |
98 | 104 |
|
@@ -139,28 +145,24 @@ import { createDecodeAccessToken } from "./oidc"; |
139 | 145 | schema: z.object({ |
140 | 146 | id: z.string().openapi({ |
141 | 147 | example: "123", |
142 | | - description: "The id of the newly created todo item" |
| 148 | + description: |
| 149 | + "The id of the newly created todo item" |
143 | 150 | }) |
144 | 151 | }) |
145 | 152 | } |
146 | 153 | }, |
147 | | - description: "Create a new todo item returns the newly created todo item's id" |
| 154 | + description: |
| 155 | + "Create a new todo item returns the newly created todo item's id" |
148 | 156 | } |
149 | 157 | } |
150 | 158 | }); |
151 | 159 |
|
152 | 160 | app.openapi(route, async c => { |
153 | | - const decodedAccessToken = await decodeAccessToken({ |
154 | | - authorizationHeaderValue: c.req.header("Authorization") |
155 | | - }); |
156 | | - |
157 | | - if (decodedAccessToken === undefined) { |
158 | | - throw new HTTPException(401); |
159 | | - } |
| 161 | + const user = await getUser(c.req); |
160 | 162 |
|
161 | 163 | const { text } = c.req.valid("json"); |
162 | 164 |
|
163 | | - const todoStore = getUserTodoStore(decodedAccessToken.sub); |
| 165 | + const todoStore = getUserTodoStore(user.id); |
164 | 166 |
|
165 | 167 | const id = Math.random().toString(); |
166 | 168 |
|
@@ -205,15 +207,9 @@ import { createDecodeAccessToken } from "./oidc"; |
205 | 207 | }); |
206 | 208 |
|
207 | 209 | app.openapi(route, async c => { |
208 | | - const decodedAccessToken = await decodeAccessToken({ |
209 | | - authorizationHeaderValue: c.req.header("Authorization") |
210 | | - }); |
211 | | - |
212 | | - if (decodedAccessToken === undefined) { |
213 | | - throw new HTTPException(401); |
214 | | - } |
| 210 | + const user = await getUser(c.req); |
215 | 211 |
|
216 | | - const todos = getUserTodoStore(decodedAccessToken.sub).getAll(); |
| 212 | + const todos = getUserTodoStore(user.id).getAll(); |
217 | 213 |
|
218 | 214 | return c.json(todos); |
219 | 215 | }); |
@@ -245,17 +241,11 @@ import { createDecodeAccessToken } from "./oidc"; |
245 | 241 | }); |
246 | 242 |
|
247 | 243 | app.openapi(route, async c => { |
248 | | - const decodedAccessToken = await decodeAccessToken({ |
249 | | - authorizationHeaderValue: c.req.header("Authorization") |
250 | | - }); |
| 244 | + const user = await getUser(c.req); |
251 | 245 |
|
252 | 246 | const { id } = c.req.valid("param"); |
253 | 247 |
|
254 | | - if (decodedAccessToken === undefined) { |
255 | | - throw new HTTPException(401); |
256 | | - } |
257 | | - |
258 | | - getUserTodoStore(decodedAccessToken.sub).remove(id); |
| 248 | + getUserTodoStore(user.id).remove(id); |
259 | 249 |
|
260 | 250 | return c.json({ |
261 | 251 | message: "Todo item deleted" |
@@ -284,5 +274,7 @@ import { createDecodeAccessToken } from "./oidc"; |
284 | 274 | port |
285 | 275 | }); |
286 | 276 |
|
287 | | - console.log(`\nServer running. OpenAPI documentation available at http://localhost:${port}/doc`); |
| 277 | + console.log( |
| 278 | + `\nServer running. OpenAPI documentation available at http://localhost:${port}/doc` |
| 279 | + ); |
288 | 280 | })(); |
0 commit comments