Working User Authorization Flow

This commit is contained in:
2026-01-26 15:56:10 -06:00
parent 8ee7dc15e5
commit 4524c0258a
8 changed files with 57 additions and 9 deletions
+3
View File
@@ -0,0 +1,3 @@
export { default as redirect } from "./redirect";
export { default as refresh } from "./refresh";
export { default as uri } from "./uri";
+17 -3
View File
@@ -1,11 +1,11 @@
import { Hono } from "hono/tiny"; import { Hono } from "hono/tiny";
import { createRoute } from "../../modules/api-utils/createRoute"; import { createRoute } from "../../modules/api-utils/createRoute";
import * as msal from "@azure/msal-node"; import * as msal from "@azure/msal-node";
import { msalClient } from "../../constants"; import { io, msalClient } from "../../constants";
import { users } from "../../managers/users"; import { users } from "../../managers/users";
/* /v1/auth/redirect */ /* /v1/auth/redirect */
export default createRoute("get", ["/"], async (c) => { export default createRoute("get", ["/redirect"], async (c) => {
c.status(200); c.status(200);
const tokenRequest: msal.AuthorizationCodeRequest = { const tokenRequest: msal.AuthorizationCodeRequest = {
@@ -15,8 +15,22 @@ export default createRoute("get", ["/"], async (c) => {
}; };
const authResult = await msalClient.acquireTokenByCode(tokenRequest); const authResult = await msalClient.acquireTokenByCode(tokenRequest);
const callbackKey = c.req.query().state as string;
const tokens = await users.authenticate(authResult);
await users.authenticate(authResult); io.of(`/auth_callback`).emit(`auth:login:callback:${callbackKey}`, {
accessToken: tokens.accessToken,
refreshToken: tokens.refreshToken,
});
console.log("Emitted auth callback for key:", callbackKey);
// Close the window because duh
return c.html(
`<script>
window.close();
</script>`,
);
return c.json({ return c.json({
status: 200, status: 200,
+3 -1
View File
@@ -3,11 +3,13 @@ import { createRoute } from "../../modules/api-utils/createRoute";
import { sessions } from "../../managers/sessions"; import { sessions } from "../../managers/sessions";
/* /v1/auth/refresh */ /* /v1/auth/refresh */
export default createRoute("post", ["/"], async (c) => { export default createRoute("post", ["/refresh"], async (c) => {
c.status(201); c.status(201);
const refreshToken = c.req.header("x-refresh-token") || ""; const refreshToken = c.req.header("x-refresh-token") || "";
console.log("Received refresh token:", refreshToken);
const session = await sessions.fetch({ const session = await sessions.fetch({
refreshToken: refreshToken, refreshToken: refreshToken,
}); });
+21
View File
@@ -0,0 +1,21 @@
import { Hono } from "hono/tiny";
import { createRoute } from "../../modules/api-utils/createRoute";
import cuid from "cuid";
/* /v1/auth/uri */
export default createRoute("get", ["/uri"], (c) => {
c.status(200);
const callbackKey = cuid();
const msUri = `https://login.microsoftonline.com/${process.env.MICROSOFT_TENANT_ID}/oauth2/v2.0/authorize?client_id=${process.env.MICROSOFT_CLIENT_ID}&response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fv1%2Fauth%2Fredirect&scope=openid+User.Read&state=${callbackKey}&prompt=login`;
return c.json({
status: 200,
message: "Successfully fetch Auth URI",
data: {
uri: msUri,
callbackKey: callbackKey,
},
successful: true,
});
});
+7
View File
@@ -0,0 +1,7 @@
import { Hono } from "hono";
import * as authRoles from "../auth";
const authRouter = new Hono();
Object.values(authRoles).map((r) => authRouter.route("/", r));
export default authRouter;
+3 -4
View File
@@ -24,7 +24,7 @@ app.onError((err, ctx) => {
return ctx.json( return ctx.json(
apiResponse.zodError(err), apiResponse.zodError(err),
//@ts-ignore //@ts-ignore
apiResponse.zodError(err).status apiResponse.zodError(err).status,
); );
} }
@@ -41,14 +41,13 @@ app.notFound((c) => {
message: `Cannot ${c.req.method.toUpperCase()} ${c.req.path}`, message: `Cannot ${c.req.method.toUpperCase()} ${c.req.path}`,
status: 404, status: 404,
cause: "Unknown", cause: "Unknown",
}) }),
); );
return c.json(response, response.status); return c.json(response, response.status);
}); });
v1.route("/teapot", teapot); v1.route("/teapot", teapot);
v1.route("/auth/redirect", await import("./auth/redirect").then(m => m.default)); v1.route("/auth", require("./routers/authRouter").default);
app.route("/v1", v1); app.route("/v1", v1);
export default app; export default app;
+1
View File
@@ -50,6 +50,7 @@ export const msalClient = new msal.ConfidentialClientApplication(msalConfig);
// Socket.io // Socket.io
const io = new Server(); const io = new Server();
const authIO = io.of("/auth_callback");
const engine = new Engine(); const engine = new Engine();
io.bind(engine); io.bind(engine);
+1
View File
@@ -3,6 +3,7 @@ import { engine, PORT } from "./constants";
Bun.serve({ Bun.serve({
port: PORT, port: PORT,
websocket: engine.handler().websocket,
fetch: (req, server) => { fetch: (req, server) => {
const url = new URL(req.url); const url = new URL(req.url);