Add session data to Call type
- AuthService.validateRequest now returns AuthResult with both user and session - Call type includes session: SessionData | null - Handlers can access session metadata (createdAt, authMethod, etc.) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -59,7 +59,7 @@ routes.forEach((route: Route, _idx: number, _allRoutes: Route[]) => {
|
|||||||
console.log("request.originalUrl", request.originalUrl);
|
console.log("request.originalUrl", request.originalUrl);
|
||||||
|
|
||||||
// Authenticate the request
|
// Authenticate the request
|
||||||
const user = await services.auth.validateRequest(request);
|
const auth = await services.auth.validateRequest(request);
|
||||||
|
|
||||||
const req: Call = {
|
const req: Call = {
|
||||||
pattern: route.path,
|
pattern: route.path,
|
||||||
@@ -67,7 +67,8 @@ routes.forEach((route: Route, _idx: number, _allRoutes: Route[]) => {
|
|||||||
method,
|
method,
|
||||||
parameters: { one: 1, two: 2 },
|
parameters: { one: 1, two: 2 },
|
||||||
request,
|
request,
|
||||||
user,
|
user: auth.user,
|
||||||
|
session: auth.session,
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
// Import authRoutes directly from "./auth/routes" instead.
|
// Import authRoutes directly from "./auth/routes" instead.
|
||||||
|
|
||||||
export { hashPassword, verifyPassword } from "./password";
|
export { hashPassword, verifyPassword } from "./password";
|
||||||
export { AuthService } from "./service";
|
export { AuthService, type AuthResult } from "./service";
|
||||||
export { type AuthStore, InMemoryAuthStore } from "./store";
|
export { type AuthStore, InMemoryAuthStore } from "./store";
|
||||||
export { generateToken, hashToken, SESSION_COOKIE_NAME } from "./token";
|
export { generateToken, hashToken, SESSION_COOKIE_NAME } from "./token";
|
||||||
export * from "./types";
|
export * from "./types";
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import {
|
|||||||
parseAuthorizationHeader,
|
parseAuthorizationHeader,
|
||||||
SESSION_COOKIE_NAME,
|
SESSION_COOKIE_NAME,
|
||||||
} from "./token";
|
} from "./token";
|
||||||
import { type TokenId, tokenLifetimes } from "./types";
|
import { type SessionData, type TokenId, tokenLifetimes } from "./types";
|
||||||
|
|
||||||
type LoginResult =
|
type LoginResult =
|
||||||
| { success: true; token: string; user: User }
|
| { success: true; token: string; user: User }
|
||||||
@@ -24,6 +24,11 @@ type RegisterResult =
|
|||||||
|
|
||||||
type SimpleResult = { success: true } | { success: false; error: string };
|
type SimpleResult = { success: true } | { success: false; error: string };
|
||||||
|
|
||||||
|
// Result of validating a request/token - contains both user and session
|
||||||
|
export type AuthResult =
|
||||||
|
| { authenticated: true; user: User; session: SessionData }
|
||||||
|
| { authenticated: false; user: typeof AnonymousUser; session: null };
|
||||||
|
|
||||||
export class AuthService {
|
export class AuthService {
|
||||||
constructor(private store: AuthStore) {}
|
constructor(private store: AuthStore) {}
|
||||||
|
|
||||||
@@ -68,7 +73,7 @@ export class AuthService {
|
|||||||
|
|
||||||
// === Session Validation ===
|
// === Session Validation ===
|
||||||
|
|
||||||
async validateRequest(request: ExpressRequest): Promise<MaybeUser> {
|
async validateRequest(request: ExpressRequest): Promise<AuthResult> {
|
||||||
// Try cookie first (for web requests)
|
// Try cookie first (for web requests)
|
||||||
let token = this.extractCookieToken(request);
|
let token = this.extractCookieToken(request);
|
||||||
|
|
||||||
@@ -78,33 +83,33 @@ export class AuthService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!token) {
|
if (!token) {
|
||||||
return AnonymousUser;
|
return { authenticated: false, user: AnonymousUser, session: null };
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.validateToken(token);
|
return this.validateToken(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
async validateToken(token: string): Promise<MaybeUser> {
|
async validateToken(token: string): Promise<AuthResult> {
|
||||||
const tokenId = hashToken(token) as TokenId;
|
const tokenId = hashToken(token) as TokenId;
|
||||||
const session = await this.store.getSession(tokenId);
|
const session = await this.store.getSession(tokenId);
|
||||||
|
|
||||||
if (!session) {
|
if (!session) {
|
||||||
return AnonymousUser;
|
return { authenticated: false, user: AnonymousUser, session: null };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (session.tokenType !== "session") {
|
if (session.tokenType !== "session") {
|
||||||
return AnonymousUser;
|
return { authenticated: false, user: AnonymousUser, session: null };
|
||||||
}
|
}
|
||||||
|
|
||||||
const user = await this.store.getUserById(session.userId as UserId);
|
const user = await this.store.getUserById(session.userId as UserId);
|
||||||
if (!user || !user.isActive()) {
|
if (!user || !user.isActive()) {
|
||||||
return AnonymousUser;
|
return { authenticated: false, user: AnonymousUser, session: null };
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update last used (fire and forget)
|
// Update last used (fire and forget)
|
||||||
this.store.updateLastUsed(tokenId).catch(() => {});
|
this.store.updateLastUsed(tokenId).catch(() => {});
|
||||||
|
|
||||||
return user;
|
return { authenticated: true, user, session };
|
||||||
}
|
}
|
||||||
|
|
||||||
private extractCookieToken(request: ExpressRequest): string | null {
|
private extractCookieToken(request: ExpressRequest): string | null {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import {
|
|||||||
} from "express";
|
} from "express";
|
||||||
import type { MatchFunction } from "path-to-regexp";
|
import type { MatchFunction } from "path-to-regexp";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
import type { SessionData } from "./auth/types";
|
||||||
import { type ContentType, contentTypes } from "./content-types";
|
import { type ContentType, contentTypes } from "./content-types";
|
||||||
import { type HttpCode, httpCodes } from "./http-codes";
|
import { type HttpCode, httpCodes } from "./http-codes";
|
||||||
import {
|
import {
|
||||||
@@ -39,6 +40,7 @@ export type Call = {
|
|||||||
parameters: object;
|
parameters: object;
|
||||||
request: ExpressRequest;
|
request: ExpressRequest;
|
||||||
user: MaybeUser;
|
user: MaybeUser;
|
||||||
|
session: SessionData | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type InternalHandler = (req: ExpressRequest) => Promise<Result>;
|
export type InternalHandler = (req: ExpressRequest) => Promise<Result>;
|
||||||
|
|||||||
Reference in New Issue
Block a user