hazo_auth 5.1.40 → 5.3.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/SETUP_CHECKLIST.md +46 -0
- package/cli-src/lib/auth/ensure_anon_id.server.ts +88 -0
- package/cli-src/lib/auth/index.ts +3 -0
- package/cli-src/lib/cookies_config.edge.ts +1 -0
- package/cli-src/lib/cookies_config.server.ts +1 -0
- package/cli-src/lib/hazo_connect_setup.server.ts +0 -8
- package/cli-src/lib/services/email_service.ts +136 -289
- package/cli-src/lib/services/email_template_manifest.ts +104 -0
- package/cli-src/lib/services/email_templates/email_verification.html +18 -0
- package/cli-src/lib/services/email_templates/email_verification.txt +9 -0
- package/cli-src/lib/services/email_templates/forgot_password.html +18 -0
- package/cli-src/lib/services/email_templates/forgot_password.txt +9 -0
- package/cli-src/lib/services/email_templates/password_changed.html +14 -0
- package/cli-src/lib/services/email_templates/password_changed.txt +9 -0
- package/cli-src/lib/services/session_token_service.ts +2 -2
- package/cli-src/lib/ui_shell_config.server.ts +6 -2
- package/dist/components/layouts/login/index.d.ts +16 -3
- package/dist/components/layouts/login/index.d.ts.map +1 -1
- package/dist/components/layouts/login/index.js +49 -5
- package/dist/components/layouts/register/index.d.ts +7 -3
- package/dist/components/layouts/register/index.d.ts.map +1 -1
- package/dist/components/layouts/register/index.js +36 -3
- package/dist/components/layouts/shared/components/floating_home_link.d.ts +20 -0
- package/dist/components/layouts/shared/components/floating_home_link.d.ts.map +1 -0
- package/dist/components/layouts/shared/components/floating_home_link.js +29 -0
- package/dist/components/layouts/shared/components/profile_pic_menu.d.ts +8 -0
- package/dist/components/layouts/shared/components/profile_pic_menu.d.ts.map +1 -1
- package/dist/components/layouts/shared/components/profile_pic_menu.js +18 -8
- package/dist/components/layouts/shared/index.d.ts +2 -0
- package/dist/components/layouts/shared/index.d.ts.map +1 -1
- package/dist/components/layouts/shared/index.js +1 -0
- package/dist/lib/auth/ensure_anon_id.server.d.ts +21 -0
- package/dist/lib/auth/ensure_anon_id.server.d.ts.map +1 -0
- package/dist/lib/auth/ensure_anon_id.server.js +73 -0
- package/dist/lib/auth/index.d.ts +1 -0
- package/dist/lib/auth/index.d.ts.map +1 -1
- package/dist/lib/auth/index.js +2 -0
- package/dist/lib/cookies_config.edge.d.ts +1 -0
- package/dist/lib/cookies_config.edge.d.ts.map +1 -1
- package/dist/lib/cookies_config.edge.js +1 -0
- package/dist/lib/cookies_config.server.d.ts +1 -0
- package/dist/lib/cookies_config.server.d.ts.map +1 -1
- package/dist/lib/cookies_config.server.js +1 -0
- package/dist/lib/hazo_connect_setup.server.d.ts.map +1 -1
- package/dist/lib/hazo_connect_setup.server.js +0 -8
- package/dist/lib/services/email_service.d.ts +17 -4
- package/dist/lib/services/email_service.d.ts.map +1 -1
- package/dist/lib/services/email_service.js +93 -221
- package/dist/lib/services/email_template_manifest.d.ts +11 -0
- package/dist/lib/services/email_template_manifest.d.ts.map +1 -0
- package/dist/lib/services/email_template_manifest.js +95 -0
- package/dist/lib/services/email_templates/email_verification.html +18 -0
- package/dist/lib/services/email_templates/email_verification.txt +9 -0
- package/dist/lib/services/email_templates/forgot_password.html +18 -0
- package/dist/lib/services/email_templates/forgot_password.txt +9 -0
- package/dist/lib/services/email_templates/password_changed.html +14 -0
- package/dist/lib/services/email_templates/password_changed.txt +9 -0
- package/dist/lib/services/session_token_service.js +2 -2
- package/dist/lib/ui_shell_config.server.d.ts.map +1 -1
- package/dist/lib/ui_shell_config.server.js +6 -2
- package/dist/server/routes/oauth_google_callback.d.ts.map +1 -1
- package/dist/server/routes/oauth_google_callback.js +33 -6
- package/dist/server-lib.d.ts +1 -0
- package/dist/server-lib.d.ts.map +1 -1
- package/dist/server-lib.js +1 -0
- package/dist/server_pages/login.d.ts +13 -1
- package/dist/server_pages/login.d.ts.map +1 -1
- package/dist/server_pages/login.js +25 -9
- package/dist/server_pages/login_client_wrapper.d.ts +6 -4
- package/dist/server_pages/login_client_wrapper.d.ts.map +1 -1
- package/dist/server_pages/login_client_wrapper.js +2 -2
- package/dist/server_pages/register.d.ts +7 -1
- package/dist/server_pages/register.d.ts.map +1 -1
- package/dist/server_pages/register.js +18 -9
- package/dist/server_pages/register_client_wrapper.d.ts +6 -4
- package/dist/server_pages/register_client_wrapper.d.ts.map +1 -1
- package/dist/server_pages/register_client_wrapper.js +2 -2
- package/package.json +26 -20
- package/cli-src/assets/images/new_firm_default.jpg +0 -0
- package/cli-src/lib/auth/org_cache.ts +0 -148
- package/cli-src/lib/index.ts +0 -48
- package/cli-src/lib/services/org_service.ts +0 -965
- package/cli-src/lib/services/scope_labels_service.ts +0 -348
|
@@ -34,8 +34,11 @@ export function ProfilePicMenu({ show_single_button = false, sign_up_label = "Si
|
|
|
34
34
|
const [isLoggingOut, setIsLoggingOut] = useState(false);
|
|
35
35
|
const [shiftKeyHeld, setShiftKeyHeld] = useState(false);
|
|
36
36
|
const [showPermissionsDialog, setShowPermissionsDialog] = useState(false);
|
|
37
|
-
//
|
|
38
|
-
|
|
37
|
+
// The logout API endpoint is always derived from apiBasePath. `logout_path`
|
|
38
|
+
// is a navigation destination for AFTER the logout completes (not the API
|
|
39
|
+
// URL — earlier versions conflated these and broke when consumers passed
|
|
40
|
+
// a non-API path like "/").
|
|
41
|
+
const logoutApiPath = `${apiBasePath}/logout`;
|
|
39
42
|
// Get initials from name or email
|
|
40
43
|
const getInitials = () => {
|
|
41
44
|
var _a, _b;
|
|
@@ -55,7 +58,7 @@ export function ProfilePicMenu({ show_single_button = false, sign_up_label = "Si
|
|
|
55
58
|
const handleLogout = async () => {
|
|
56
59
|
setIsLoggingOut(true);
|
|
57
60
|
try {
|
|
58
|
-
const response = await fetch(
|
|
61
|
+
const response = await fetch(logoutApiPath, {
|
|
59
62
|
method: "POST",
|
|
60
63
|
headers: {
|
|
61
64
|
"Content-Type": "application/json",
|
|
@@ -68,8 +71,13 @@ export function ProfilePicMenu({ show_single_button = false, sign_up_label = "Si
|
|
|
68
71
|
toast.success("Logged out successfully");
|
|
69
72
|
// Trigger auth status refresh in all components
|
|
70
73
|
trigger_auth_status_refresh();
|
|
71
|
-
//
|
|
72
|
-
|
|
74
|
+
// Navigate to the configured post-logout destination, or refresh in place.
|
|
75
|
+
if (logout_path) {
|
|
76
|
+
router.push(logout_path);
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
router.refresh();
|
|
80
|
+
}
|
|
73
81
|
}
|
|
74
82
|
catch (error) {
|
|
75
83
|
const errorMessage = error instanceof Error ? error.message : "Logout failed. Please try again.";
|
|
@@ -116,11 +124,13 @@ export function ProfilePicMenu({ show_single_button = false, sign_up_label = "Si
|
|
|
116
124
|
order: 1,
|
|
117
125
|
id: "default_settings",
|
|
118
126
|
});
|
|
119
|
-
// Logout (link, order: 2)
|
|
127
|
+
// Logout (link, order: 2). The href is a fallback for accessibility —
|
|
128
|
+
// `default_logout` items are click-intercepted by `handleLogout` which
|
|
129
|
+
// POSTs to the API path and then navigates per `logout_path`.
|
|
120
130
|
items.push({
|
|
121
131
|
type: "link",
|
|
122
132
|
label: "Logout",
|
|
123
|
-
href:
|
|
133
|
+
href: logoutApiPath,
|
|
124
134
|
order: 2,
|
|
125
135
|
id: "default_logout",
|
|
126
136
|
});
|
|
@@ -141,7 +151,7 @@ export function ProfilePicMenu({ show_single_button = false, sign_up_label = "Si
|
|
|
141
151
|
return a.order - b.order;
|
|
142
152
|
});
|
|
143
153
|
return items;
|
|
144
|
-
}, [authStatus.authenticated, authStatus.name, authStatus.email, settings_path,
|
|
154
|
+
}, [authStatus.authenticated, authStatus.name, authStatus.email, settings_path, logoutApiPath, custom_menu_items]);
|
|
145
155
|
// Avatar size classes
|
|
146
156
|
const avatarSizeClasses = {
|
|
147
157
|
sm: "h-8 w-8",
|
|
@@ -2,6 +2,8 @@ export { AlreadyLoggedInGuard } from "./components/already_logged_in_guard.js";
|
|
|
2
2
|
export { AuthNavbar } from "./components/auth_navbar.js";
|
|
3
3
|
export type { AuthNavbarProps } from "./components/auth_navbar";
|
|
4
4
|
export { FieldErrorMessage } from "./components/field_error_message.js";
|
|
5
|
+
export { FloatingHomeLink } from "./components/floating_home_link.js";
|
|
6
|
+
export type { FloatingHomeLinkProps } from "./components/floating_home_link";
|
|
5
7
|
export { FormActionButtons } from "./components/form_action_buttons.js";
|
|
6
8
|
export { FormFieldWrapper } from "./components/form_field_wrapper.js";
|
|
7
9
|
export { FormHeader } from "./components/form_header.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/layouts/shared/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,sCAAsC,CAAC;AAC5E,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,YAAY,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAEhE,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAE5D,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,YAAY,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AAE7F,OAAO,EAAE,uBAAuB,EAAE,MAAM,wCAAwC,CAAC;AACjF,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC1E,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AACxE,YAAY,EAAE,uBAAuB,EAAE,MAAM,oCAAoC,CAAC;AAClF,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,YAAY,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAGpE,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AACjF,YAAY,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAGnF,cAAc,+BAA+B,CAAC;AAG9C,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACnE,YAAY,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAGlE,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,cAAc,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/layouts/shared/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,sCAAsC,CAAC;AAC5E,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,YAAY,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAEhE,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,YAAY,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AAC7E,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAE5D,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,YAAY,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AAE7F,OAAO,EAAE,uBAAuB,EAAE,MAAM,wCAAwC,CAAC;AACjF,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC1E,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AACxE,YAAY,EAAE,uBAAuB,EAAE,MAAM,oCAAoC,CAAC;AAClF,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,YAAY,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAGpE,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AACjF,YAAY,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAGnF,cAAc,+BAA+B,CAAC;AAG9C,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACnE,YAAY,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAGlE,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,cAAc,oBAAoB,CAAC"}
|
|
@@ -4,6 +4,7 @@ export { AlreadyLoggedInGuard } from "./components/already_logged_in_guard.js";
|
|
|
4
4
|
export { AuthNavbar } from "./components/auth_navbar.js";
|
|
5
5
|
// AuthPageShell - NOT exported (test workspace component only)
|
|
6
6
|
export { FieldErrorMessage } from "./components/field_error_message.js";
|
|
7
|
+
export { FloatingHomeLink } from "./components/floating_home_link.js";
|
|
7
8
|
export { FormActionButtons } from "./components/form_action_buttons.js";
|
|
8
9
|
export { FormFieldWrapper } from "./components/form_field_wrapper.js";
|
|
9
10
|
export { FormHeader } from "./components/form_header.js";
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import "server-only";
|
|
2
|
+
import { NextRequest } from "next/server";
|
|
3
|
+
/**
|
|
4
|
+
* Returns a stable opaque anonymous visitor ID for the caller, reading an
|
|
5
|
+
* existing httpOnly cookie or issuing a fresh UUID v4 if absent.
|
|
6
|
+
*
|
|
7
|
+
* - Cookie name: `hazo_auth_anon_id` (prefixed via `[hazo_auth__cookies] cookie_prefix`)
|
|
8
|
+
* - Cookie attributes: httpOnly, sameSite=lax, path=/, secure in production,
|
|
9
|
+
* maxAge = 2 years.
|
|
10
|
+
* - Idempotent per-request: calling twice with the same NextRequest returns
|
|
11
|
+
* the same id and only queues one Set-Cookie.
|
|
12
|
+
*
|
|
13
|
+
* Independent from authenticated identity: an authenticated user can still
|
|
14
|
+
* have an anon id cookie. Whether to consult it for a logged-in caller is up
|
|
15
|
+
* to the caller (hazo_feedback, for example, doesn't bother).
|
|
16
|
+
*
|
|
17
|
+
* @param request - The incoming NextRequest.
|
|
18
|
+
* @returns The existing or freshly-issued anonymous visitor id (UUID v4 string).
|
|
19
|
+
*/
|
|
20
|
+
export declare function ensure_anon_id(request: NextRequest): Promise<string>;
|
|
21
|
+
//# sourceMappingURL=ensure_anon_id.server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ensure_anon_id.server.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/ensure_anon_id.server.ts"],"names":[],"mappings":"AAqBA,OAAO,aAAa,CAAC;AAGrB,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAgB1C;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CA8B1E"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// file_description: server-only helper to issue/read a stable opaque anonymous visitor ID via httpOnly cookie
|
|
2
|
+
//
|
|
3
|
+
// Used by hazo_feedback (and any future caller) to group submissions from the
|
|
4
|
+
// same anonymous visitor across page loads / weeks without requiring login.
|
|
5
|
+
//
|
|
6
|
+
// Signature choice (v5.2.0): async, request-only — Option A in the design doc.
|
|
7
|
+
// - Reads the existing cookie from the incoming `request.cookies`.
|
|
8
|
+
// - Writes a freshly-issued cookie via the async `cookies()` API from
|
|
9
|
+
// `next/headers`, which is the supported write surface in Server Components,
|
|
10
|
+
// Server Actions, and Route Handlers in Next.js 15+.
|
|
11
|
+
// - Tradeoff: NOT valid in Edge middleware (where `next/headers` throws). If a
|
|
12
|
+
// middleware caller ever needs this, add a sibling `ensure_anon_id_edge`
|
|
13
|
+
// that takes (request, response) and writes via `response.cookies.set`.
|
|
14
|
+
//
|
|
15
|
+
// Idempotent per-request: a per-request WeakMap remembers which id was issued
|
|
16
|
+
// for a given NextRequest instance, so calling `ensure_anon_id(request)` twice
|
|
17
|
+
// in the same request returns the same id and queues only one Set-Cookie. This
|
|
18
|
+
// matters because `request.cookies` reflects the *incoming* state and won't
|
|
19
|
+
// see an id that the same request just issued.
|
|
20
|
+
// section: server-only-guard
|
|
21
|
+
import "server-only";
|
|
22
|
+
import { cookies } from "next/headers";
|
|
23
|
+
import { BASE_COOKIE_NAMES, get_cookie_name, get_cookie_options, } from "../cookies_config.server.js";
|
|
24
|
+
// section: constants
|
|
25
|
+
const TWO_YEARS_SECONDS = 60 * 60 * 24 * 365 * 2;
|
|
26
|
+
// section: state
|
|
27
|
+
// WeakMap keyed by NextRequest so entries are GC'd with the request.
|
|
28
|
+
const issued_per_request = new WeakMap();
|
|
29
|
+
// section: main_function
|
|
30
|
+
/**
|
|
31
|
+
* Returns a stable opaque anonymous visitor ID for the caller, reading an
|
|
32
|
+
* existing httpOnly cookie or issuing a fresh UUID v4 if absent.
|
|
33
|
+
*
|
|
34
|
+
* - Cookie name: `hazo_auth_anon_id` (prefixed via `[hazo_auth__cookies] cookie_prefix`)
|
|
35
|
+
* - Cookie attributes: httpOnly, sameSite=lax, path=/, secure in production,
|
|
36
|
+
* maxAge = 2 years.
|
|
37
|
+
* - Idempotent per-request: calling twice with the same NextRequest returns
|
|
38
|
+
* the same id and only queues one Set-Cookie.
|
|
39
|
+
*
|
|
40
|
+
* Independent from authenticated identity: an authenticated user can still
|
|
41
|
+
* have an anon id cookie. Whether to consult it for a logged-in caller is up
|
|
42
|
+
* to the caller (hazo_feedback, for example, doesn't bother).
|
|
43
|
+
*
|
|
44
|
+
* @param request - The incoming NextRequest.
|
|
45
|
+
* @returns The existing or freshly-issued anonymous visitor id (UUID v4 string).
|
|
46
|
+
*/
|
|
47
|
+
export async function ensure_anon_id(request) {
|
|
48
|
+
var _a;
|
|
49
|
+
const cookie_name = get_cookie_name(BASE_COOKIE_NAMES.ANON_ID);
|
|
50
|
+
// Per-request idempotency: if we already issued for this NextRequest, reuse it.
|
|
51
|
+
const already_issued = issued_per_request.get(request);
|
|
52
|
+
if (already_issued) {
|
|
53
|
+
return already_issued;
|
|
54
|
+
}
|
|
55
|
+
// Read the existing cookie from the incoming request.
|
|
56
|
+
const existing = (_a = request.cookies.get(cookie_name)) === null || _a === void 0 ? void 0 : _a.value;
|
|
57
|
+
if (existing) {
|
|
58
|
+
return existing;
|
|
59
|
+
}
|
|
60
|
+
// Issue a new id and queue the Set-Cookie via the next/headers cookie store.
|
|
61
|
+
const new_id = crypto.randomUUID();
|
|
62
|
+
const cookie_options = get_cookie_options({
|
|
63
|
+
httpOnly: true,
|
|
64
|
+
secure: process.env.NODE_ENV === "production",
|
|
65
|
+
sameSite: "lax",
|
|
66
|
+
path: "/",
|
|
67
|
+
maxAge: TWO_YEARS_SECONDS,
|
|
68
|
+
});
|
|
69
|
+
const cookie_store = await cookies();
|
|
70
|
+
cookie_store.set(cookie_name, new_id, cookie_options);
|
|
71
|
+
issued_per_request.set(request, new_id);
|
|
72
|
+
return new_id;
|
|
73
|
+
}
|
package/dist/lib/auth/index.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ export * from "./auth_types.js";
|
|
|
2
2
|
export { hazo_get_auth } from "./hazo_get_auth.server.js";
|
|
3
3
|
export { get_authenticated_user, require_auth, is_authenticated, } from "./auth_utils.server.js";
|
|
4
4
|
export type { AuthResult, AuthUser } from "./auth_utils.server";
|
|
5
|
+
export { ensure_anon_id } from "./ensure_anon_id.server.js";
|
|
5
6
|
export { hazo_get_tenant_auth, require_tenant_auth, extract_scope_id_from_request, } from "./hazo_get_tenant_auth.server.js";
|
|
6
7
|
export type { ScopeDetails, TenantOrganization, TenantAuthOptions, TenantAuthResult, RequiredTenantAuthResult, } from "./auth_types";
|
|
7
8
|
export { HazoAuthError, AuthenticationRequiredError, TenantRequiredError, TenantAccessDeniedError, } from "./auth_types.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/index.ts"],"names":[],"mappings":"AAEA,cAAc,cAAc,CAAC;AAG7B,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EACL,sBAAsB,EACtB,YAAY,EACZ,gBAAgB,GACjB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAGhE,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,6BAA6B,GAC9B,MAAM,+BAA+B,CAAC;AACvC,YAAY,EACV,YAAY,EACZ,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,wBAAwB,GACzB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,aAAa,EACb,2BAA2B,EAC3B,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrD,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAGtD,OAAO,EACL,QAAQ,EACR,gBAAgB,EAChB,aAAa,EACb,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,EACjB,qBAAqB,GACtB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACV,uBAAuB,EACvB,8BAA8B,EAC9B,eAAe,GAChB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAGhE,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/index.ts"],"names":[],"mappings":"AAEA,cAAc,cAAc,CAAC;AAG7B,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EACL,sBAAsB,EACtB,YAAY,EACZ,gBAAgB,GACjB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAGhE,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAGzD,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,6BAA6B,GAC9B,MAAM,+BAA+B,CAAC;AACvC,YAAY,EACV,YAAY,EACZ,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,wBAAwB,GACzB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,aAAa,EACb,2BAA2B,EAC3B,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrD,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAGtD,OAAO,EACL,QAAQ,EACR,gBAAgB,EAChB,aAAa,EACb,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,EACjB,qBAAqB,GACtB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACV,uBAAuB,EACvB,8BAA8B,EAC9B,eAAe,GAChB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAGhE,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC"}
|
package/dist/lib/auth/index.js
CHANGED
|
@@ -4,6 +4,8 @@ export * from "./auth_types.js";
|
|
|
4
4
|
// section: server_exports
|
|
5
5
|
export { hazo_get_auth } from "./hazo_get_auth.server.js";
|
|
6
6
|
export { get_authenticated_user, require_auth, is_authenticated, } from "./auth_utils.server.js";
|
|
7
|
+
// section: anon_id_exports (v5.2)
|
|
8
|
+
export { ensure_anon_id } from "./ensure_anon_id.server.js";
|
|
7
9
|
// section: tenant_auth_exports
|
|
8
10
|
export { hazo_get_tenant_auth, require_tenant_auth, extract_scope_id_from_request, } from "./hazo_get_tenant_auth.server.js";
|
|
9
11
|
export { HazoAuthError, AuthenticationRequiredError, TenantRequiredError, TenantAccessDeniedError, } from "./auth_types.js";
|
|
@@ -3,6 +3,7 @@ export declare const BASE_COOKIE_NAMES: {
|
|
|
3
3
|
readonly USER_EMAIL: "hazo_auth_user_email";
|
|
4
4
|
readonly SESSION: "hazo_auth_session";
|
|
5
5
|
readonly DEV_LOCK: "hazo_auth_dev_lock";
|
|
6
|
+
readonly ANON_ID: "hazo_auth_anon_id";
|
|
6
7
|
};
|
|
7
8
|
/**
|
|
8
9
|
* Gets the cookie prefix from environment variable
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cookies_config.edge.d.ts","sourceRoot":"","sources":["../../src/lib/cookies_config.edge.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,iBAAiB
|
|
1
|
+
{"version":3,"file":"cookies_config.edge.d.ts","sourceRoot":"","sources":["../../src/lib/cookies_config.edge.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,iBAAiB;;;;;;CAMpB,CAAC;AAGX;;;;;GAKG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CAc/C;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CAE/C;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAG9D;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC,GAAG,CAAC,GAAG;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAQ9G"}
|
|
@@ -7,6 +7,7 @@ export const BASE_COOKIE_NAMES = {
|
|
|
7
7
|
USER_EMAIL: "hazo_auth_user_email",
|
|
8
8
|
SESSION: "hazo_auth_session",
|
|
9
9
|
DEV_LOCK: "hazo_auth_dev_lock",
|
|
10
|
+
ANON_ID: "hazo_auth_anon_id", // v5.2: Stable opaque per-visitor ID for anonymous flows (e.g. hazo_feedback). Kept in sync with the server constant.
|
|
10
11
|
};
|
|
11
12
|
// section: main_functions
|
|
12
13
|
/**
|
|
@@ -11,6 +11,7 @@ export declare const BASE_COOKIE_NAMES: {
|
|
|
11
11
|
readonly SESSION: "hazo_auth_session";
|
|
12
12
|
readonly DEV_LOCK: "hazo_auth_dev_lock";
|
|
13
13
|
readonly SCOPE_ID: "hazo_auth_scope_id";
|
|
14
|
+
readonly ANON_ID: "hazo_auth_anon_id";
|
|
14
15
|
};
|
|
15
16
|
/**
|
|
16
17
|
* Reads cookie configuration from hazo_auth_config.ini file
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cookies_config.server.d.ts","sourceRoot":"","sources":["../../src/lib/cookies_config.server.ts"],"names":[],"mappings":"AAEA,OAAO,aAAa,CAAC;AAMrB,MAAM,MAAM,aAAa,GAAG;IAC1B,6FAA6F;IAC7F,aAAa,EAAE,MAAM,CAAC;IACtB,6EAA6E;IAC7E,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC;AAYF,eAAO,MAAM,iBAAiB
|
|
1
|
+
{"version":3,"file":"cookies_config.server.d.ts","sourceRoot":"","sources":["../../src/lib/cookies_config.server.ts"],"names":[],"mappings":"AAEA,OAAO,aAAa,CAAC;AAMrB,MAAM,MAAM,aAAa,GAAG;IAC1B,6FAA6F;IAC7F,aAAa,EAAE,MAAM,CAAC;IACtB,6EAA6E;IAC7E,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC;AAYF,eAAO,MAAM,iBAAiB;;;;;;;CAOpB,CAAC;AAGX;;;;GAIG;AACH,wBAAgB,kBAAkB,IAAI,aAAa,CAoBlD;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAGzD;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC,GAAG,CAAC,GAAG;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAQzG;AAKD;;;GAGG;AACH,wBAAgB,yBAAyB,IAAI,aAAa,CAKzD;AAED;;GAEG;AACH,wBAAgB,0BAA0B,IAAI,IAAI,CAEjD"}
|
|
@@ -16,6 +16,7 @@ export const BASE_COOKIE_NAMES = {
|
|
|
16
16
|
SESSION: "hazo_auth_session",
|
|
17
17
|
DEV_LOCK: "hazo_auth_dev_lock",
|
|
18
18
|
SCOPE_ID: "hazo_auth_scope_id", // v5.2: Tenant context cookie for multi-tenancy
|
|
19
|
+
ANON_ID: "hazo_auth_anon_id", // v5.2: Stable opaque per-visitor ID for anonymous flows (e.g. hazo_feedback)
|
|
19
20
|
};
|
|
20
21
|
// section: main_function
|
|
21
22
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hazo_connect_setup.server.d.ts","sourceRoot":"","sources":["../../src/lib/hazo_connect_setup.server.ts"],"names":[],"mappings":"AAEA,OAAO,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"hazo_connect_setup.server.d.ts","sourceRoot":"","sources":["../../src/lib/hazo_connect_setup.server.ts"],"names":[],"mappings":"AAEA,OAAO,aAAa,CAAC;AAsJrB;;;;GAIG;AACH,wBAAgB,iCAAiC,8CAuBhD;AAED;;;;GAIG;AACH,wBAAgB,+BAA+B,IAAI;IACjD,IAAI,CAAC,EAAE,QAAQ,GAAG,WAAW,CAAC;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAsBA"}
|
|
@@ -78,14 +78,6 @@ function get_hazo_connect_config() {
|
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
|
-
// Log the resolved path so consumers can see which DB file is being used
|
|
82
|
-
logger.info("hazo_connect_sqlite_path_resolved", {
|
|
83
|
-
filename: "hazo_connect_setup.server.ts",
|
|
84
|
-
line_number: 0,
|
|
85
|
-
sqlite_path,
|
|
86
|
-
process_cwd: process.cwd(),
|
|
87
|
-
config_source: hazo_connect_section ? "hazo_auth_config.ini" : "environment variables",
|
|
88
|
-
});
|
|
89
81
|
return {
|
|
90
82
|
type: "sqlite",
|
|
91
83
|
sqlitePath: sqlite_path,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { EmailerConfig } from "hazo_notify";
|
|
2
|
+
import type { HazoConnectInstance } from "hazo_notify/template_manager";
|
|
2
3
|
export type EmailOptions = {
|
|
3
4
|
to: string;
|
|
4
5
|
from: string;
|
|
@@ -21,6 +22,14 @@ export type EmailTemplateData = {
|
|
|
21
22
|
* @param config - The hazo_notify emailer configuration instance
|
|
22
23
|
*/
|
|
23
24
|
export declare function set_hazo_notify_instance(config: EmailerConfig): void;
|
|
25
|
+
/**
|
|
26
|
+
* Registers the hazo_notify-compatible hazo_connect instance used by
|
|
27
|
+
* `send_template_email`. Call this from `instrumentation.ts` with the same
|
|
28
|
+
* instance you pass to `init_template_manager({ hazo_connect_factory })`.
|
|
29
|
+
*
|
|
30
|
+
* @param instance - hazo_notify-shaped database adapter
|
|
31
|
+
*/
|
|
32
|
+
export declare function set_hazo_notify_connect(instance: HazoConnectInstance): void;
|
|
24
33
|
/**
|
|
25
34
|
* Sends an email using hazo_notify
|
|
26
35
|
* @param options - Email options (to, from, subject, html_body, text_body)
|
|
@@ -31,11 +40,15 @@ export declare function send_email(options: EmailOptions): Promise<{
|
|
|
31
40
|
error?: string;
|
|
32
41
|
}>;
|
|
33
42
|
/**
|
|
34
|
-
* Sends an email using a template
|
|
35
|
-
*
|
|
43
|
+
* Sends an email using a template, delegating rendering to hazo_notify's
|
|
44
|
+
* scope-aware template manager. Templates and per-scope overrides live in
|
|
45
|
+
* hazo_notify's database; hazo_auth ships the global defaults via
|
|
46
|
+
* `hazo_auth_template_manifest`.
|
|
47
|
+
*
|
|
48
|
+
* @param template_type - System template name (email_verification | forgot_password | password_changed)
|
|
36
49
|
* @param to - Recipient email address
|
|
37
|
-
* @param data - Template data
|
|
38
|
-
* @returns Promise that resolves
|
|
50
|
+
* @param data - Template data; `token` is auto-expanded into verification_url/reset_url
|
|
51
|
+
* @returns Promise that resolves with success status
|
|
39
52
|
*/
|
|
40
53
|
export declare function send_template_email(template_type: EmailTemplateType, to: string, data: EmailTemplateData): Promise<{
|
|
41
54
|
success: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"email_service.d.ts","sourceRoot":"","sources":["../../../src/lib/services/email_service.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"email_service.d.ts","sourceRoot":"","sources":["../../../src/lib/services/email_service.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAoB,MAAM,aAAa,CAAC;AACnE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAGxE,MAAM,MAAM,YAAY,GAAG;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,iBAAiB,GAAG,oBAAoB,GAAG,kBAAkB,CAAC;AAE9F,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CACnC,CAAC;AAiBF;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CAEpE;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,mBAAmB,GAAG,IAAI,CAE3E;AA8LD;;;;GAIG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAwErG;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,mBAAmB,CACvC,aAAa,EAAE,iBAAiB,EAChC,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAyF/C"}
|