UNPKG

alepha

Version:

Easy-to-use modern TypeScript framework for building many kind of applications.

205 lines (179 loc) 5.1 kB
import { randomUUID } from "node:crypto"; import { Alepha } from "alepha"; import { DateTimeProvider } from "alepha/datetime"; import { $issuer, AlephaSecurity } from "alepha/security"; import { AlephaServer, HttpClient, ServerProvider } from "alepha/server"; import { $auth, alephaServerAuthRoutes, type TokenResponse, tokenResponseSchema, tokensSchema, } from "alepha/server/auth"; import { $client } from "alepha/server/links"; import { describe, test } from "vitest"; import { ReactAuth, type ReactAuthProvider } from "../index.ts"; describe("$auth", () => { const user = { id: randomUUID(), name: "John Doe", username: "john", password: "***", roles: ["admin"], }; class App { issuer = $issuer({ secret: "my-secret-key", roles: [ { name: "admin", permissions: [{ name: "*" }], }, ], }); auth = $auth({ issuer: this.issuer, credentials: { account: () => user, }, }); api = $client<ReactAuthProvider>(); } const userinfo = (alepha: Alepha, token?: string) => alepha .inject(HttpClient) .fetch( `${alepha.inject(ServerProvider).hostname}${alephaServerAuthRoutes.userinfo}`, { method: "GET", headers: { authorization: `Bearer ${token}`, }, }, ) .then((it) => it.data); const login = (alepha: Alepha) => alepha .inject(HttpClient) .fetch( `${alepha.inject(ServerProvider).hostname}${alephaServerAuthRoutes.token}?provider=auth`, { method: "POST", body: JSON.stringify({ username: user.username, password: user.password, }), schema: { response: tokenResponseSchema, }, }, ); const refresh = (alepha: Alepha, tokens: TokenResponse) => alepha .inject(HttpClient) .fetch( `${alepha.inject(ServerProvider).hostname}${alephaServerAuthRoutes.refresh}?provider=auth`, { method: "POST", body: JSON.stringify({ refresh_token: tokens.refresh_token!, access_token: tokens.access_token, }), schema: { response: tokensSchema, }, }, ); test("should login with credentials", async ({ expect }) => { const alepha = Alepha.create() .with(AlephaServer) .with(AlephaSecurity) .with(App); const auth = alepha.inject(ReactAuth); await alepha.start(); expect(auth.user).toBeUndefined(); await auth.login("auth", { username: user.username, password: user.password, hostname: alepha.inject(ServerProvider).hostname, }); expect(auth.user).toEqual({ id: user.id, name: user.name, roles: user.roles, username: user.username, }); }); test("should get userinfo", async ({ expect }) => { const alepha = Alepha.create() .with(AlephaServer) .with(AlephaSecurity) .with(App); await alepha.start(); const { data: tokens } = await login(alepha); expect(await userinfo(alepha, tokens.access_token)).toEqual({ user: { id: user.id, name: user.name, roles: user.roles, username: user.username, sessionId: expect.any(String), realm: "issuer", }, api: { prefix: "/api", actions: {}, }, }); }); test("should reject expired token", async ({ expect }) => { const alepha = Alepha.create() .with(AlephaServer) .with(AlephaSecurity) .with(App); await alepha.start(); const { data: tokens } = await login(alepha); await alepha.inject(DateTimeProvider).travel(1, "hour"); expect(await userinfo(alepha, tokens.access_token)).toEqual({ api: { prefix: "/api", actions: {}, }, }); }); test("should refresh expired token", async ({ expect }) => { const alepha = Alepha.create() .with(AlephaServer) .with(AlephaSecurity) .with(App); await alepha.start(); const { data: tokens } = await login(alepha); await alepha.inject(DateTimeProvider).travel(1, "hour"); const { data: tokens2 } = await refresh(alepha, tokens); expect(await userinfo(alepha, tokens2.access_token)).toEqual({ user: { id: user.id, name: user.name, roles: user.roles, username: user.username, realm: "issuer", }, api: { prefix: "/api", actions: {}, }, }); }); test("should reject expired refresh token", async ({ expect }) => { const alepha = Alepha.create() .with(AlephaServer) .with(AlephaSecurity) .with(App); await alepha.start(); const { data: tokens } = await login(alepha); await alepha.inject(DateTimeProvider).travel(40, "days"); await expect(refresh(alepha, tokens)).rejects.toThrowError( "Failed to refresh access token using the refresh token (issuer)", ); }); });