feat(auth): add User, Cookie, Session entities + errors + config
This commit is contained in:
1
packages/auth/src/config.ts
Normal file
1
packages/auth/src/config.ts
Normal file
@@ -0,0 +1 @@
|
||||
export const SESSION_COOKIE = "session";
|
||||
15
packages/auth/src/entities/cookie.ts
Normal file
15
packages/auth/src/entities/cookie.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
type CookieAttributes = {
|
||||
secure?: boolean;
|
||||
path?: string;
|
||||
domain?: string;
|
||||
sameSite?: "lax" | "strict" | "none";
|
||||
httpOnly?: boolean;
|
||||
maxAge?: number;
|
||||
expires?: Date;
|
||||
};
|
||||
|
||||
export type Cookie = {
|
||||
name: string;
|
||||
value: string;
|
||||
attributes: CookieAttributes;
|
||||
};
|
||||
23
packages/auth/src/entities/errors.ts
Normal file
23
packages/auth/src/entities/errors.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
export class AuthenticationError extends Error {
|
||||
constructor(message: string, options?: ErrorOptions) {
|
||||
super(message, options);
|
||||
}
|
||||
}
|
||||
|
||||
export class UnauthenticatedError extends Error {
|
||||
constructor(message: string, options?: ErrorOptions) {
|
||||
super(message, options);
|
||||
}
|
||||
}
|
||||
|
||||
export class UnauthorizedError extends Error {
|
||||
constructor(message: string, options?: ErrorOptions) {
|
||||
super(message, options);
|
||||
}
|
||||
}
|
||||
|
||||
export class InputParseError extends Error {
|
||||
constructor(message: string, options?: ErrorOptions) {
|
||||
super(message, options);
|
||||
}
|
||||
}
|
||||
23
packages/auth/src/entities/session.test.ts
Normal file
23
packages/auth/src/entities/session.test.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { sessionSchema } from "./session";
|
||||
|
||||
describe("sessionSchema", () => {
|
||||
it("accepts a valid session", () => {
|
||||
const result = sessionSchema.parse({
|
||||
id: "session_1",
|
||||
userId: "1",
|
||||
expiresAt: new Date(),
|
||||
});
|
||||
expect(result.userId).toBe("1");
|
||||
});
|
||||
|
||||
it("rejects non-Date expiresAt", () => {
|
||||
expect(() =>
|
||||
sessionSchema.parse({
|
||||
id: "session_1",
|
||||
userId: "1",
|
||||
expiresAt: "2026-05-04",
|
||||
}),
|
||||
).toThrow();
|
||||
});
|
||||
});
|
||||
9
packages/auth/src/entities/session.ts
Normal file
9
packages/auth/src/entities/session.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { z } from "zod";
|
||||
|
||||
export const sessionSchema = z.object({
|
||||
id: z.string(),
|
||||
userId: z.string(),
|
||||
expiresAt: z.date(),
|
||||
});
|
||||
|
||||
export type Session = z.infer<typeof sessionSchema>;
|
||||
33
packages/auth/src/entities/user.test.ts
Normal file
33
packages/auth/src/entities/user.test.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { userSchema } from "./user";
|
||||
|
||||
describe("userSchema", () => {
|
||||
it("accepts a valid user", () => {
|
||||
const result = userSchema.parse({
|
||||
id: "1",
|
||||
username: "alice",
|
||||
passwordHash: "hashed_password_1",
|
||||
});
|
||||
expect(result.username).toBe("alice");
|
||||
});
|
||||
|
||||
it("rejects username shorter than 3 chars", () => {
|
||||
expect(() =>
|
||||
userSchema.parse({
|
||||
id: "1",
|
||||
username: "ab",
|
||||
passwordHash: "hashed_password_1",
|
||||
}),
|
||||
).toThrow();
|
||||
});
|
||||
|
||||
it("rejects passwordHash shorter than 6 chars", () => {
|
||||
expect(() =>
|
||||
userSchema.parse({
|
||||
id: "1",
|
||||
username: "alice",
|
||||
passwordHash: "abc",
|
||||
}),
|
||||
).toThrow();
|
||||
});
|
||||
});
|
||||
9
packages/auth/src/entities/user.ts
Normal file
9
packages/auth/src/entities/user.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { z } from "zod";
|
||||
|
||||
export const userSchema = z.object({
|
||||
id: z.string(),
|
||||
username: z.string().min(3).max(31),
|
||||
passwordHash: z.string().min(6).max(255),
|
||||
});
|
||||
|
||||
export type User = z.infer<typeof userSchema>;
|
||||
Reference in New Issue
Block a user