@bernouy/socle 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 matthias-bernouy
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1 @@
1
+ # DASS
package/dist/app.d.ts ADDED
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,69 @@
1
+ import type { IBe5_AccountSummary, IBe5_Authentication, IBe5_Subject } from "../../interfaces/AuthInterface";
2
+ import type { IBe5_Runner, Middleware } from "../../interfaces/RunnerInterface";
3
+ import type { IBe5_Mailer } from "../../interfaces/MailerInterface";
4
+ import type { AuthRepository } from "./interfaces/repository/AuthRepository";
5
+ interface Be5_TokenPayload {
6
+ email: string;
7
+ role: "admin" | "user";
8
+ sub: string;
9
+ }
10
+ export type AuthConfig = {
11
+ basePath?: string;
12
+ registerDisabled?: boolean;
13
+ defaultRedirection?: string;
14
+ /**
15
+ * Absolute public base URL of the app (e.g. "https://app.example.com").
16
+ * Required for features that embed links in emails. If absent, reset
17
+ * links fall back to a relative URL (which may not be clickable in mail
18
+ * clients but still works for dev).
19
+ */
20
+ baseUrl?: string;
21
+ /**
22
+ * Optional mailer. If omitted, email-dependent features
23
+ * (requestPasswordReset) throw and the HTTP routes return 503.
24
+ */
25
+ mailer?: IBe5_Mailer;
26
+ /** Lifetime of a password reset token in minutes. Defaults to 30. */
27
+ resetTokenTtlMinutes?: number;
28
+ /** "From" address used for outgoing auth emails. */
29
+ mailFrom?: string;
30
+ };
31
+ export declare class Authentication implements IBe5_Authentication {
32
+ registerDisabled: boolean;
33
+ defaultRedirection: string;
34
+ private _repository;
35
+ private _mailer;
36
+ private _baseUrl;
37
+ private _resetTtlMs;
38
+ private _mailFrom;
39
+ private _basePath;
40
+ readonly loginPage: string;
41
+ readonly registerPage: string;
42
+ readonly recoverPage: string;
43
+ readonly resetPage: string;
44
+ readonly logoutPage: string;
45
+ readonly setupPage: string;
46
+ readonly adminAccountsPage: string;
47
+ constructor(repository: AuthRepository, runner: IBe5_Runner, config?: AuthConfig);
48
+ get repository(): AuthRepository;
49
+ get mailEnabled(): boolean;
50
+ getSubject(req: Request): Promise<IBe5_Subject | null>;
51
+ isAuthenticated(req: Request): Promise<boolean>;
52
+ guardAuthenticated(req: Request): Promise<IBe5_Subject>;
53
+ guardAdmin(req: Request): Promise<IBe5_Subject>;
54
+ withRedirect(page: string, redirect: string): string;
55
+ get requireAuthenticated(): Middleware;
56
+ get requireAdmin(): Middleware;
57
+ logout(): Response;
58
+ requestPasswordReset(email: string): Promise<void>;
59
+ resetPassword(token: string, newPassword: string): Promise<void>;
60
+ changePassword(req: Request, currentPassword: string, newPassword: string): Promise<void>;
61
+ listAccounts(): Promise<IBe5_AccountSummary[]>;
62
+ createAccount(identifier: string, password: string, role: "admin" | "user"): Promise<IBe5_Subject>;
63
+ deleteAccount(identifier: string): Promise<void>;
64
+ setAccountRole(identifier: string, role: "admin" | "user"): Promise<void>;
65
+ private countAdmins;
66
+ }
67
+ /** Convenience factory: produces a signed JWT for use by login handlers. */
68
+ export declare function signAuthJwt(payload: Be5_TokenPayload): Promise<string>;
69
+ export {};
@@ -0,0 +1,5 @@
1
+ import type { Authentication } from "../Authentication";
2
+ export declare function adminListAccounts(_req: Request, system: Authentication): Promise<Response>;
3
+ export declare function adminCreateAccount(req: Request, system: Authentication): Promise<Response>;
4
+ export declare function adminDeleteAccount(req: Request, system: Authentication): Promise<Response>;
5
+ export declare function adminUpdateRole(req: Request, system: Authentication): Promise<Response>;
@@ -0,0 +1,2 @@
1
+ import type { Authentication } from "../Authentication";
2
+ export declare function changePasswordSubmit(req: Request, system: Authentication): Promise<Response>;
@@ -0,0 +1,2 @@
1
+ import type { Authentication } from "../Authentication";
2
+ export declare function loginSubmit(req: Request, system: Authentication): Promise<Response>;
@@ -0,0 +1,2 @@
1
+ import type { Authentication } from "../Authentication";
2
+ export declare function logoutHandler(_req: Request, system: Authentication): Response;
@@ -0,0 +1,2 @@
1
+ import type { Authentication } from "../Authentication";
2
+ export declare function recoverSubmit(req: Request, system: Authentication): Promise<Response>;
@@ -0,0 +1,2 @@
1
+ import type { Authentication } from "../Authentication";
2
+ export declare function registerSubmit(req: Request, system: Authentication): Promise<Response>;
@@ -0,0 +1,2 @@
1
+ import type { Authentication } from "../Authentication";
2
+ export declare function resetSubmit(req: Request, system: Authentication): Promise<Response>;
@@ -0,0 +1,6 @@
1
+ import type { Authentication } from "../Authentication";
2
+ /**
3
+ * Creates the very first admin account.
4
+ * 409 if any account already exists — this endpoint is meant to run exactly once.
5
+ */
6
+ export declare function setupSubmit(req: Request, system: Authentication): Promise<Response>;
@@ -0,0 +1,26 @@
1
+ import { MongoClient } from "mongodb";
2
+ import type { AuthRepository, TSubject } from "../repository/AuthRepository";
3
+ type DefaultDatastoreConfig = {
4
+ uri: string;
5
+ databaseName: string;
6
+ };
7
+ /**
8
+ * Default MongoDB-backed implementation of AuthRepository.
9
+ */
10
+ export declare class AuthRepositoryProvider implements AuthRepository {
11
+ private _database;
12
+ private _accountCollection;
13
+ constructor(client: MongoClient, databaseName: string);
14
+ static create(config: DefaultDatastoreConfig): Promise<AuthRepositoryProvider>;
15
+ findByEmail(email: string): Promise<TSubject | null>;
16
+ findByResetTokenHash(tokenHash: string): Promise<TSubject | null>;
17
+ register(subject: TSubject): Promise<TSubject>;
18
+ updatePassword(email: string, passwordHash: string): Promise<void>;
19
+ updateRole(email: string, role: 'admin' | 'user'): Promise<void>;
20
+ setResetToken(email: string, tokenHash: string, expiresAt: Date): Promise<void>;
21
+ clearResetToken(email: string): Promise<void>;
22
+ delete(email: string): Promise<void>;
23
+ list(): Promise<TSubject[]>;
24
+ count(): Promise<number>;
25
+ }
26
+ export {};
@@ -0,0 +1,23 @@
1
+ export type TSubject = {
2
+ id?: string;
3
+ email: string;
4
+ passwordHash: string;
5
+ role: 'admin' | 'user';
6
+ createdAt?: Date;
7
+ /** sha256 hex of the active password-reset token, or null. */
8
+ passwordResetTokenHash?: string | null;
9
+ /** Expiry of the active reset token. */
10
+ passwordResetExpiresAt?: Date | null;
11
+ };
12
+ export interface AuthRepository {
13
+ findByEmail(email: string): Promise<TSubject | null>;
14
+ findByResetTokenHash(tokenHash: string): Promise<TSubject | null>;
15
+ register(subject: TSubject): Promise<TSubject>;
16
+ updatePassword(email: string, passwordHash: string): Promise<void>;
17
+ updateRole(email: string, role: 'admin' | 'user'): Promise<void>;
18
+ setResetToken(email: string, tokenHash: string, expiresAt: Date): Promise<void>;
19
+ clearResetToken(email: string): Promise<void>;
20
+ delete(email: string): Promise<void>;
21
+ list(): Promise<TSubject[]>;
22
+ count(): Promise<number>;
23
+ }
@@ -0,0 +1 @@
1
+ export declare function send_html(content: string): Response;
@@ -0,0 +1,12 @@
1
+ import type { Be5_MailMessage, IBe5_Mailer } from "../../interfaces/MailerInterface";
2
+ /**
3
+ * Default mailer used for development and tests.
4
+ *
5
+ * It does not actually send anything — it just prints the message to stdout.
6
+ * Useful to inspect password reset links without configuring SMTP.
7
+ */
8
+ export declare class ConsoleMailerProvider implements IBe5_Mailer {
9
+ private readonly defaultFrom;
10
+ constructor(defaultFrom?: string);
11
+ send(message: Be5_MailMessage): Promise<void>;
12
+ }
@@ -0,0 +1,24 @@
1
+ import type { Be5_MailMessage, IBe5_Mailer } from "../../interfaces/MailerInterface";
2
+ export type SmtpMailerConfig = {
3
+ host: string;
4
+ port: number;
5
+ secure?: boolean;
6
+ auth?: {
7
+ user: string;
8
+ pass: string;
9
+ };
10
+ defaultFrom: string;
11
+ };
12
+ /**
13
+ * SMTP-backed mailer built on top of nodemailer.
14
+ *
15
+ * Nodemailer is imported dynamically so that consumers who only use the
16
+ * ConsoleMailerProvider don't pay the cost of pulling it in.
17
+ */
18
+ export declare class SmtpMailerProvider implements IBe5_Mailer {
19
+ private readonly config;
20
+ private _transporter;
21
+ constructor(config: SmtpMailerConfig);
22
+ private transporter;
23
+ send(message: Be5_MailMessage): Promise<void>;
24
+ }
@@ -0,0 +1,15 @@
1
+ import type { IBe5_Runner, RouteHandler, Middleware } from "src/interfaces/RunnerInterface";
2
+ export declare class Be5_Runner implements IBe5_Runner {
3
+ private routes;
4
+ private globalMiddlewares;
5
+ addEndpoint(method: string, path: string, handler: RouteHandler, middlewares?: Middleware[]): void;
6
+ use(middleware: Middleware): void;
7
+ group(prefix: string, callback: (runner: IBe5_Runner) => void, middlewares?: Middleware[]): void;
8
+ get(path: string, handler: RouteHandler, middlewares?: Middleware[]): void;
9
+ post(path: string, handler: RouteHandler, middlewares?: Middleware[]): void;
10
+ patch(path: string, handler: RouteHandler, middlewares?: Middleware[]): void;
11
+ delete(path: string, handler: RouteHandler, middlewares?: Middleware[]): void;
12
+ put(path: string, handler: RouteHandler, middlewares?: Middleware[]): void;
13
+ start(port?: number): void;
14
+ private matchPath;
15
+ }
@@ -0,0 +1,9 @@
1
+ export * from "./default/AuthenticationProvider/Authentication";
2
+ export * from "./default/AuthenticationProvider/interfaces/default-provider/AuthRepositoryProvider";
3
+ export * from "./default/AuthenticationProvider/interfaces/repository/AuthRepository";
4
+ export * from "./default/RunnerProvider";
5
+ export * from "./default/MailerProvider/ConsoleMailerProvider";
6
+ export * from "./default/MailerProvider/SmtpMailerProvider";
7
+ export * from "./interfaces/RunnerInterface";
8
+ export * from "./interfaces/AuthInterface";
9
+ export * from "./interfaces/MailerInterface";