@binary1702/auth 0.2.5 → 0.4.0
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/AGENTS.md +155 -0
- package/CHANGELOG.md +49 -0
- package/INSTALL.md +27 -16
- package/PROMPT.md +325 -36
- package/README.md +338 -53
- package/dist/cli.js +248 -17
- package/dist/core/admin-html.d.ts +32 -0
- package/dist/core/admin-html.js +350 -0
- package/dist/core/admin.d.ts +56 -0
- package/dist/core/admin.js +90 -0
- package/dist/core/config.d.ts +10 -3
- package/dist/core/config.js +22 -8
- package/dist/core/db.d.ts +155 -10
- package/dist/core/db.js +449 -69
- package/dist/core/email.d.ts +49 -0
- package/dist/core/email.js +213 -0
- package/dist/core/guard.d.ts +52 -0
- package/dist/core/guard.js +106 -0
- package/dist/core/html.d.ts +43 -0
- package/dist/core/html.js +122 -28
- package/dist/core/invite.d.ts +7 -0
- package/dist/core/invite.js +30 -0
- package/dist/core/options.d.ts +95 -0
- package/dist/core/options.js +377 -0
- package/dist/core/org.d.ts +43 -0
- package/dist/core/org.js +65 -0
- package/dist/core/pages.d.ts +34 -0
- package/dist/core/pages.js +73 -0
- package/dist/core/password.d.ts +16 -0
- package/dist/core/password.js +41 -12
- package/dist/core/rate.d.ts +26 -0
- package/dist/core/rate.js +70 -0
- package/dist/core/reset.d.ts +9 -0
- package/dist/core/reset.js +31 -0
- package/dist/core/session.d.ts +11 -1
- package/dist/core/session.js +27 -7
- package/dist/core/signup.d.ts +13 -6
- package/dist/core/signup.js +30 -15
- package/dist/core/tokens.d.ts +29 -0
- package/dist/core/tokens.js +64 -0
- package/dist/core/verify.d.ts +8 -0
- package/dist/core/verify.js +33 -0
- package/dist/core/yaml.d.ts +10 -0
- package/dist/core/yaml.js +85 -0
- package/dist/index.d.ts +18 -6
- package/dist/index.js +18 -6
- package/dist/next/index.d.ts +10 -3
- package/dist/next/index.js +649 -63
- package/dist/next/proxy.d.ts +2 -1
- package/dist/next/proxy.js +22 -10
- package/dist/react/index.d.ts +72 -0
- package/dist/react/index.js +107 -0
- package/package.json +18 -4
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
// ─────────────────────────────────────────────────────────────
|
|
2
|
+
// The subset of YAML that b17_auth.yaml uses. No dependency.
|
|
3
|
+
//
|
|
4
|
+
// key: value a string (quotes optional; "…" or '…' strip them)
|
|
5
|
+
// key: a section; children indented deeper than the key
|
|
6
|
+
// # … a comment, whole line or after a value
|
|
7
|
+
// no arrays, no anchors, no multi-line scalars. Lists are words
|
|
8
|
+
// separated by spaces, split by whoever reads the key.
|
|
9
|
+
//
|
|
10
|
+
// Everything is a string or a section. Typing happens in options.ts,
|
|
11
|
+
// which knows what each key means. Pure.
|
|
12
|
+
// ─────────────────────────────────────────────────────────────
|
|
13
|
+
export class YamlError extends Error {
|
|
14
|
+
line;
|
|
15
|
+
constructor(message, line) {
|
|
16
|
+
super(`b17_auth.yaml line ${line}: ${message}`);
|
|
17
|
+
this.name = "YamlError";
|
|
18
|
+
this.line = line;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
/** Strip a trailing comment, respecting quotes. */
|
|
22
|
+
function stripComment(s) {
|
|
23
|
+
let quote = null;
|
|
24
|
+
for (let i = 0; i < s.length; i++) {
|
|
25
|
+
const c = s[i];
|
|
26
|
+
if (quote) {
|
|
27
|
+
if (c === quote)
|
|
28
|
+
quote = null;
|
|
29
|
+
}
|
|
30
|
+
else if (c === '"' || c === "'") {
|
|
31
|
+
quote = c;
|
|
32
|
+
}
|
|
33
|
+
else if (c === "#" && (i === 0 || /\s/.test(s[i - 1]))) {
|
|
34
|
+
return s.slice(0, i);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return s;
|
|
38
|
+
}
|
|
39
|
+
function unquote(v) {
|
|
40
|
+
const m = v.match(/^(["'])(.*)\1$/s);
|
|
41
|
+
return m ? m[2] : v;
|
|
42
|
+
}
|
|
43
|
+
export function parseYaml(text) {
|
|
44
|
+
const root = {};
|
|
45
|
+
// The stack of open sections with the indentation of their keys
|
|
46
|
+
const stack = [{ indent: -1, node: root }];
|
|
47
|
+
const lines = text.split(/\r?\n/);
|
|
48
|
+
for (let i = 0; i < lines.length; i++) {
|
|
49
|
+
const lineNo = i + 1;
|
|
50
|
+
const raw = lines[i];
|
|
51
|
+
if (raw.includes("\t"))
|
|
52
|
+
throw new YamlError("tabs are not allowed; indent with spaces", lineNo);
|
|
53
|
+
const content = stripComment(raw).trimEnd();
|
|
54
|
+
if (!content.trim())
|
|
55
|
+
continue;
|
|
56
|
+
const indent = content.length - content.trimStart().length;
|
|
57
|
+
const body = content.trim();
|
|
58
|
+
if (body.startsWith("- "))
|
|
59
|
+
throw new YamlError("lists use spaces between items, not dashes", lineNo);
|
|
60
|
+
const m = body.match(/^([^\s:#][^:]*?)\s*:(?:\s+(.*))?$/);
|
|
61
|
+
if (!m)
|
|
62
|
+
throw new YamlError(`expected "key: value" or "key:", got "${body}"`, lineNo);
|
|
63
|
+
const key = unquote(m[1].trim());
|
|
64
|
+
const value = m[2]?.trim();
|
|
65
|
+
// Close sections that this line is not inside of
|
|
66
|
+
while (stack.length > 1 && indent <= stack[stack.length - 1].indent)
|
|
67
|
+
stack.pop();
|
|
68
|
+
const parent = stack[stack.length - 1].node;
|
|
69
|
+
if (key in parent)
|
|
70
|
+
throw new YamlError(`duplicate key "${key}"`, lineNo);
|
|
71
|
+
if (value === undefined || value === "") {
|
|
72
|
+
const section = {};
|
|
73
|
+
parent[key] = section;
|
|
74
|
+
stack.push({ indent, node: section });
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
parent[key] = unquote(value);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return root;
|
|
81
|
+
}
|
|
82
|
+
/** Words of a space-separated value. "" → []. */
|
|
83
|
+
export function words(value) {
|
|
84
|
+
return (value ?? "").split(/\s+/).filter(Boolean);
|
|
85
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,18 @@
|
|
|
1
|
-
export { hashPassword, verifyPassword } from "./core/password.ts";
|
|
2
|
-
export { isCurrent, signSession, verifySession, type Claim, type User } from "./core/session.ts";
|
|
3
|
-
export { ensureSchema, findUser, createUser, countUsers, listUsers, setPassword, sessionEpoch, revokeSessions, removeUser } from "./core/db.ts";
|
|
4
|
-
export { signInPage, signUpPage } from "./core/html.ts";
|
|
5
|
-
export {
|
|
6
|
-
export {
|
|
1
|
+
export { hashPassword, verifyPassword, needsRehash, parseHash, SCRYPT_N } from "./core/password.ts";
|
|
2
|
+
export { isCurrent, signSession, verifySession, claimsAcceptable, ISSUER, AUDIENCE, CLAIMS_REQUIRED_FROM, type Claim, type User } from "./core/session.ts";
|
|
3
|
+
export { db, ensureSchema, pendingSteps, MIGRATIONS, findUser, createUser, countUsers, listUsers, setPassword, setPasswordById, sessionEpoch, userState, sessionRow, markVerified, revokeSessions, removeUser, createOrg, findOrg, listOrgs, addMember, removeMember, removeOrg, adminUsers, adminOrgs, setActiveOrg, storedRoles, setRolePermissions, resetRole, seedRoles, memberRole, type StoredRole, type Db, type UserState, type SessionRow, type OrgRow, type Migration, type Statement, type UserRow, } from "./core/db.ts";
|
|
4
|
+
export { signInPage, signUpPage, forgotPage, resetPage, messagePage, securityHeaders } from "./core/html.ts";
|
|
5
|
+
export { resetLink, resetEmail, FORGOT_PATH, RESET_PATH, RESET_TTL_SECONDS } from "./core/reset.ts";
|
|
6
|
+
export { mayAccess, verifyLink, verifyEmail, VERIFY_PATH, VERIFY_TTL_SECONDS } from "./core/verify.ts";
|
|
7
|
+
export { options, loadOptions, resolveOptions, resetOptions, literalSecrets, looksLikeRoleMap, PERMISSION_ID, CONFIG_FILE, DEFAULTS, type Options, type EmailOptions, type SignupMode, } from "./core/options.ts";
|
|
8
|
+
export { parseYaml, YamlError, type YamlTree } from "./core/yaml.ts";
|
|
9
|
+
export { isAdmin, mayEditRoles, refusedOnSelf, roleChoices, checkedFor, grantedFromFields, ADMIN_PATH, ROLE_NAME, ROLE_ACTIONS } from "./core/admin.ts";
|
|
10
|
+
export { rateLimit, decide, clientIp, bucketKey, retryMessage, LIMITS, type Bucket, type Decision } from "./core/rate.ts";
|
|
11
|
+
export { adminPage } from "./core/admin-html.ts";
|
|
12
|
+
export { buildSession, hasPermission, permissionsFor, NO_SESSION, OWNER, type Session, type Organization, type Authorization, type PermissionSource, type StoredGrants, } from "./core/org.ts";
|
|
13
|
+
export { sendEmail, emailTransport, type EmailMessage, type Transport } from "./core/email.ts";
|
|
14
|
+
export { issueToken, consumeToken, hashToken, tokenState, type Token, type TokenKind } from "./core/tokens.ts";
|
|
15
|
+
export { signupPolicy, validateCredentials, validatePassword, PASSWORD_MIN, PASSWORD_MAX, type SignupPolicy } from "./core/signup.ts";
|
|
16
|
+
export { safeNext, safeEqual, isPublic, matchesPattern, isSameOrigin, MATCHER } from "./core/guard.ts";
|
|
17
|
+
export { pagePath, pageOverride, appPages, validatePagePath, validateAppPath, landing, sendsHome, PAGE_KEYS, type Pages, type PageKey } from "./core/pages.ts";
|
|
18
|
+
export { COOKIE_NAME, cookieName, SESSION_DAYS, SIGN_IN_PATH, SIGN_OUT_PATH, SIGN_UP_PATH, getSecret, getDatabaseUrl } from "./core/config.ts";
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,20 @@
|
|
|
1
1
|
// Core primitives. Framework-free. Use these if you are not on Next.js
|
|
2
2
|
// or want to build your own handlers.
|
|
3
|
-
export { hashPassword, verifyPassword } from "./core/password.js";
|
|
4
|
-
export { isCurrent, signSession, verifySession } from "./core/session.js";
|
|
5
|
-
export { ensureSchema, findUser, createUser, countUsers, listUsers, setPassword, sessionEpoch, revokeSessions, removeUser } from "./core/db.js";
|
|
6
|
-
export { signInPage, signUpPage } from "./core/html.js";
|
|
7
|
-
export {
|
|
8
|
-
export {
|
|
3
|
+
export { hashPassword, verifyPassword, needsRehash, parseHash, SCRYPT_N } from "./core/password.js";
|
|
4
|
+
export { isCurrent, signSession, verifySession, claimsAcceptable, ISSUER, AUDIENCE, CLAIMS_REQUIRED_FROM } from "./core/session.js";
|
|
5
|
+
export { db, ensureSchema, pendingSteps, MIGRATIONS, findUser, createUser, countUsers, listUsers, setPassword, setPasswordById, sessionEpoch, userState, sessionRow, markVerified, revokeSessions, removeUser, createOrg, findOrg, listOrgs, addMember, removeMember, removeOrg, adminUsers, adminOrgs, setActiveOrg, storedRoles, setRolePermissions, resetRole, seedRoles, memberRole, } from "./core/db.js";
|
|
6
|
+
export { signInPage, signUpPage, forgotPage, resetPage, messagePage, securityHeaders } from "./core/html.js";
|
|
7
|
+
export { resetLink, resetEmail, FORGOT_PATH, RESET_PATH, RESET_TTL_SECONDS } from "./core/reset.js";
|
|
8
|
+
export { mayAccess, verifyLink, verifyEmail, VERIFY_PATH, VERIFY_TTL_SECONDS } from "./core/verify.js";
|
|
9
|
+
export { options, loadOptions, resolveOptions, resetOptions, literalSecrets, looksLikeRoleMap, PERMISSION_ID, CONFIG_FILE, DEFAULTS, } from "./core/options.js";
|
|
10
|
+
export { parseYaml, YamlError } from "./core/yaml.js";
|
|
11
|
+
export { isAdmin, mayEditRoles, refusedOnSelf, roleChoices, checkedFor, grantedFromFields, ADMIN_PATH, ROLE_NAME, ROLE_ACTIONS } from "./core/admin.js";
|
|
12
|
+
export { rateLimit, decide, clientIp, bucketKey, retryMessage, LIMITS } from "./core/rate.js";
|
|
13
|
+
export { adminPage } from "./core/admin-html.js";
|
|
14
|
+
export { buildSession, hasPermission, permissionsFor, NO_SESSION, OWNER, } from "./core/org.js";
|
|
15
|
+
export { sendEmail, emailTransport } from "./core/email.js";
|
|
16
|
+
export { issueToken, consumeToken, hashToken, tokenState } from "./core/tokens.js";
|
|
17
|
+
export { signupPolicy, validateCredentials, validatePassword, PASSWORD_MIN, PASSWORD_MAX } from "./core/signup.js";
|
|
18
|
+
export { safeNext, safeEqual, isPublic, matchesPattern, isSameOrigin, MATCHER } from "./core/guard.js";
|
|
19
|
+
export { pagePath, pageOverride, appPages, validatePagePath, validateAppPath, landing, sendsHome, PAGE_KEYS } from "./core/pages.js";
|
|
20
|
+
export { COOKIE_NAME, cookieName, SESSION_DAYS, SIGN_IN_PATH, SIGN_OUT_PATH, SIGN_UP_PATH, getSecret, getDatabaseUrl } from "./core/config.js";
|
package/dist/next/index.d.ts
CHANGED
|
@@ -1,15 +1,22 @@
|
|
|
1
1
|
import { NextResponse, type NextRequest } from "next/server.js";
|
|
2
2
|
import { type User } from "../core/session.ts";
|
|
3
|
-
|
|
3
|
+
import { type Authorization, type Organization, type Session } from "../core/org.ts";
|
|
4
|
+
export type { User, Session, Organization, Authorization };
|
|
4
5
|
export declare class AuthError extends Error {
|
|
5
6
|
status: number;
|
|
6
|
-
constructor(message?: string);
|
|
7
|
+
constructor(message?: string, status?: number);
|
|
7
8
|
}
|
|
9
|
+
/** The session contract for the current request, or null if signed out, deleted or revoked. */
|
|
10
|
+
export declare function getSession(): Promise<Session | null>;
|
|
11
|
+
/** The session, or throw AuthError (status 401). */
|
|
12
|
+
export declare function requireSession(): Promise<Session>;
|
|
13
|
+
/** The session, or throw AuthError: 401 when signed out, 403 when the role lacks the permission. */
|
|
14
|
+
export declare function requirePermission(permission: string): Promise<Session>;
|
|
8
15
|
/** Current user from the session cookie, or null if signed out, deleted or revoked. */
|
|
9
16
|
export declare function getUser(): Promise<User | null>;
|
|
10
17
|
/** Current user, or throw AuthError (status 401). */
|
|
11
18
|
export declare function requireUser(): Promise<User>;
|
|
12
|
-
/** A 401 JSON response for catch blocks: `catch (e) { return unauthorized(e) }` */
|
|
19
|
+
/** A 401/403 JSON response for catch blocks: `catch (e) { return unauthorized(e) }` */
|
|
13
20
|
export declare function unauthorized(err?: unknown): NextResponse;
|
|
14
21
|
type Ctx = {
|
|
15
22
|
params: Promise<{
|