@rebasepro/server 0.15.0 → 0.16.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/dist/auth/api-keys/api-key-middleware.d.ts +1 -1
- package/dist/auth/jwt.d.ts +1 -1
- package/dist/auth/rls-scope.d.ts +1 -1
- package/dist/{auth-DIKS1rsI.js → auth-5Et5mnUA.js} +141 -32
- package/dist/auth-5Et5mnUA.js.map +1 -0
- package/dist/boot/boot.d.ts +17 -1
- package/dist/boot/env.d.ts +1 -0
- package/dist/boot/provision.d.ts +1 -1
- package/dist/boot/schema-stamp.d.ts +173 -0
- package/dist/boot/version-skew.d.ts +27 -3
- package/dist/{contract-routes-DDNj4_J1.js → contract-routes-DZ-LBpSL.js} +2 -2
- package/dist/contract-routes-DZ-LBpSL.js.map +1 -0
- package/dist/cron/define-cron.d.ts +1 -1
- package/dist/{cron-store-BBGvOA-9.js → cron-store-DfH_4Cd9.js} +2 -2
- package/dist/{cron-store-BBGvOA-9.js.map → cron-store-DfH_4Cd9.js.map} +1 -1
- package/dist/ddl-bootstrap-Cywoj8Ta.js.map +1 -1
- package/dist/email/index.d.ts +1 -0
- package/dist/email/templates.d.ts +21 -5
- package/dist/email/types.d.ts +14 -0
- package/dist/functions/define-function.d.ts +1 -1
- package/dist/index.es.js +386 -35
- package/dist/index.es.js.map +1 -1
- package/dist/init/surfaces.d.ts +8 -1
- package/dist/{jobs-BOEOIGAm.js → jobs-CyOKXXlu.js} +2 -2
- package/dist/{jobs-BOEOIGAm.js.map → jobs-CyOKXXlu.js.map} +1 -1
- package/dist/jwt-DxH9fLPt.js.map +1 -1
- package/dist/{openapi-generator-DLiiGD9X.js → openapi-generator-BCKJRUS4.js} +2 -2
- package/dist/{openapi-generator-DLiiGD9X.js.map → openapi-generator-BCKJRUS4.js.map} +1 -1
- package/dist/singleton.d.ts +1 -1
- package/dist/{src-B-E7RjdN.js → src-BPfYOeN4.js} +3 -3
- package/dist/src-BPfYOeN4.js.map +1 -0
- package/dist/src-CrCxd8km.js.map +1 -1
- package/package.json +5 -5
- package/dist/auth-DIKS1rsI.js.map +0 -1
- package/dist/contract-routes-DDNj4_J1.js.map +0 -1
- package/dist/src-B-E7RjdN.js.map +0 -1
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* injected `default_admin` policies; a non-admin key (roles `["service"]`,
|
|
18
18
|
* uid `api-key:<id>`) only sees rows that a policy explicitly grants to the
|
|
19
19
|
* `service` role or to the public. Owner-style policies
|
|
20
|
-
* (`owner_id =
|
|
20
|
+
* (`owner_id = rebase.uid()`) never match an API key's synthetic uid.
|
|
21
21
|
*
|
|
22
22
|
* @module
|
|
23
23
|
*/
|
package/dist/auth/jwt.d.ts
CHANGED
|
@@ -25,7 +25,7 @@ export interface JwtConfig {
|
|
|
25
25
|
export interface AccessTokenPayload {
|
|
26
26
|
/**
|
|
27
27
|
* The user's id — the same spelling the domain model, the auth adapters and
|
|
28
|
-
* the RLS layer (`
|
|
28
|
+
* the RLS layer (`rebase.uid()`) all use. Tokens minted before this rename
|
|
29
29
|
* carry `uid` instead, and older external IdPs may send `sub`;
|
|
30
30
|
* {@link verifyAccessToken} accepts all three and normalises to this.
|
|
31
31
|
*/
|
package/dist/auth/rls-scope.d.ts
CHANGED
|
@@ -25,7 +25,7 @@ import type { DataDriver } from "@rebasepro/types";
|
|
|
25
25
|
*
|
|
26
26
|
* - It passes the default policies through their `rolesOverlap(['admin'])`
|
|
27
27
|
* arm — the same arm an application user holding the `admin` role passes.
|
|
28
|
-
* - `policy.serverContext()` compiles to `
|
|
28
|
+
* - `policy.serverContext()` compiles to `rebase.uid() IS NULL` and is therefore
|
|
29
29
|
* **false** for it. A collection with `disableDefaultPolicies: true` whose
|
|
30
30
|
* only rule is `serverContext()` denies these writes (42501) and returns
|
|
31
31
|
* zero rows for these reads.
|
|
@@ -2,7 +2,7 @@ import { createRequire as __createRequire } from "module";
|
|
|
2
2
|
import process from "process";
|
|
3
3
|
__createRequire(import.meta.url);
|
|
4
4
|
import { i as __toESM, n as __exportAll } from "./rolldown-runtime-DSJWtz9O.js";
|
|
5
|
-
import { C as ListLimitError, D as isAnonymousUid, E as ANONYMOUS_USER_ID, T as resolveClientListLimit, a as deserializeLogicalCondition, i as deserializeFilter, r as UnknownFilterOperatorError } from "./src-
|
|
5
|
+
import { C as ListLimitError, D as isAnonymousUid, E as ANONYMOUS_USER_ID, T as resolveClientListLimit, a as deserializeLogicalCondition, i as deserializeFilter, r as UnknownFilterOperatorError } from "./src-BPfYOeN4.js";
|
|
6
6
|
import "./src-CrCxd8km.js";
|
|
7
7
|
import { n as createDdlBootstrapper, o as revokeInternalTableSql, s as isSQLAdmin } from "./ddl-bootstrap-Cywoj8Ta.js";
|
|
8
8
|
import { S as canonicalStorageId, T as require_jsonwebtoken, _ as verifyMfaPendingToken, a as generateMfaPendingToken, c as getJwks, d as hasAsymmetricSigningKey, f as hashRefreshToken, g as verifyDownloadToken, h as verifyAccessToken, i as generateDownloadToken, l as getRefreshTokenExpiry, n as configureJwt, o as generateRefreshToken, p as isJwtConfigured, r as generateAccessToken, s as getAccessTokenExpiry, t as MAX_COOKIE_AGE_MS, u as getRefreshTokenTtlMs, w as tryCanonicalStorageKey } from "./jwt-DxH9fLPt.js";
|
|
@@ -589,7 +589,7 @@ var import_jsonwebtoken = /* @__PURE__ */ __toESM(require_jsonwebtoken(), 1);
|
|
|
589
589
|
*
|
|
590
590
|
* - It passes the default policies through their `rolesOverlap(['admin'])`
|
|
591
591
|
* arm — the same arm an application user holding the `admin` role passes.
|
|
592
|
-
* - `policy.serverContext()` compiles to `
|
|
592
|
+
* - `policy.serverContext()` compiles to `rebase.uid() IS NULL` and is therefore
|
|
593
593
|
* **false** for it. A collection with `disableDefaultPolicies: true` whose
|
|
594
594
|
* only rule is `serverContext()` denies these writes (42501) and returns
|
|
595
595
|
* zero rows for these reads.
|
|
@@ -710,7 +710,7 @@ function extractBearerToken(authHeader) {
|
|
|
710
710
|
* injected `default_admin` policies; a non-admin key (roles `["service"]`,
|
|
711
711
|
* uid `api-key:<id>`) only sees rows that a policy explicitly grants to the
|
|
712
712
|
* `service` role or to the public. Owner-style policies
|
|
713
|
-
* (`owner_id =
|
|
713
|
+
* (`owner_id = rebase.uid()`) never match an API key's synthetic uid.
|
|
714
714
|
*
|
|
715
715
|
* @module
|
|
716
716
|
*/
|
|
@@ -1561,9 +1561,90 @@ var styles = {
|
|
|
1561
1561
|
`)
|
|
1562
1562
|
};
|
|
1563
1563
|
/**
|
|
1564
|
+
* The app name every template falls back to when `email.appName` is unset.
|
|
1565
|
+
*/
|
|
1566
|
+
var DEFAULT_APP_NAME = "Rebase";
|
|
1567
|
+
/**
|
|
1568
|
+
* The Rebase mark, hosted. Mail clients do not render SVG (Gmail strips it
|
|
1569
|
+
* outright), so this is the PNG rather than `logo.svg`, and it is an absolute
|
|
1570
|
+
* URL rather than a data URI because Gmail blocks those in `<img src>` too.
|
|
1571
|
+
*/
|
|
1572
|
+
var REBASE_LOGO_URL = "https://rebase.pro/img/logo_small.png";
|
|
1573
|
+
/**
|
|
1574
|
+
* Whether a configured logo can actually be fetched by a mail client.
|
|
1575
|
+
*
|
|
1576
|
+
* A relative path, a `data:` URI or a `file:` URL all produce a broken image in
|
|
1577
|
+
* the recipient's inbox rather than an error anyone would see, so an unusable
|
|
1578
|
+
* value renders no logo at all instead. This is deliberately not a boot-time
|
|
1579
|
+
* assert like `assertEmailLinkBases`: a dead link makes the mail useless, a
|
|
1580
|
+
* missing logo only makes it plain.
|
|
1581
|
+
*/
|
|
1582
|
+
function isMailableImageUrl(url) {
|
|
1583
|
+
if (!url) return false;
|
|
1584
|
+
try {
|
|
1585
|
+
const { protocol } = new URL(url);
|
|
1586
|
+
return protocol === "https:" || protocol === "http:";
|
|
1587
|
+
} catch {
|
|
1588
|
+
return false;
|
|
1589
|
+
}
|
|
1590
|
+
}
|
|
1591
|
+
/**
|
|
1592
|
+
* Whether this config still carries the stock app name — i.e. nobody has
|
|
1593
|
+
* branded this install.
|
|
1594
|
+
*
|
|
1595
|
+
* Testing against the *value* rather than against `undefined` is deliberate and
|
|
1596
|
+
* load-bearing: `APP_NAME` is declared `z.string().default("Rebase")` in the
|
|
1597
|
+
* cloud, in the demo app and in the eject template, so `appName` arrives here as
|
|
1598
|
+
* the literal string "Rebase" even when the operator set nothing. Keying the
|
|
1599
|
+
* fallback on `appName === undefined` would mean the logo never appeared in any
|
|
1600
|
+
* Rebase-run product.
|
|
1601
|
+
*/
|
|
1602
|
+
function isUnbranded(appName) {
|
|
1603
|
+
return !appName || appName === DEFAULT_APP_NAME;
|
|
1604
|
+
}
|
|
1605
|
+
/**
|
|
1606
|
+
* Resolve the branding a template should render from the email config.
|
|
1607
|
+
*
|
|
1608
|
+
* The fallback is asymmetric on purpose. `appName` falls back to "Rebase"
|
|
1609
|
+
* because an unconfigured app has no better name to show. The *logo* is stricter:
|
|
1610
|
+
* an app that named itself "Acme" but set no `logoUrl` gets no logo at all,
|
|
1611
|
+
* because the alternative is mailing Acme's users a Rebase mark from Acme's
|
|
1612
|
+
* domain. Only an install that has not renamed itself is treated as Rebase's own.
|
|
1613
|
+
*/
|
|
1614
|
+
function resolveEmailBranding(config) {
|
|
1615
|
+
const logoUrl = config?.logoUrl ?? (isUnbranded(config?.appName) ? REBASE_LOGO_URL : void 0);
|
|
1616
|
+
return {
|
|
1617
|
+
appName: config?.appName || DEFAULT_APP_NAME,
|
|
1618
|
+
logoUrl: isMailableImageUrl(logoUrl) ? logoUrl : void 0
|
|
1619
|
+
};
|
|
1620
|
+
}
|
|
1621
|
+
/**
|
|
1622
|
+
* The logo block that sits above the card in every default template.
|
|
1623
|
+
*
|
|
1624
|
+
* `width`/`height` are attributes as well as CSS because Outlook's Word renderer
|
|
1625
|
+
* ignores the style block. `alt` carries the app name, for screen readers and
|
|
1626
|
+
* for the very common case of a client that blocks remote images on a first
|
|
1627
|
+
* email from an unknown sender.
|
|
1628
|
+
*
|
|
1629
|
+
* The type styling on the `<img>` is what that blocked case falls back to: alt
|
|
1630
|
+
* text inherits it, and at the body's 16px "Rebase" overflows a 48px box and
|
|
1631
|
+
* renders as "Rebas". 12px plus `height: auto` — CSS the clients that block
|
|
1632
|
+
* images do read, while Outlook still sizes from the attributes — lets the name
|
|
1633
|
+
* through intact.
|
|
1634
|
+
*/
|
|
1635
|
+
function renderHeader(appName, logoUrl) {
|
|
1636
|
+
if (!logoUrl) return raw("");
|
|
1637
|
+
return html`
|
|
1638
|
+
<div style="text-align: center; margin-bottom: 24px;">
|
|
1639
|
+
<img src="${logoUrl}" width="48" height="48" alt="${appName}"
|
|
1640
|
+
style="display: inline-block; width: 48px; height: auto; border: 0; outline: none; text-decoration: none; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; font-size: 12px; color: #64748b;">
|
|
1641
|
+
</div>
|
|
1642
|
+
`;
|
|
1643
|
+
}
|
|
1644
|
+
/**
|
|
1564
1645
|
* Default password reset email template
|
|
1565
1646
|
*/
|
|
1566
|
-
function getPasswordResetTemplate(resetUrl, user, appName =
|
|
1647
|
+
function getPasswordResetTemplate(resetUrl, user, appName = DEFAULT_APP_NAME, logoUrl) {
|
|
1567
1648
|
const greeting = getGreeting(user);
|
|
1568
1649
|
const subject = `Reset your ${appName} password`;
|
|
1569
1650
|
const body = html`
|
|
@@ -1575,7 +1656,7 @@ function getPasswordResetTemplate(resetUrl, user, appName = "Rebase") {
|
|
|
1575
1656
|
<title>${subject}</title>
|
|
1576
1657
|
</head>
|
|
1577
1658
|
<body style="margin: 0; padding: 0; background-color: #f8fafc;">
|
|
1578
|
-
<div style="${styles.container}"
|
|
1659
|
+
<div style="${styles.container}">${renderHeader(appName, logoUrl)}
|
|
1579
1660
|
<div style="${styles.card}">
|
|
1580
1661
|
<h1 style="${styles.heading}">Reset Your Password</h1>
|
|
1581
1662
|
|
|
@@ -1638,7 +1719,7 @@ Your password will remain unchanged.
|
|
|
1638
1719
|
/**
|
|
1639
1720
|
* Default email verification template
|
|
1640
1721
|
*/
|
|
1641
|
-
function getEmailVerificationTemplate(verifyUrl, user, appName =
|
|
1722
|
+
function getEmailVerificationTemplate(verifyUrl, user, appName = DEFAULT_APP_NAME, logoUrl) {
|
|
1642
1723
|
const greeting = getGreeting(user);
|
|
1643
1724
|
const subject = `Verify your ${appName} email address`;
|
|
1644
1725
|
const body = html`
|
|
@@ -1650,7 +1731,7 @@ function getEmailVerificationTemplate(verifyUrl, user, appName = "Rebase") {
|
|
|
1650
1731
|
<title>${subject}</title>
|
|
1651
1732
|
</head>
|
|
1652
1733
|
<body style="margin: 0; padding: 0; background-color: #f8fafc;">
|
|
1653
|
-
<div style="${styles.container}"
|
|
1734
|
+
<div style="${styles.container}">${renderHeader(appName, logoUrl)}
|
|
1654
1735
|
<div style="${styles.card}">
|
|
1655
1736
|
<h1 style="${styles.heading}">Verify Your Email</h1>
|
|
1656
1737
|
|
|
@@ -1704,7 +1785,7 @@ If you didn't create an account with ${appName}, you can safely ignore this emai
|
|
|
1704
1785
|
* Default user invitation email template
|
|
1705
1786
|
* Sent when an admin creates a new user account
|
|
1706
1787
|
*/
|
|
1707
|
-
function getUserInvitationTemplate(setPasswordUrl, user, appName =
|
|
1788
|
+
function getUserInvitationTemplate(setPasswordUrl, user, appName = DEFAULT_APP_NAME, logoUrl) {
|
|
1708
1789
|
const greeting = getGreeting(user);
|
|
1709
1790
|
const subject = `You've been invited to ${appName}`;
|
|
1710
1791
|
const body = html`
|
|
@@ -1716,7 +1797,7 @@ function getUserInvitationTemplate(setPasswordUrl, user, appName = "Rebase") {
|
|
|
1716
1797
|
<title>${subject}</title>
|
|
1717
1798
|
</head>
|
|
1718
1799
|
<body style="margin: 0; padding: 0; background-color: #f8fafc;">
|
|
1719
|
-
<div style="${styles.container}"
|
|
1800
|
+
<div style="${styles.container}">${renderHeader(appName, logoUrl)}
|
|
1720
1801
|
<div style="${styles.card}">
|
|
1721
1802
|
<h1 style="${styles.heading}">Welcome to ${appName}!</h1>
|
|
1722
1803
|
|
|
@@ -1778,7 +1859,7 @@ If you weren't expecting this invitation, you can safely ignore this email.
|
|
|
1778
1859
|
* Default welcome email template
|
|
1779
1860
|
* Sent automatically when a new user registers
|
|
1780
1861
|
*/
|
|
1781
|
-
function getWelcomeEmailTemplate(user, appName =
|
|
1862
|
+
function getWelcomeEmailTemplate(user, appName = DEFAULT_APP_NAME, loginUrl, logoUrl) {
|
|
1782
1863
|
const greeting = getGreeting(user);
|
|
1783
1864
|
const url = loginUrl || "";
|
|
1784
1865
|
const subject = `¡Bienvenido/a a ${appName}!`;
|
|
@@ -1791,7 +1872,7 @@ function getWelcomeEmailTemplate(user, appName = "Rebase", loginUrl) {
|
|
|
1791
1872
|
<title>${subject}</title>
|
|
1792
1873
|
</head>
|
|
1793
1874
|
<body style="margin: 0; padding: 0; background-color: #f8fafc;">
|
|
1794
|
-
<div style="${styles.container}"
|
|
1875
|
+
<div style="${styles.container}">${renderHeader(appName, logoUrl)}
|
|
1795
1876
|
<div style="${styles.card}">
|
|
1796
1877
|
<h1 style="${styles.heading}">¡Bienvenido/a a ${appName}!</h1>
|
|
1797
1878
|
|
|
@@ -1851,7 +1932,7 @@ Si tienes alguna pregunta, no dudes en contactarnos respondiendo a este correo.
|
|
|
1851
1932
|
/**
|
|
1852
1933
|
* Default magic link email template
|
|
1853
1934
|
*/
|
|
1854
|
-
function getMagicLinkTemplate(magicLinkUrl, user, appName =
|
|
1935
|
+
function getMagicLinkTemplate(magicLinkUrl, user, appName = DEFAULT_APP_NAME, logoUrl) {
|
|
1855
1936
|
const greeting = getGreeting(user);
|
|
1856
1937
|
const subject = `Sign in to ${appName}`;
|
|
1857
1938
|
const body = html`
|
|
@@ -1863,7 +1944,7 @@ function getMagicLinkTemplate(magicLinkUrl, user, appName = "Rebase") {
|
|
|
1863
1944
|
<title>${subject}</title>
|
|
1864
1945
|
</head>
|
|
1865
1946
|
<body style="margin: 0; padding: 0; background-color: #f8fafc;">
|
|
1866
|
-
<div style="${styles.container}"
|
|
1947
|
+
<div style="${styles.container}">${renderHeader(appName, logoUrl)}
|
|
1867
1948
|
<div style="${styles.card}">
|
|
1868
1949
|
<h1 style="${styles.heading}">Sign In to ${appName}</h1>
|
|
1869
1950
|
|
|
@@ -2054,7 +2135,7 @@ async function finalizeAdminUserCreation(entity, clearPassword, ctx) {
|
|
|
2054
2135
|
const expiresAt = new Date(Date.now() + 1440 * 60 * 1e3);
|
|
2055
2136
|
await ctx.authRepo.createPasswordResetToken(entity.id, tokenHash, expiresAt);
|
|
2056
2137
|
const setPasswordUrl = `${ctx.emailConfig?.resetPasswordUrl || ""}/reset-password?token=${token}`;
|
|
2057
|
-
const appName = ctx.emailConfig
|
|
2138
|
+
const { appName, logoUrl } = resolveEmailBranding(ctx.emailConfig);
|
|
2058
2139
|
const templateFn = ctx.emailConfig?.templates?.userInvitation;
|
|
2059
2140
|
const emailContent = templateFn ? templateFn(setPasswordUrl, {
|
|
2060
2141
|
email: entity.values.email,
|
|
@@ -2062,7 +2143,7 @@ async function finalizeAdminUserCreation(entity, clearPassword, ctx) {
|
|
|
2062
2143
|
}) : getUserInvitationTemplate(setPasswordUrl, {
|
|
2063
2144
|
email: entity.values.email,
|
|
2064
2145
|
displayName: entity.values.displayName
|
|
2065
|
-
}, appName);
|
|
2146
|
+
}, appName, logoUrl);
|
|
2066
2147
|
await ctx.emailService.send({
|
|
2067
2148
|
to: entity.values.email,
|
|
2068
2149
|
subject: emailContent.subject,
|
|
@@ -2633,6 +2714,36 @@ var DEFAULT_FUNCTIONS_ANONYMOUS_LIMIT = 3e3;
|
|
|
2633
2714
|
function createDataRateLimiter(config = {}) {
|
|
2634
2715
|
const { windowMs = 900 * 1e3, apiKey: apiKeyLimit = 1e3, user: userLimit = 1e3, anonymous: anonLimit = 300, store = new MemoryRateLimitStore(windowMs) } = config;
|
|
2635
2716
|
const trustedProxyHops = resolveTrustedProxyHops(config.trustedProxyHops);
|
|
2717
|
+
/**
|
|
2718
|
+
* Who this request is, for bucketing only.
|
|
2719
|
+
*
|
|
2720
|
+
* `c.get("user")` is the answer whenever an auth middleware has already run.
|
|
2721
|
+
* On the storage router it has not: the limiter is registered before
|
|
2722
|
+
* `route("/")`, and the JWT middlewares live inside those routes, so a
|
|
2723
|
+
* signed-in caller reached here indistinguishable from an anonymous one and
|
|
2724
|
+
* was bucketed `ip:` at the anonymous allowance. Everyone behind one NAT
|
|
2725
|
+
* shared 300 requests per window, and the admin panel — which mints a
|
|
2726
|
+
* download token per file — spent them on a single page of thumbnails.
|
|
2727
|
+
*
|
|
2728
|
+
* Reading the token here rather than moving the limiter is deliberate. The
|
|
2729
|
+
* limiter has to run *before* the routes to guard them, and pre-resolving
|
|
2730
|
+
* the user into the context instead would change authorization: the storage
|
|
2731
|
+
* adapter path enforces on `c.get("user")` when its own `verifyRequest`
|
|
2732
|
+
* finds nobody, so seeding that key would let a Rebase-signed JWT satisfy a
|
|
2733
|
+
* deployment that delegates auth to Firebase or Clerk. Nothing here writes
|
|
2734
|
+
* to the context; an identity that fails to verify simply buckets by IP,
|
|
2735
|
+
* exactly as before.
|
|
2736
|
+
*/
|
|
2737
|
+
const identify = (c) => {
|
|
2738
|
+
const user = c.get("user");
|
|
2739
|
+
if (user?.uid) return isAnonymousUid(user.uid) ? void 0 : user.uid;
|
|
2740
|
+
if (!isJwtConfigured()) return void 0;
|
|
2741
|
+
const token = extractBearerToken(c.req.header("authorization"));
|
|
2742
|
+
if (token === void 0) return void 0;
|
|
2743
|
+
const payload = verifyAccessToken(token);
|
|
2744
|
+
if (!payload?.uid || isAnonymousUid(payload.uid)) return void 0;
|
|
2745
|
+
return payload.uid;
|
|
2746
|
+
};
|
|
2636
2747
|
return createRateLimiter({
|
|
2637
2748
|
windowMs,
|
|
2638
2749
|
store,
|
|
@@ -2640,16 +2751,14 @@ function createDataRateLimiter(config = {}) {
|
|
|
2640
2751
|
keyGenerator: (c) => {
|
|
2641
2752
|
const key = c.get("apiKey");
|
|
2642
2753
|
if (key) return `api-key:${key.id}`;
|
|
2643
|
-
const
|
|
2644
|
-
if (
|
|
2754
|
+
const uid = identify(c);
|
|
2755
|
+
if (uid) return `user:${uid}`;
|
|
2645
2756
|
return `ip:${defaultKeyGenerator(c, trustedProxyHops)}`;
|
|
2646
2757
|
},
|
|
2647
2758
|
resolveLimit: (c) => {
|
|
2648
2759
|
const key = c.get("apiKey");
|
|
2649
2760
|
if (key) return key.rate_limit ?? apiKeyLimit;
|
|
2650
|
-
|
|
2651
|
-
if (user?.uid && !isAnonymousUid(user.uid)) return userLimit;
|
|
2652
|
-
return anonLimit;
|
|
2761
|
+
return identify(c) ? userLimit : anonLimit;
|
|
2653
2762
|
}
|
|
2654
2763
|
});
|
|
2655
2764
|
}
|
|
@@ -7627,7 +7736,7 @@ function mountMagicLinkRoutes(deps) {
|
|
|
7627
7736
|
const expiresAt = getMagicLinkExpiry();
|
|
7628
7737
|
await authRepo.createMagicLinkToken(user.id, tokenHash, expiresAt);
|
|
7629
7738
|
const magicLinkUrl = `${resolveEmailLinkBase(emailConfig, "magicLink")}/auth/magic-link?token=${token}`;
|
|
7630
|
-
const appName = emailConfig
|
|
7739
|
+
const { appName, logoUrl } = resolveEmailBranding(emailConfig);
|
|
7631
7740
|
const templateFn = emailConfig?.templates?.magicLink;
|
|
7632
7741
|
const emailContent = templateFn ? templateFn(magicLinkUrl, {
|
|
7633
7742
|
email: user.email,
|
|
@@ -7635,7 +7744,7 @@ function mountMagicLinkRoutes(deps) {
|
|
|
7635
7744
|
}) : getMagicLinkTemplate(magicLinkUrl, {
|
|
7636
7745
|
email: user.email,
|
|
7637
7746
|
displayName: user.displayName
|
|
7638
|
-
}, appName);
|
|
7747
|
+
}, appName, logoUrl);
|
|
7639
7748
|
try {
|
|
7640
7749
|
await emailService.send({
|
|
7641
7750
|
to: user.email,
|
|
@@ -7849,10 +7958,10 @@ function createAuthRoutes(config) {
|
|
|
7849
7958
|
*/
|
|
7850
7959
|
function sendWelcomeEmail(user) {
|
|
7851
7960
|
if (!isEmailConfigured()) return;
|
|
7852
|
-
const appName = emailConfig
|
|
7961
|
+
const { appName, logoUrl } = resolveEmailBranding(emailConfig);
|
|
7853
7962
|
const loginUrl = resolveEmailLinkBase(emailConfig, "resetPassword");
|
|
7854
7963
|
const templateFn = emailConfig?.templates?.welcomeEmail;
|
|
7855
|
-
const emailContent = templateFn ? templateFn(user, appName) : getWelcomeEmailTemplate(user, appName, loginUrl ? `${loginUrl}/app` : void 0);
|
|
7964
|
+
const emailContent = templateFn ? templateFn(user, appName) : getWelcomeEmailTemplate(user, appName, loginUrl ? `${loginUrl}/app` : void 0, logoUrl);
|
|
7856
7965
|
emailService.send({
|
|
7857
7966
|
to: user.email,
|
|
7858
7967
|
subject: emailContent.subject,
|
|
@@ -8123,7 +8232,7 @@ function createAuthRoutes(config) {
|
|
|
8123
8232
|
const expiresAt = getPasswordResetExpiry();
|
|
8124
8233
|
await authRepo.createPasswordResetToken(user.id, tokenHash, expiresAt);
|
|
8125
8234
|
const resetUrl = `${resolveEmailLinkBase(emailConfig, "resetPassword")}/reset-password?token=${token}`;
|
|
8126
|
-
const appName = emailConfig
|
|
8235
|
+
const { appName, logoUrl } = resolveEmailBranding(emailConfig);
|
|
8127
8236
|
const templateFn = emailConfig?.templates?.passwordReset;
|
|
8128
8237
|
const emailContent = templateFn ? templateFn(resetUrl, {
|
|
8129
8238
|
email: user.email,
|
|
@@ -8131,7 +8240,7 @@ function createAuthRoutes(config) {
|
|
|
8131
8240
|
}) : getPasswordResetTemplate(resetUrl, {
|
|
8132
8241
|
email: user.email,
|
|
8133
8242
|
displayName: user.displayName
|
|
8134
|
-
}, appName);
|
|
8243
|
+
}, appName, logoUrl);
|
|
8135
8244
|
try {
|
|
8136
8245
|
await emailService.send({
|
|
8137
8246
|
to: user.email,
|
|
@@ -8215,7 +8324,7 @@ function createAuthRoutes(config) {
|
|
|
8215
8324
|
const token = generateSecureToken();
|
|
8216
8325
|
await authRepo.setVerificationToken(user.id, hashToken(token));
|
|
8217
8326
|
const verifyUrl = `${resolveEmailLinkBase(emailConfig, "verifyEmail")}/verify-email?token=${token}`;
|
|
8218
|
-
const appName = emailConfig
|
|
8327
|
+
const { appName, logoUrl } = resolveEmailBranding(emailConfig);
|
|
8219
8328
|
const templateFn = emailConfig?.templates?.emailVerification;
|
|
8220
8329
|
const emailContent = templateFn ? templateFn(verifyUrl, {
|
|
8221
8330
|
email: user.email,
|
|
@@ -8223,7 +8332,7 @@ function createAuthRoutes(config) {
|
|
|
8223
8332
|
}) : getEmailVerificationTemplate(verifyUrl, {
|
|
8224
8333
|
email: user.email,
|
|
8225
8334
|
displayName: user.displayName
|
|
8226
|
-
}, appName);
|
|
8335
|
+
}, appName, logoUrl);
|
|
8227
8336
|
await emailService.send({
|
|
8228
8337
|
to: user.email,
|
|
8229
8338
|
subject: emailContent.subject,
|
|
@@ -8432,7 +8541,7 @@ function createResetPasswordRoute(config) {
|
|
|
8432
8541
|
const expiresAt = new Date(Date.now() + 3600 * 1e3);
|
|
8433
8542
|
await authRepo.createPasswordResetToken(existing.id, tokenHash, expiresAt);
|
|
8434
8543
|
const setPasswordUrl = `${emailConfig?.resetPasswordUrl || ""}/reset-password?token=${token}`;
|
|
8435
|
-
const appName = emailConfig
|
|
8544
|
+
const { appName, logoUrl } = resolveEmailBranding(emailConfig);
|
|
8436
8545
|
const templateFn = emailConfig?.templates?.passwordReset;
|
|
8437
8546
|
const emailContent = templateFn ? templateFn(setPasswordUrl, {
|
|
8438
8547
|
email: existing.email,
|
|
@@ -8440,7 +8549,7 @@ function createResetPasswordRoute(config) {
|
|
|
8440
8549
|
}) : getPasswordResetTemplate(setPasswordUrl, {
|
|
8441
8550
|
email: existing.email,
|
|
8442
8551
|
displayName: existing.displayName
|
|
8443
|
-
}, appName);
|
|
8552
|
+
}, appName, logoUrl);
|
|
8444
8553
|
await emailService.send({
|
|
8445
8554
|
to: existing.email,
|
|
8446
8555
|
subject: emailContent.subject,
|
|
@@ -10697,6 +10806,6 @@ var auth_exports = /* @__PURE__ */ __exportAll({
|
|
|
10697
10806
|
verifyPassword: () => verifyPassword
|
|
10698
10807
|
});
|
|
10699
10808
|
//#endregion
|
|
10700
|
-
export {
|
|
10809
|
+
export { createAdapterAuthMiddleware as $, _coercedNumber as A, validatePasswordStrength as B, providerVerifiedEmail as C, parseQueryOptions as Ct, _enum as D, ZodNumber as E, isPublicStoragePath as Et, createEmailService as F, getPasswordResetTemplate as G, generateSecurePassword as H, assertEmailLinkBases as I, resolveEmailBranding as J, getUserInvitationTemplate as K, resolveEmailLinkBase as L, createDataRateLimiter as M, MemoryRateLimitStore as N, object as O, SMTPEmailService as P, raw as Q, resolveAuthHooks as R, pkceTokenParams as S, parseGroupBy as St, createBuiltinAuthAdapter as T, PUBLIC_STORAGE_PREFIX as Tt, getEmailVerificationTemplate as U, verifyPassword as V, getMagicLinkTemplate as W, escapeHtml as X, RawHtml as Y, html as Z, verifyOidcIdToken as _, scopeDataDriver as _t, resolveRateLimitStoreKind as a, publicObjectAuth as at, createGoogleProvider as b, orderByEntriesToTuples as bt, createSlackProvider as c, requireAuth as ct, createDiscordProvider as d, createStorageApiKeyGuard as dt, createAuthMiddleware as et, createTwitterProvider as f, isApiKeyToken as ft, tryVerifyOidcIdToken as g, SERVICE_IDENTITY as gt, createMicrosoftProvider as h, safeCompare as ht, createApiKeyStore as i, optionalAuth as it, DEFAULT_FUNCTIONS_ANONYMOUS_LIMIT as j, string as k, createBitbucketProvider as l, createApiKeyPreAuth as lt, createAppleProvider as m, extractBearerToken as mt, createCustomAuthAdapter as n, extractUserFromToken as nt, createSqlRateLimitStore as o, queryTokenAuth as ot, createFacebookProvider as p, validateApiKey as pt, getWelcomeEmailTemplate as q, createApiKeyRoutes as r, fileTokenAuth as rt, createSpotifyProvider as s, requireAdmin as st, auth_exports as t, createRequireAuth as tt, createGitLabProvider as u, createFunctionApiKeyGuard as ut, createGitHubProvider as v, httpMethodToOperation as vt, createJwksRoutes as w, resolveListLimitParam as wt, oauthCodeFlowSchema as x, parseAggregateSelect as xt, createLinkedinProvider as y, isOperationAllowed as yt, hashPassword as z };
|
|
10701
10810
|
|
|
10702
|
-
//# sourceMappingURL=auth-
|
|
10811
|
+
//# sourceMappingURL=auth-5Et5mnUA.js.map
|