hazo_auth 7.0.2 → 9.0.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/README.md +34 -0
- package/SETUP_CHECKLIST.md +31 -0
- package/cli-src/lib/AGENTS.md +26 -0
- package/cli-src/lib/app_logger.ts +3 -7
- package/cli-src/lib/auth/auth_types.ts +3 -0
- package/cli-src/lib/auth/auth_utils.server.ts +2 -1
- package/cli-src/lib/auth/ensure_anon_id.server.ts +2 -1
- package/cli-src/lib/auth/hazo_get_auth.server.ts +30 -4
- package/cli-src/lib/config/hazo_auth_core_config.ts +44 -0
- package/cli-src/lib/cookies_config.server.ts +13 -10
- package/cli-src/lib/hazo_connect_setup.server.ts +19 -11
- package/cli-src/lib/legal/legal_docs_config.server.ts +61 -0
- package/cli-src/lib/legal/legal_docs_reader.server.ts +36 -0
- package/cli-src/lib/legal/legal_docs_service.ts +197 -0
- package/cli-src/lib/legal/legal_docs_types.ts +31 -0
- package/cli-src/lib/services/email_service.ts +22 -11
- package/cli-src/lib/services/firm_service.ts +2 -1
- package/cli-src/lib/services/otp_service.ts +3 -2
- package/cli-src/lib/services/profile_picture_service.ts +2 -1
- package/cli-src/lib/services/registration_service.ts +16 -1
- package/cli-src/lib/services/relationship_service.ts +5 -4
- package/cli-src/lib/services/session_token_service.ts +3 -2
- package/cli-src/lib/utils/api_route_helpers.ts +4 -59
- package/cli-src/lib/utils/get_origin_url.ts +5 -61
- package/cli-src/lib/utils.ts +4 -10
- package/config/hazo_auth_config.example.ini +6 -0
- package/dist/client.d.ts +1 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +3 -0
- package/dist/components/layouts/index.d.ts +1 -0
- package/dist/components/layouts/index.d.ts.map +1 -1
- package/dist/components/layouts/index.js +2 -0
- package/dist/components/layouts/legal/index.d.ts +5 -0
- package/dist/components/layouts/legal/index.d.ts.map +1 -0
- package/dist/components/layouts/legal/index.js +4 -0
- package/dist/components/layouts/legal/legal_acceptance_gate.d.ts +7 -0
- package/dist/components/layouts/legal/legal_acceptance_gate.d.ts.map +1 -0
- package/dist/components/layouts/legal/legal_acceptance_gate.js +84 -0
- package/dist/components/layouts/legal/legal_doc_checkbox_list.d.ts +9 -0
- package/dist/components/layouts/legal/legal_doc_checkbox_list.d.ts.map +1 -0
- package/dist/components/layouts/legal/legal_doc_checkbox_list.js +11 -0
- package/dist/components/layouts/legal/legal_doc_combined_view.d.ts +9 -0
- package/dist/components/layouts/legal/legal_doc_combined_view.d.ts.map +1 -0
- package/dist/components/layouts/legal/legal_doc_combined_view.js +11 -0
- package/dist/components/layouts/legal/legal_doc_drawer.d.ts +8 -0
- package/dist/components/layouts/legal/legal_doc_drawer.d.ts.map +1 -0
- package/dist/components/layouts/legal/legal_doc_drawer.js +55 -0
- package/dist/components/layouts/register/hooks/use_register_form.d.ts +5 -1
- package/dist/components/layouts/register/hooks/use_register_form.d.ts.map +1 -1
- package/dist/components/layouts/register/hooks/use_register_form.js +25 -10
- package/dist/components/layouts/register/index.d.ts.map +1 -1
- package/dist/components/layouts/register/index.js +21 -1
- package/dist/components/layouts/user_management/index.d.ts.map +1 -1
- package/dist/components/layouts/user_management/index.js +45 -7
- package/dist/components/ui/input-otp.d.ts +2 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/lib/app_logger.d.ts +2 -3
- package/dist/lib/app_logger.d.ts.map +1 -1
- package/dist/lib/app_logger.js +3 -5
- package/dist/lib/auth/auth_types.d.ts +2 -0
- package/dist/lib/auth/auth_types.d.ts.map +1 -1
- package/dist/lib/auth/auth_types.js +0 -2
- package/dist/lib/auth/auth_utils.server.d.ts.map +1 -1
- package/dist/lib/auth/auth_utils.server.js +2 -1
- package/dist/lib/auth/ensure_anon_id.server.d.ts.map +1 -1
- package/dist/lib/auth/ensure_anon_id.server.js +2 -1
- package/dist/lib/auth/hazo_get_auth.server.d.ts.map +1 -1
- package/dist/lib/auth/hazo_get_auth.server.js +30 -4
- package/dist/lib/config/hazo_auth_core_config.d.ts +44 -0
- package/dist/lib/config/hazo_auth_core_config.d.ts.map +1 -0
- package/dist/lib/config/hazo_auth_core_config.js +40 -0
- package/dist/lib/cookies_config.server.d.ts.map +1 -1
- package/dist/lib/cookies_config.server.js +12 -7
- package/dist/lib/hazo_connect_setup.server.d.ts.map +1 -1
- package/dist/lib/hazo_connect_setup.server.js +18 -5
- package/dist/lib/legal/legal_docs_config.server.d.ts +22 -0
- package/dist/lib/legal/legal_docs_config.server.d.ts.map +1 -0
- package/dist/lib/legal/legal_docs_config.server.js +52 -0
- package/dist/lib/legal/legal_docs_reader.server.d.ts +15 -0
- package/dist/lib/legal/legal_docs_reader.server.d.ts.map +1 -0
- package/dist/lib/legal/legal_docs_reader.server.js +24 -0
- package/dist/lib/legal/legal_docs_service.d.ts +49 -0
- package/dist/lib/legal/legal_docs_service.d.ts.map +1 -0
- package/dist/lib/legal/legal_docs_service.js +141 -0
- package/dist/lib/legal/legal_docs_types.d.ts +25 -0
- package/dist/lib/legal/legal_docs_types.d.ts.map +1 -0
- package/dist/lib/legal/legal_docs_types.js +2 -0
- package/dist/lib/services/email_service.d.ts +1 -1
- package/dist/lib/services/email_service.d.ts.map +1 -1
- package/dist/lib/services/email_service.js +21 -9
- package/dist/lib/services/firm_service.d.ts.map +1 -1
- package/dist/lib/services/firm_service.js +2 -1
- package/dist/lib/services/otp_service.d.ts.map +1 -1
- package/dist/lib/services/otp_service.js +3 -2
- package/dist/lib/services/profile_picture_service.d.ts.map +1 -1
- package/dist/lib/services/profile_picture_service.js +2 -1
- package/dist/lib/services/registration_service.d.ts +5 -0
- package/dist/lib/services/registration_service.d.ts.map +1 -1
- package/dist/lib/services/registration_service.js +6 -0
- package/dist/lib/services/relationship_service.d.ts.map +1 -1
- package/dist/lib/services/relationship_service.js +5 -4
- package/dist/lib/services/session_token_service.d.ts.map +1 -1
- package/dist/lib/services/session_token_service.js +3 -2
- package/dist/lib/utils/api_route_helpers.d.ts +1 -12
- package/dist/lib/utils/api_route_helpers.d.ts.map +1 -1
- package/dist/lib/utils/api_route_helpers.js +4 -57
- package/dist/lib/utils/get_origin_url.d.ts +1 -22
- package/dist/lib/utils/get_origin_url.d.ts.map +1 -1
- package/dist/lib/utils/get_origin_url.js +5 -57
- package/dist/lib/utils.d.ts +2 -3
- package/dist/lib/utils.d.ts.map +1 -1
- package/dist/lib/utils.js +4 -9
- package/dist/page_components/index.d.ts +0 -5
- package/dist/page_components/index.d.ts.map +1 -1
- package/dist/page_components/index.js +0 -5
- package/dist/server/config/config_loader.js +2 -2
- package/dist/server/index.js +1 -1
- package/dist/server/routes/index.d.ts +3 -0
- package/dist/server/routes/index.d.ts.map +1 -1
- package/dist/server/routes/index.js +4 -0
- package/dist/server/routes/legal_docs_accept.d.ts +3 -0
- package/dist/server/routes/legal_docs_accept.d.ts.map +1 -0
- package/dist/server/routes/legal_docs_accept.js +43 -0
- package/dist/server/routes/legal_docs_get.d.ts +3 -0
- package/dist/server/routes/legal_docs_get.d.ts.map +1 -0
- package/dist/server/routes/legal_docs_get.js +49 -0
- package/dist/server/routes/legal_docs_publish.d.ts +3 -0
- package/dist/server/routes/legal_docs_publish.d.ts.map +1 -0
- package/dist/server/routes/legal_docs_publish.js +35 -0
- package/dist/server/routes/register.d.ts.map +1 -1
- package/dist/server/routes/register.js +26 -0
- package/dist/server/routes/remove_profile_picture.d.ts.map +1 -1
- package/dist/server/routes/remove_profile_picture.js +6 -1
- package/dist/server/routes/upload_profile_picture.d.ts.map +1 -1
- package/dist/server/routes/upload_profile_picture.js +6 -1
- package/dist/server/routes/user_management_users.d.ts +2 -2
- package/dist/server/routes/user_management_users.d.ts.map +1 -1
- package/dist/server/routes/user_management_users.js +46 -2
- package/dist/server/server.d.ts.map +1 -1
- package/dist/server/server.js +7 -0
- package/dist/strings.d.ts +2 -0
- package/dist/strings.d.ts.map +1 -0
- package/dist/strings.js +3 -0
- package/package.json +33 -35
|
@@ -1,23 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
* Gets the public-facing origin URL for redirect construction.
|
|
3
|
-
*
|
|
4
|
-
* Behind reverse proxies (Cloudflare, nginx, etc.), `request.url` contains the
|
|
5
|
-
* internal address (e.g. `http://localhost:3000`), not the public domain.
|
|
6
|
-
* This function returns the correct origin from environment variables.
|
|
7
|
-
*
|
|
8
|
-
* Priority: NEXTAUTH_URL > APP_DOMAIN_NAME > NEXT_PUBLIC_APP_URL > APP_URL > request.url
|
|
9
|
-
*
|
|
10
|
-
* @param request_url - The request.url to use as fallback
|
|
11
|
-
* @returns The origin URL (e.g. "https://gotimer.org")
|
|
12
|
-
*/
|
|
13
|
-
export declare function get_origin_url(request_url: string): string;
|
|
14
|
-
/**
|
|
15
|
-
* Creates a URL using the public-facing origin instead of request.url.
|
|
16
|
-
* Drop-in replacement for `new URL(path, request.url)` in route handlers.
|
|
17
|
-
*
|
|
18
|
-
* @param path - The path or relative URL (e.g. "/hazo_auth/login")
|
|
19
|
-
* @param request_url - The request.url (used as fallback only)
|
|
20
|
-
* @returns A URL object with the correct public origin
|
|
21
|
-
*/
|
|
22
|
-
export declare function create_redirect_url(path: string, request_url: string): URL;
|
|
1
|
+
export { get_origin_url, create_redirect_url } from 'hazo_core';
|
|
23
2
|
//# sourceMappingURL=get_origin_url.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get_origin_url.d.ts","sourceRoot":"","sources":["../../../src/lib/utils/get_origin_url.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"get_origin_url.d.ts","sourceRoot":"","sources":["../../../src/lib/utils/get_origin_url.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC"}
|
|
@@ -1,57 +1,5 @@
|
|
|
1
|
-
// file_description:
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
|
|
6
|
-
* Gets the public-facing origin URL for redirect construction.
|
|
7
|
-
*
|
|
8
|
-
* Behind reverse proxies (Cloudflare, nginx, etc.), `request.url` contains the
|
|
9
|
-
* internal address (e.g. `http://localhost:3000`), not the public domain.
|
|
10
|
-
* This function returns the correct origin from environment variables.
|
|
11
|
-
*
|
|
12
|
-
* Priority: NEXTAUTH_URL > APP_DOMAIN_NAME > NEXT_PUBLIC_APP_URL > APP_URL > request.url
|
|
13
|
-
*
|
|
14
|
-
* @param request_url - The request.url to use as fallback
|
|
15
|
-
* @returns The origin URL (e.g. "https://gotimer.org")
|
|
16
|
-
*/
|
|
17
|
-
export function get_origin_url(request_url) {
|
|
18
|
-
// NEXTAUTH_URL is the standard for NextAuth.js apps
|
|
19
|
-
const nextauth_url = process.env.NEXTAUTH_URL;
|
|
20
|
-
if (nextauth_url) {
|
|
21
|
-
return nextauth_url.replace(/\/$/, "");
|
|
22
|
-
}
|
|
23
|
-
// APP_DOMAIN_NAME (with protocol handling)
|
|
24
|
-
const app_domain = process.env.APP_DOMAIN_NAME;
|
|
25
|
-
if (app_domain) {
|
|
26
|
-
const domain = app_domain.trim();
|
|
27
|
-
if (domain.startsWith("http://") || domain.startsWith("https://")) {
|
|
28
|
-
return domain.replace(/\/$/, "");
|
|
29
|
-
}
|
|
30
|
-
return `https://${domain}`;
|
|
31
|
-
}
|
|
32
|
-
// Other common env vars
|
|
33
|
-
const env_url = process.env.NEXT_PUBLIC_APP_URL || process.env.APP_URL;
|
|
34
|
-
if (env_url) {
|
|
35
|
-
return env_url.replace(/\/$/, "");
|
|
36
|
-
}
|
|
37
|
-
// Fallback to request.url (works in development without a proxy)
|
|
38
|
-
try {
|
|
39
|
-
const url = new URL(request_url);
|
|
40
|
-
return url.origin;
|
|
41
|
-
}
|
|
42
|
-
catch (_a) {
|
|
43
|
-
return request_url;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* Creates a URL using the public-facing origin instead of request.url.
|
|
48
|
-
* Drop-in replacement for `new URL(path, request.url)` in route handlers.
|
|
49
|
-
*
|
|
50
|
-
* @param path - The path or relative URL (e.g. "/hazo_auth/login")
|
|
51
|
-
* @param request_url - The request.url (used as fallback only)
|
|
52
|
-
* @returns A URL object with the correct public origin
|
|
53
|
-
*/
|
|
54
|
-
export function create_redirect_url(path, request_url) {
|
|
55
|
-
const origin = get_origin_url(request_url);
|
|
56
|
-
return new URL(path, origin);
|
|
57
|
-
}
|
|
1
|
+
// file_description: Re-exports get_origin_url and create_redirect_url from hazo_core.
|
|
2
|
+
// Canonical location moved to hazo_core/http in hazo_core v1.
|
|
3
|
+
// This re-export maintains backward compatibility for hazo_auth consumers.
|
|
4
|
+
// Will be removed in hazo_auth v9 — import from 'hazo_core' directly.
|
|
5
|
+
export { get_origin_url, create_redirect_url } from 'hazo_core';
|
package/dist/lib/utils.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
export
|
|
3
|
-
export declare const cn: (...inputs: ClassValue[]) => string;
|
|
1
|
+
export { cn } from "hazo_ui";
|
|
2
|
+
export { cn as merge_class_names } from "hazo_ui";
|
|
4
3
|
//# sourceMappingURL=utils.d.ts.map
|
package/dist/lib/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/lib/utils.ts"],"names":[],"mappings":"AACA,OAAO,
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/lib/utils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAG7B,OAAO,EAAE,EAAE,IAAI,iBAAiB,EAAE,MAAM,SAAS,CAAC"}
|
package/dist/lib/utils.js
CHANGED
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
// file_description:
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
export function merge_class_names(...inputs) {
|
|
6
|
-
return twMerge(clsx(inputs));
|
|
7
|
-
}
|
|
8
|
-
// section: shadcn_compatibility_helper
|
|
9
|
-
export const cn = (...inputs) => merge_class_names(...inputs);
|
|
1
|
+
// file_description: re-exports cn and merge_class_names from hazo_ui (canonical source)
|
|
2
|
+
export { cn } from "hazo_ui";
|
|
3
|
+
// merge_class_names alias — kept for backward compatibility
|
|
4
|
+
export { cn as merge_class_names } from "hazo_ui";
|
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
export { LoginPage, type LoginPageProps } from "./login.js";
|
|
2
|
-
export { RegisterPage, type RegisterPageProps } from "./register.js";
|
|
3
|
-
export { ForgotPasswordPage, type ForgotPasswordPageProps } from "./forgot_password.js";
|
|
4
|
-
export { ResetPasswordPage, type ResetPasswordPageProps } from "./reset_password.js";
|
|
5
|
-
export { VerifyEmailPage, type VerifyEmailPageProps } from "./verify_email.js";
|
|
6
1
|
export { MySettingsPage, type MySettingsPageProps } from "./my_settings.js";
|
|
7
2
|
export { CreateFirmPage, type CreateFirmPageProps } from "./create_firm.js";
|
|
8
3
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/page_components/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/page_components/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,cAAc,EAAE,KAAK,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,KAAK,mBAAmB,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
// file_description: barrel export for zero-config page components
|
|
2
2
|
// These components can be used directly by consumers with sensible defaults
|
|
3
3
|
// section: page_exports
|
|
4
|
-
export { LoginPage } from "./login.js";
|
|
5
|
-
export { RegisterPage } from "./register.js";
|
|
6
|
-
export { ForgotPasswordPage } from "./forgot_password.js";
|
|
7
|
-
export { ResetPasswordPage } from "./reset_password.js";
|
|
8
|
-
export { VerifyEmailPage } from "./verify_email.js";
|
|
9
4
|
export { MySettingsPage } from "./my_settings.js";
|
|
10
5
|
export { CreateFirmPage } from "./create_firm.js";
|
|
@@ -4,7 +4,7 @@ import fs from "fs";
|
|
|
4
4
|
import path from "path";
|
|
5
5
|
import axios from "axios";
|
|
6
6
|
import { HazoConfig } from "hazo_config/server";
|
|
7
|
-
import { createLogger } from "
|
|
7
|
+
import { createLogger } from "hazo_core";
|
|
8
8
|
const is_string_record = (value) => !!value &&
|
|
9
9
|
typeof value === "object" &&
|
|
10
10
|
!Array.isArray(value) &&
|
|
@@ -268,7 +268,7 @@ export const load_runtime_configuration = (options) => {
|
|
|
268
268
|
const fallback_logger = createLogger("hazo_auth_config");
|
|
269
269
|
const parsed_options = sanitize_configuration_options(options, fallback_logger);
|
|
270
270
|
const direct_configuration = parsed_options.direct_configuration;
|
|
271
|
-
const logger = (_a = direct_configuration === null || direct_configuration === void 0 ? void 0 : direct_configuration.logger) !== null && _a !== void 0 ? _a : fallback_logger;
|
|
271
|
+
const logger = ((_a = direct_configuration === null || direct_configuration === void 0 ? void 0 : direct_configuration.logger) !== null && _a !== void 0 ? _a : fallback_logger);
|
|
272
272
|
let hazo_config;
|
|
273
273
|
try {
|
|
274
274
|
const config_file_path = (_b = parsed_options === null || parsed_options === void 0 ? void 0 : parsed_options.config_file_path) !== null && _b !== void 0 ? _b : default_config_path;
|
package/dist/server/index.js
CHANGED
|
@@ -3,7 +3,7 @@ var _a;
|
|
|
3
3
|
// section: imports
|
|
4
4
|
import http from "http";
|
|
5
5
|
import { create_server_app } from "./server.js";
|
|
6
|
-
import { createLogger } from "
|
|
6
|
+
import { createLogger } from "hazo_core";
|
|
7
7
|
// section: constants
|
|
8
8
|
const default_port = Number((_a = process.env.PORT) !== null && _a !== void 0 ? _a : 4100);
|
|
9
9
|
// section: bootstrap_runner
|
|
@@ -34,6 +34,9 @@ export { POST as relationshipUpgradePOST } from "./relationship_upgrade.js";
|
|
|
34
34
|
export { POST as pinLoginPOST } from "./pin_login.js";
|
|
35
35
|
export { otpRequestPOST } from "./otp/request.js";
|
|
36
36
|
export { otpVerifyPOST } from "./otp/verify.js";
|
|
37
|
+
export { legalDocsGET } from './legal_docs_get.js';
|
|
38
|
+
export { legalDocsAcceptPOST } from './legal_docs_accept.js';
|
|
39
|
+
export { legalDocsPublishPOST } from './legal_docs_publish.js';
|
|
37
40
|
export { consentMeGET } from "./consent_me.js";
|
|
38
41
|
export { stringsDefaultsGET } from "./strings_defaults.js";
|
|
39
42
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/server/routes/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/server/routes/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -48,6 +48,10 @@ export { POST as pinLoginPOST } from "./pin_login.js";
|
|
|
48
48
|
// OTP sign-in routes
|
|
49
49
|
export { otpRequestPOST } from "./otp/request.js";
|
|
50
50
|
export { otpVerifyPOST } from "./otp/verify.js";
|
|
51
|
+
// Legal docs routes
|
|
52
|
+
export { legalDocsGET } from './legal_docs_get.js';
|
|
53
|
+
export { legalDocsAcceptPOST } from './legal_docs_accept.js';
|
|
54
|
+
export { legalDocsPublishPOST } from './legal_docs_publish.js';
|
|
51
55
|
// Consent routes
|
|
52
56
|
export { consentMeGET } from "./consent_me.js";
|
|
53
57
|
// Strings routes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"legal_docs_accept.d.ts","sourceRoot":"","sources":["../../../src/server/routes/legal_docs_accept.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AASxD,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CA0CrF"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// file_description: POST /api/hazo_auth/legal_docs/accept — records a user's acceptance of one or more legal docs
|
|
2
|
+
import { NextResponse } from 'next/server';
|
|
3
|
+
import { hazo_get_auth } from '../../lib/auth/hazo_get_auth.server.js';
|
|
4
|
+
import { get_client_ip } from '../../lib/auth/hazo_get_auth.server.js';
|
|
5
|
+
import { get_legal_docs_config } from '../../lib/legal/legal_docs_config.server.js';
|
|
6
|
+
import { read_legal_doc } from '../../lib/legal/legal_docs_reader.server.js';
|
|
7
|
+
import { write_legal_acceptance } from '../../lib/legal/legal_docs_service.js';
|
|
8
|
+
import { get_hazo_connect_instance } from '../../lib/hazo_connect_instance.server.js';
|
|
9
|
+
import { create_app_logger } from '../../lib/app_logger.js';
|
|
10
|
+
export async function legalDocsAcceptPOST(request) {
|
|
11
|
+
const logger = create_app_logger();
|
|
12
|
+
try {
|
|
13
|
+
const auth = await hazo_get_auth(request);
|
|
14
|
+
if (!auth.user) {
|
|
15
|
+
return NextResponse.json({ ok: false, error: 'Authentication required' }, { status: 401 });
|
|
16
|
+
}
|
|
17
|
+
const body = await request.json().catch(() => null);
|
|
18
|
+
const accepted = body === null || body === void 0 ? void 0 : body.accepted;
|
|
19
|
+
if (!accepted || typeof accepted !== 'object' || Object.keys(accepted).length === 0) {
|
|
20
|
+
return NextResponse.json({ ok: false, error: 'accepted is required' }, { status: 400 });
|
|
21
|
+
}
|
|
22
|
+
const config = get_legal_docs_config();
|
|
23
|
+
for (const [doc_key, { hash }] of Object.entries(accepted)) {
|
|
24
|
+
const doc_config = config.docs.find(d => d.key === doc_key);
|
|
25
|
+
if (!doc_config) {
|
|
26
|
+
return NextResponse.json({ ok: false, error: `Unknown doc key: ${doc_key}` }, { status: 400 });
|
|
27
|
+
}
|
|
28
|
+
const { hash: current_hash } = read_legal_doc(doc_config.path);
|
|
29
|
+
if (hash !== current_hash) {
|
|
30
|
+
return NextResponse.json({ ok: false, error: `Hash mismatch for "${doc_key}" — user may have seen a stale version` }, { status: 400 });
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
const ip = get_client_ip(request);
|
|
34
|
+
const user_agent = request.headers.get('user-agent');
|
|
35
|
+
const adapter = get_hazo_connect_instance();
|
|
36
|
+
await write_legal_acceptance(adapter, auth.user.id, accepted, ip, user_agent);
|
|
37
|
+
return NextResponse.json({ ok: true });
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
logger.error('legal_docs_accept: internal server error', { err });
|
|
41
|
+
return NextResponse.json({ ok: false, error: 'Internal server error' }, { status: 500 });
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"legal_docs_get.d.ts","sourceRoot":"","sources":["../../../src/server/routes/legal_docs_get.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAOxD,wBAAsB,YAAY,CAAC,QAAQ,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CA8C/E"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
// file_description: GET /api/hazo_auth/legal_docs — returns configured legal docs with content and required version info
|
|
2
|
+
import { NextResponse } from 'next/server';
|
|
3
|
+
import { get_legal_docs_config } from '../../lib/legal/legal_docs_config.server.js';
|
|
4
|
+
import { read_legal_doc } from '../../lib/legal/legal_docs_reader.server.js';
|
|
5
|
+
import { get_required_versions } from '../../lib/legal/legal_docs_service.js';
|
|
6
|
+
import { get_hazo_connect_instance } from '../../lib/hazo_connect_instance.server.js';
|
|
7
|
+
import { create_app_logger } from '../../lib/app_logger.js';
|
|
8
|
+
export async function legalDocsGET(_request) {
|
|
9
|
+
const logger = create_app_logger();
|
|
10
|
+
try {
|
|
11
|
+
const config = get_legal_docs_config();
|
|
12
|
+
if (config.docs.length === 0) {
|
|
13
|
+
return NextResponse.json({ ok: true, data: { display_mode: config.display_mode, docs: [] } });
|
|
14
|
+
}
|
|
15
|
+
const doc_results = config.docs.map((doc_config) => {
|
|
16
|
+
try {
|
|
17
|
+
const { content, hash } = read_legal_doc(doc_config.path);
|
|
18
|
+
return { ok: true, key: doc_config.key, title: doc_config.title, content, hash };
|
|
19
|
+
}
|
|
20
|
+
catch (err) {
|
|
21
|
+
logger.error('legal_docs_get: failed to read legal doc file', { err, key: doc_config.key, path: doc_config.path });
|
|
22
|
+
return { ok: false, key: doc_config.key, error: `File not found: ${doc_config.path}` };
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
const failed = doc_results.find(d => !d.ok);
|
|
26
|
+
if (failed) {
|
|
27
|
+
return NextResponse.json({ ok: false, error: `Legal doc "${failed.key}" could not be read. Check hazo_auth_config.ini path.` }, { status: 500 });
|
|
28
|
+
}
|
|
29
|
+
const adapter = get_hazo_connect_instance();
|
|
30
|
+
const keys = config.docs.map(d => d.key);
|
|
31
|
+
const required_versions = await get_required_versions(adapter, keys);
|
|
32
|
+
const docs = doc_results.map((d) => {
|
|
33
|
+
var _a, _b, _c, _d;
|
|
34
|
+
return ({
|
|
35
|
+
key: d.key,
|
|
36
|
+
title: d.title,
|
|
37
|
+
content: d.content,
|
|
38
|
+
hash: d.hash,
|
|
39
|
+
required_hash: (_b = (_a = required_versions[d.key]) === null || _a === void 0 ? void 0 : _a.required_hash) !== null && _b !== void 0 ? _b : null,
|
|
40
|
+
required_published_at: (_d = (_c = required_versions[d.key]) === null || _c === void 0 ? void 0 : _c.published_at) !== null && _d !== void 0 ? _d : null,
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
return NextResponse.json({ ok: true, data: { display_mode: config.display_mode, docs } });
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
logger.error('legal_docs_get: internal server error', { err });
|
|
47
|
+
return NextResponse.json({ ok: false, error: 'Internal server error' }, { status: 500 });
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"legal_docs_publish.d.ts","sourceRoot":"","sources":["../../../src/server/routes/legal_docs_publish.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAQxD,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CA+BtF"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// file_description: POST /api/hazo_auth/legal_docs/publish — admin endpoint to publish a new required version of a legal doc
|
|
2
|
+
import { NextResponse } from 'next/server';
|
|
3
|
+
import { hazo_get_auth } from '../../lib/auth/hazo_get_auth.server.js';
|
|
4
|
+
import { get_legal_docs_config } from '../../lib/legal/legal_docs_config.server.js';
|
|
5
|
+
import { read_legal_doc } from '../../lib/legal/legal_docs_reader.server.js';
|
|
6
|
+
import { publish_doc_version } from '../../lib/legal/legal_docs_service.js';
|
|
7
|
+
import { get_hazo_connect_instance } from '../../lib/hazo_connect_instance.server.js';
|
|
8
|
+
import { create_app_logger } from '../../lib/app_logger.js';
|
|
9
|
+
export async function legalDocsPublishPOST(request) {
|
|
10
|
+
const logger = create_app_logger();
|
|
11
|
+
try {
|
|
12
|
+
const auth = await hazo_get_auth(request, { required_permissions: ['admin_user_management'] });
|
|
13
|
+
if (!auth.permission_ok) {
|
|
14
|
+
return NextResponse.json({ ok: false, error: 'Forbidden' }, { status: 403 });
|
|
15
|
+
}
|
|
16
|
+
const body = await request.json().catch(() => null);
|
|
17
|
+
const doc_key = body === null || body === void 0 ? void 0 : body.doc_key;
|
|
18
|
+
if (!doc_key || typeof doc_key !== 'string') {
|
|
19
|
+
return NextResponse.json({ ok: false, error: 'doc_key is required' }, { status: 400 });
|
|
20
|
+
}
|
|
21
|
+
const config = get_legal_docs_config();
|
|
22
|
+
const doc_config = config.docs.find(d => d.key === doc_key);
|
|
23
|
+
if (!doc_config) {
|
|
24
|
+
return NextResponse.json({ ok: false, error: `Unknown doc key: ${doc_key}` }, { status: 400 });
|
|
25
|
+
}
|
|
26
|
+
const { hash } = read_legal_doc(doc_config.path);
|
|
27
|
+
const adapter = get_hazo_connect_instance();
|
|
28
|
+
const { published_at } = await publish_doc_version(adapter, doc_key, hash, auth.user.id);
|
|
29
|
+
return NextResponse.json({ ok: true, data: { doc_key, required_hash: hash, published_at } });
|
|
30
|
+
}
|
|
31
|
+
catch (err) {
|
|
32
|
+
logger.error('legal_docs_publish: internal server error', { err });
|
|
33
|
+
return NextResponse.json({ ok: false, error: 'Internal server error' }, { status: 500 });
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../../src/server/routes/register.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../../src/server/routes/register.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAWxD,wBAAsB,IAAI,CAAC,OAAO,EAAE,WAAW;;;;;;IAgI9C"}
|
|
@@ -6,12 +6,17 @@ import { create_app_logger } from "../../lib/app_logger.js";
|
|
|
6
6
|
import { register_user } from "../../lib/services/registration_service.js";
|
|
7
7
|
import { get_filename, get_line_number } from "../../lib/utils/api_route_helpers.js";
|
|
8
8
|
import { sanitize_error_for_user } from "../../lib/utils/error_sanitizer.js";
|
|
9
|
+
import { get_legal_docs_config } from "../../lib/legal/legal_docs_config.server.js";
|
|
10
|
+
import { read_legal_doc } from "../../lib/legal/legal_docs_reader.server.js";
|
|
11
|
+
import { get_client_ip } from "../../lib/auth/hazo_get_auth.server.js";
|
|
9
12
|
// section: api_handler
|
|
10
13
|
export async function POST(request) {
|
|
14
|
+
var _a;
|
|
11
15
|
const logger = create_app_logger();
|
|
12
16
|
try {
|
|
13
17
|
const body = await request.json();
|
|
14
18
|
const { name, email, password, url_on_logon } = body;
|
|
19
|
+
const legal_accepted = body === null || body === void 0 ? void 0 : body.legal_accepted;
|
|
15
20
|
// Validate input
|
|
16
21
|
if (!email || !password) {
|
|
17
22
|
logger.warn("registration_validation_failed", {
|
|
@@ -32,6 +37,24 @@ export async function POST(request) {
|
|
|
32
37
|
});
|
|
33
38
|
return NextResponse.json({ error: "Invalid email address format" }, { status: 400 });
|
|
34
39
|
}
|
|
40
|
+
// Validate legal acceptance if docs are configured
|
|
41
|
+
const legal_config = get_legal_docs_config();
|
|
42
|
+
if (legal_config.docs.length > 0) {
|
|
43
|
+
const missing_keys = legal_config.docs
|
|
44
|
+
.map(d => d.key)
|
|
45
|
+
.filter(key => !(legal_accepted === null || legal_accepted === void 0 ? void 0 : legal_accepted[key]));
|
|
46
|
+
if (missing_keys.length > 0) {
|
|
47
|
+
return NextResponse.json({ ok: false, error: 'legal_acceptance_required', missing_keys }, { status: 400 });
|
|
48
|
+
}
|
|
49
|
+
// Validate hashes match current file content
|
|
50
|
+
for (const doc_config of legal_config.docs) {
|
|
51
|
+
const submitted_hash = (_a = legal_accepted[doc_config.key]) === null || _a === void 0 ? void 0 : _a.hash;
|
|
52
|
+
const { hash: current_hash } = read_legal_doc(doc_config.path);
|
|
53
|
+
if (submitted_hash !== current_hash) {
|
|
54
|
+
return NextResponse.json({ ok: false, error: `Hash mismatch for "${doc_config.key}"` }, { status: 400 });
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
35
58
|
// Get singleton hazo_connect instance (reuses same connection across all routes)
|
|
36
59
|
const hazoConnect = get_hazo_connect_instance();
|
|
37
60
|
// Register user using the registration service
|
|
@@ -40,6 +63,9 @@ export async function POST(request) {
|
|
|
40
63
|
password,
|
|
41
64
|
name,
|
|
42
65
|
url_on_logon,
|
|
66
|
+
legal_accepted,
|
|
67
|
+
ip: get_client_ip(request),
|
|
68
|
+
user_agent: request.headers.get('user-agent'),
|
|
43
69
|
});
|
|
44
70
|
if (!result.success) {
|
|
45
71
|
const status_code = result.error === "Email address already registered" ? 409 : 500;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remove_profile_picture.d.ts","sourceRoot":"","sources":["../../../src/server/routes/remove_profile_picture.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"remove_profile_picture.d.ts","sourceRoot":"","sources":["../../../src/server/routes/remove_profile_picture.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAQxD,wBAAsB,MAAM,CAAC,OAAO,EAAE,WAAW;;;;;IAsGhD"}
|
|
@@ -5,6 +5,7 @@ import { get_hazo_connect_instance } from "../../lib/hazo_connect_instance.serve
|
|
|
5
5
|
import { create_app_logger } from "../../lib/app_logger.js";
|
|
6
6
|
import { remove_user_profile_picture } from "../../lib/services/profile_picture_remove_service.js";
|
|
7
7
|
import { get_filename, get_line_number } from "../../lib/utils/api_route_helpers.js";
|
|
8
|
+
import { optional_import } from "hazo_core";
|
|
8
9
|
// section: api_handler
|
|
9
10
|
export async function DELETE(request) {
|
|
10
11
|
const logger = create_app_logger();
|
|
@@ -36,7 +37,11 @@ export async function DELETE(request) {
|
|
|
36
37
|
return NextResponse.json({ error: "Relationship accounts not enabled" }, { status: 403 });
|
|
37
38
|
}
|
|
38
39
|
const hazoConnect_rel = get_hazo_connect_instance();
|
|
39
|
-
const
|
|
40
|
+
const hazo_connect_module = await optional_import("hazo_connect/server");
|
|
41
|
+
if (!hazo_connect_module) {
|
|
42
|
+
return NextResponse.json({ error: "hazo_connect not available" }, { status: 503 });
|
|
43
|
+
}
|
|
44
|
+
const { createCrudService } = hazo_connect_module;
|
|
40
45
|
const rel_service = createCrudService(hazoConnect_rel, "hazo_user_relationships");
|
|
41
46
|
const rels = await rel_service.findBy({ parent_user_id: user_id, child_user_id: target_user_id });
|
|
42
47
|
if (!rels || rels.length === 0) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upload_profile_picture.d.ts","sourceRoot":"","sources":["../../../src/server/routes/upload_profile_picture.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"upload_profile_picture.d.ts","sourceRoot":"","sources":["../../../src/server/routes/upload_profile_picture.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAcxD,wBAAsB,IAAI,CAAC,OAAO,EAAE,WAAW;;;;;;IAsR9C"}
|
|
@@ -9,6 +9,7 @@ import { update_user_profile_picture } from "../../lib/services/profile_picture_
|
|
|
9
9
|
import { createCrudService } from "hazo_connect/server";
|
|
10
10
|
import { map_db_source_to_ui } from "../../lib/services/profile_picture_source_mapper.js";
|
|
11
11
|
import { get_filename, get_line_number } from "../../lib/utils/api_route_helpers.js";
|
|
12
|
+
import { optional_import } from "hazo_core";
|
|
12
13
|
import fs from "fs";
|
|
13
14
|
import path from "path";
|
|
14
15
|
// section: api_handler
|
|
@@ -42,7 +43,11 @@ export async function POST(request) {
|
|
|
42
43
|
return NextResponse.json({ error: "Relationship accounts not enabled" }, { status: 403 });
|
|
43
44
|
}
|
|
44
45
|
const hazoConnect = get_hazo_connect_instance();
|
|
45
|
-
const
|
|
46
|
+
const hazo_connect_module = await optional_import("hazo_connect/server");
|
|
47
|
+
if (!hazo_connect_module) {
|
|
48
|
+
return NextResponse.json({ error: "hazo_connect not available" }, { status: 503 });
|
|
49
|
+
}
|
|
50
|
+
const { createCrudService: createRelCrudService } = hazo_connect_module;
|
|
46
51
|
const rel_service = createRelCrudService(hazoConnect, "hazo_user_relationships");
|
|
47
52
|
const rels = await rel_service.findBy({ parent_user_id: user_id, child_user_id: target_user_id });
|
|
48
53
|
if (!rels || rels.length === 0) {
|
|
@@ -26,6 +26,7 @@ export declare function GET(request: NextRequest): Promise<NextResponse<{
|
|
|
26
26
|
profile_source: {} | null;
|
|
27
27
|
user_type: string | null;
|
|
28
28
|
app_user_data: Record<string, unknown> | null;
|
|
29
|
+
legal_acceptance_status: "current" | "none" | "outdated";
|
|
29
30
|
}[];
|
|
30
31
|
}>>;
|
|
31
32
|
/**
|
|
@@ -47,8 +48,7 @@ export declare function POST(request: NextRequest): Promise<NextResponse<{
|
|
|
47
48
|
/**
|
|
48
49
|
* DELETE - Hard-delete a user from hazo_users (cascades to all related rows).
|
|
49
50
|
* Body: { user_id: string }
|
|
50
|
-
* Requires: admin_user_management permission
|
|
51
|
-
* pattern as PATCH/POST in this file which also don't re-auth).
|
|
51
|
+
* Requires: admin_user_management permission.
|
|
52
52
|
*/
|
|
53
53
|
export declare function DELETE(request: NextRequest): Promise<NextResponse<{
|
|
54
54
|
error: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user_management_users.d.ts","sourceRoot":"","sources":["../../../src/server/routes/user_management_users.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"user_management_users.d.ts","sourceRoot":"","sources":["../../../src/server/routes/user_management_users.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAkBxD,eAAO,MAAM,OAAO,kBAAkB,CAAC;AA+BvC;;;GAGG;AACH,wBAAsB,GAAG,CAAC,OAAO,EAAE,WAAW;;;;;;;;;;;;;;;;;;;;;;;;IAsG7C;AAED;;GAEG;AACH,wBAAsB,KAAK,CAAC,OAAO,EAAE,WAAW;;;;IAgI/C;AAED;;GAEG;AACH,wBAAsB,IAAI,CAAC,OAAO,EAAE,WAAW;;;;IA2E9C;AAED;;;;GAIG;AACH,wBAAsB,MAAM,CAAC,OAAO,EAAE,WAAW;;;;IAmEhD"}
|
|
@@ -9,8 +9,35 @@ import { request_password_reset } from "../../lib/services/password_reset_servic
|
|
|
9
9
|
import { get_auth_cache } from "../../lib/auth/auth_cache.js";
|
|
10
10
|
import { get_auth_utility_config } from "../../lib/auth_utility_config.server.js";
|
|
11
11
|
import { is_user_types_enabled, get_all_user_types, get_user_types_config, } from "../../lib/user_types_config.server.js";
|
|
12
|
+
import { get_required_versions } from "../../lib/legal/legal_docs_service.js";
|
|
13
|
+
import { get_legal_docs_config } from "../../lib/legal/legal_docs_config.server.js";
|
|
14
|
+
import { hazo_get_auth } from "../../lib/auth/hazo_get_auth.server.js";
|
|
12
15
|
// section: route_config
|
|
13
16
|
export const dynamic = 'force-dynamic';
|
|
17
|
+
// section: helpers
|
|
18
|
+
/**
|
|
19
|
+
* Compute a user's legal compliance status given their raw legal_acceptance JSON,
|
|
20
|
+
* the currently-required hashes, and the configured doc keys.
|
|
21
|
+
*/
|
|
22
|
+
function compute_legal_status(raw, required, docs) {
|
|
23
|
+
if (docs.length === 0)
|
|
24
|
+
return 'none';
|
|
25
|
+
if (Object.keys(required).length === 0)
|
|
26
|
+
return 'none';
|
|
27
|
+
let map = {};
|
|
28
|
+
try {
|
|
29
|
+
map = typeof raw === 'string' ? JSON.parse(raw) : (raw !== null && raw !== void 0 ? raw : {});
|
|
30
|
+
}
|
|
31
|
+
catch ( /* ignore */_a) { /* ignore */ }
|
|
32
|
+
const all_current = docs.every(doc => {
|
|
33
|
+
var _a;
|
|
34
|
+
const req = required[doc.key];
|
|
35
|
+
if (!req)
|
|
36
|
+
return true;
|
|
37
|
+
return ((_a = map[doc.key]) === null || _a === void 0 ? void 0 : _a.hash) === req.required_hash;
|
|
38
|
+
});
|
|
39
|
+
return all_current ? 'current' : 'outdated';
|
|
40
|
+
}
|
|
14
41
|
// section: api_handler
|
|
15
42
|
/**
|
|
16
43
|
* GET - Fetch all users with details or a specific user by id
|
|
@@ -42,6 +69,13 @@ export async function GET(request) {
|
|
|
42
69
|
badge_color: t.badge_color,
|
|
43
70
|
}))
|
|
44
71
|
: [];
|
|
72
|
+
// Load legal docs required versions for compliance status
|
|
73
|
+
const legal_config = get_legal_docs_config();
|
|
74
|
+
let required_versions = {};
|
|
75
|
+
if (legal_config.docs.length > 0) {
|
|
76
|
+
const adapter = get_hazo_connect_instance();
|
|
77
|
+
required_versions = await get_required_versions(adapter, legal_config.docs.map(d => d.key));
|
|
78
|
+
}
|
|
45
79
|
return NextResponse.json({
|
|
46
80
|
success: true,
|
|
47
81
|
user_types_enabled,
|
|
@@ -74,6 +108,7 @@ export async function GET(request) {
|
|
|
74
108
|
profile_source: user.profile_source || null,
|
|
75
109
|
user_type: user.user_type || null,
|
|
76
110
|
app_user_data,
|
|
111
|
+
legal_acceptance_status: compute_legal_status(user.legal_acceptance, required_versions, legal_config.docs),
|
|
77
112
|
};
|
|
78
113
|
}),
|
|
79
114
|
}, { status: 200 });
|
|
@@ -244,14 +279,23 @@ export async function POST(request) {
|
|
|
244
279
|
/**
|
|
245
280
|
* DELETE - Hard-delete a user from hazo_users (cascades to all related rows).
|
|
246
281
|
* Body: { user_id: string }
|
|
247
|
-
* Requires: admin_user_management permission
|
|
248
|
-
* pattern as PATCH/POST in this file which also don't re-auth).
|
|
282
|
+
* Requires: admin_user_management permission.
|
|
249
283
|
*/
|
|
250
284
|
export async function DELETE(request) {
|
|
251
285
|
const logger = create_app_logger();
|
|
252
286
|
try {
|
|
287
|
+
const auth = await hazo_get_auth(request, { required_permissions: ['admin_user_management'] });
|
|
288
|
+
if (!auth.user) {
|
|
289
|
+
return NextResponse.json({ error: 'Authentication required' }, { status: 401 });
|
|
290
|
+
}
|
|
291
|
+
if (!auth.permission_ok) {
|
|
292
|
+
return NextResponse.json({ error: 'Forbidden' }, { status: 403 });
|
|
293
|
+
}
|
|
253
294
|
const body = await request.json();
|
|
254
295
|
const { user_id } = body;
|
|
296
|
+
if (auth.user.id === user_id) {
|
|
297
|
+
return NextResponse.json({ error: 'Cannot delete your own account' }, { status: 400 });
|
|
298
|
+
}
|
|
255
299
|
if (!user_id) {
|
|
256
300
|
return NextResponse.json({ error: "user_id is required" }, { status: 400 });
|
|
257
301
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/server/server.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/server/server.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAM3C,eAAO,MAAM,iBAAiB,QAAO,WAoBpC,CAAC"}
|
package/dist/server/server.js
CHANGED
|
@@ -7,6 +7,7 @@ import cookie_parser from "cookie-parser";
|
|
|
7
7
|
import compression from "compression";
|
|
8
8
|
import { create_root_router } from "./routes/root_router.js";
|
|
9
9
|
import { create_app_context } from "./config/config_loader.js";
|
|
10
|
+
import { withContext, generateRequestId, REQUEST_ID_HEADER } from "hazo_core";
|
|
10
11
|
// section: app_factory
|
|
11
12
|
export const create_server_app = () => {
|
|
12
13
|
const server_app = express();
|
|
@@ -15,6 +16,12 @@ export const create_server_app = () => {
|
|
|
15
16
|
server_app.use(express.json({ limit: "1mb" }));
|
|
16
17
|
server_app.use(express.urlencoded({ extended: true }));
|
|
17
18
|
server_app.use(cookie_parser());
|
|
19
|
+
server_app.use((request, response, next) => {
|
|
20
|
+
var _a;
|
|
21
|
+
const correlationId = (_a = request.headers[REQUEST_ID_HEADER]) !== null && _a !== void 0 ? _a : generateRequestId();
|
|
22
|
+
response.setHeader(REQUEST_ID_HEADER, correlationId);
|
|
23
|
+
withContext({ correlationId }, () => next());
|
|
24
|
+
});
|
|
18
25
|
server_app.use(compression());
|
|
19
26
|
server_app.use((request, _response, next) => {
|
|
20
27
|
request.context = create_app_context();
|