Add Session class to provide getUser() on call.session
Wraps SessionData and user into a Session class that handlers can use via call.session.getUser() instead of accessing services directly. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -3,6 +3,7 @@ import express, {
|
||||
type Response as ExpressResponse,
|
||||
} from "express";
|
||||
import { match } from "path-to-regexp";
|
||||
import { Session } from "./auth";
|
||||
import { cli } from "./cli";
|
||||
import { contentTypes } from "./content-types";
|
||||
import { httpCodes } from "./http-codes";
|
||||
@@ -68,7 +69,7 @@ routes.forEach((route: Route, _idx: number, _allRoutes: Route[]) => {
|
||||
parameters: { one: 1, two: 2 },
|
||||
request,
|
||||
user: auth.user,
|
||||
session: auth.session,
|
||||
session: new Session(auth.session, auth.user),
|
||||
};
|
||||
|
||||
try {
|
||||
|
||||
@@ -10,4 +10,11 @@ export { hashPassword, verifyPassword } from "./password";
|
||||
export { AuthService, type AuthResult } from "./service";
|
||||
export { type AuthStore, InMemoryAuthStore } from "./store";
|
||||
export { generateToken, hashToken, SESSION_COOKIE_NAME } from "./token";
|
||||
export * from "./types";
|
||||
export {
|
||||
type AuthMethod,
|
||||
type SessionData,
|
||||
type TokenId,
|
||||
type TokenType,
|
||||
Session,
|
||||
tokenLifetimes,
|
||||
} from "./types";
|
||||
|
||||
@@ -62,3 +62,35 @@ export const tokenLifetimes: Record<TokenType, number> = {
|
||||
password_reset: 1 * 60 * 60 * 1000, // 1 hour
|
||||
email_verify: 24 * 60 * 60 * 1000, // 24 hours
|
||||
};
|
||||
|
||||
// Import here to avoid circular dependency at module load time
|
||||
import { AnonymousUser, type MaybeUser } from "../user";
|
||||
|
||||
// Session wrapper class providing a consistent interface for handlers.
|
||||
// Always present on Call (never null), but may represent an anonymous session.
|
||||
export class Session {
|
||||
constructor(
|
||||
private readonly data: SessionData | null,
|
||||
private readonly user: MaybeUser,
|
||||
) {}
|
||||
|
||||
getUser(): MaybeUser {
|
||||
return this.user;
|
||||
}
|
||||
|
||||
getData(): SessionData | null {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
isAuthenticated(): boolean {
|
||||
return this.user !== AnonymousUser;
|
||||
}
|
||||
|
||||
get tokenId(): string | undefined {
|
||||
return this.data?.tokenId;
|
||||
}
|
||||
|
||||
get userId(): string | undefined {
|
||||
return this.data?.userId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,19 +51,35 @@ const routes: Route[] = [
|
||||
return ret;
|
||||
};
|
||||
|
||||
const rrr = lr(routes)
|
||||
|
||||
const template=`
|
||||
<html>
|
||||
<head></head>
|
||||
<body>
|
||||
<ul>
|
||||
{% for route in rrr %}
|
||||
<li><a href="{{ route }}">{{ route }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
`
|
||||
const result = nunjucks.renderString(template,{rrr})
|
||||
|
||||
const listing = lr(routes).join(", ");
|
||||
return {
|
||||
code,
|
||||
result: listing + "\n",
|
||||
contentType: contentTypes.text.plain,
|
||||
result,
|
||||
contentType: contentTypes.text.html,
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "/whoami",
|
||||
methods: ["GET"],
|
||||
handler: async (_call: Call): Promise<Result> => {
|
||||
const me = services.session.getUser();
|
||||
handler: async (call: Call): Promise<Result> => {
|
||||
const me = call.session.getUser();
|
||||
const template = `
|
||||
<html>
|
||||
<head></head>
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
} from "express";
|
||||
import type { MatchFunction } from "path-to-regexp";
|
||||
import { z } from "zod";
|
||||
import type { SessionData } from "./auth/types";
|
||||
import type { Session } from "./auth/types";
|
||||
import { type ContentType, contentTypes } from "./content-types";
|
||||
import { type HttpCode, httpCodes } from "./http-codes";
|
||||
import {
|
||||
@@ -40,7 +40,7 @@ export type Call = {
|
||||
parameters: object;
|
||||
request: ExpressRequest;
|
||||
user: MaybeUser;
|
||||
session: SessionData | null;
|
||||
session: Session;
|
||||
};
|
||||
|
||||
export type InternalHandler = (req: ExpressRequest) => Promise<Result>;
|
||||
|
||||
Reference in New Issue
Block a user