hazo_auth 9.1.1 → 10.1.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 +124 -6
- package/SETUP_CHECKLIST.md +24 -16
- package/cli-src/cli/init_users.ts +40 -48
- package/cli-src/lib/auth/auth_types.ts +0 -2
- package/cli-src/lib/auth/hazo_get_auth.server.ts +31 -25
- package/cli-src/lib/auth/hazo_get_tenant_auth.server.ts +9 -13
- package/cli-src/lib/auth/nextauth_config.ts +41 -0
- package/cli-src/lib/auth/request_google_scopes.ts +23 -0
- package/cli-src/lib/constants.ts +2 -0
- package/cli-src/lib/profile_pic_menu_config.server.ts +4 -3
- package/cli-src/lib/schema/sqlite_schema.ts +16 -4
- package/cli-src/lib/scope_hierarchy_config.server.ts +1 -9
- package/cli-src/lib/services/google_token_service.ts +408 -0
- package/cli-src/lib/services/index.ts +1 -1
- package/cli-src/lib/services/invitation_service.ts +1 -1
- package/cli-src/lib/services/scope_service.ts +2 -76
- package/cli-src/lib/services/user_scope_service.ts +7 -61
- package/dist/cli/init_users.d.ts.map +1 -1
- package/dist/cli/init_users.js +42 -42
- package/dist/client.d.ts +2 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +3 -1
- package/dist/components/layouts/google_token_test/index.d.ts +6 -0
- package/dist/components/layouts/google_token_test/index.d.ts.map +1 -0
- package/dist/components/layouts/google_token_test/index.js +74 -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 +7 -1
- package/dist/components/layouts/shared/components/sidebar_layout_wrapper.d.ts.map +1 -1
- package/dist/components/layouts/shared/components/sidebar_layout_wrapper.js +2 -2
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/lib/auth/auth_types.d.ts +0 -2
- package/dist/lib/auth/auth_types.d.ts.map +1 -1
- package/dist/lib/auth/hazo_get_auth.server.d.ts.map +1 -1
- package/dist/lib/auth/hazo_get_auth.server.js +27 -19
- package/dist/lib/auth/hazo_get_tenant_auth.server.d.ts.map +1 -1
- package/dist/lib/auth/hazo_get_tenant_auth.server.js +10 -10
- package/dist/lib/auth/nextauth_config.d.ts +2 -0
- package/dist/lib/auth/nextauth_config.d.ts.map +1 -1
- package/dist/lib/auth/nextauth_config.js +39 -1
- package/dist/lib/auth/request_google_scopes.d.ts +10 -0
- package/dist/lib/auth/request_google_scopes.d.ts.map +1 -0
- package/dist/lib/auth/request_google_scopes.js +13 -0
- package/dist/lib/constants.d.ts +1 -0
- package/dist/lib/constants.d.ts.map +1 -1
- package/dist/lib/constants.js +1 -0
- package/dist/lib/profile_pic_menu_config.server.d.ts +2 -1
- package/dist/lib/profile_pic_menu_config.server.d.ts.map +1 -1
- package/dist/lib/profile_pic_menu_config.server.js +1 -1
- package/dist/lib/schema/sqlite_schema.d.ts +1 -1
- package/dist/lib/schema/sqlite_schema.d.ts.map +1 -1
- package/dist/lib/schema/sqlite_schema.js +16 -4
- package/dist/lib/scope_hierarchy_config.server.d.ts +0 -2
- package/dist/lib/scope_hierarchy_config.server.d.ts.map +1 -1
- package/dist/lib/scope_hierarchy_config.server.js +1 -3
- package/dist/lib/services/google_token_service.d.ts +48 -0
- package/dist/lib/services/google_token_service.d.ts.map +1 -0
- package/dist/lib/services/google_token_service.js +319 -0
- package/dist/lib/services/index.d.ts +1 -0
- package/dist/lib/services/index.d.ts.map +1 -1
- package/dist/lib/services/index.js +1 -0
- package/dist/lib/services/invitation_service.d.ts +1 -1
- package/dist/lib/services/invitation_service.js +1 -1
- package/dist/lib/services/scope_service.d.ts +1 -14
- package/dist/lib/services/scope_service.d.ts.map +1 -1
- package/dist/lib/services/scope_service.js +2 -67
- package/dist/lib/services/user_scope_service.d.ts +5 -12
- package/dist/lib/services/user_scope_service.d.ts.map +1 -1
- package/dist/lib/services/user_scope_service.js +8 -45
- package/dist/server/routes/google_token.d.ts +13 -0
- package/dist/server/routes/google_token.d.ts.map +1 -0
- package/dist/server/routes/google_token.js +66 -0
- package/dist/server/routes/index.d.ts +1 -0
- package/dist/server/routes/index.d.ts.map +1 -1
- package/dist/server/routes/index.js +2 -0
- package/dist/server/routes/invitations.d.ts +1 -1
- package/dist/server/routes/invitations.d.ts.map +1 -1
- package/dist/server/routes/invitations.js +12 -11
- package/dist/server/routes/user_management_users.d.ts +1 -1
- package/package.json +17 -13
|
@@ -16,6 +16,7 @@ import { is_hrbac_enabled, get_scope_hierarchy_config } from "../scope_hierarchy
|
|
|
16
16
|
import { check_user_scope_access, get_user_scopes, } from "../services/user_scope_service.js";
|
|
17
17
|
import { get_cookie_name, BASE_COOKIE_NAMES } from "../cookies_config.server.js";
|
|
18
18
|
import { get_app_permission_descriptions } from "../app_permissions_config.server.js";
|
|
19
|
+
import { GLOBAL_ADMIN_PERMISSION } from "../constants.js";
|
|
19
20
|
// section: helpers
|
|
20
21
|
/**
|
|
21
22
|
* Parse JSON string to object, returning null on failure
|
|
@@ -287,7 +288,6 @@ async function check_scope_access_internal(user_id, scope_id) {
|
|
|
287
288
|
scope_access_via: {
|
|
288
289
|
scope_id: result.access_via.scope_id,
|
|
289
290
|
scope_name: result.access_via.scope_name,
|
|
290
|
-
is_super_admin: result.is_super_admin,
|
|
291
291
|
},
|
|
292
292
|
user_scopes,
|
|
293
293
|
};
|
|
@@ -445,25 +445,33 @@ export async function hazo_get_auth(request, options) {
|
|
|
445
445
|
let scope_access_via;
|
|
446
446
|
const hrbac_enabled = is_hrbac_enabled();
|
|
447
447
|
if (hrbac_enabled && (options === null || options === void 0 ? void 0 : options.scope_id)) {
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
const client_ip = get_client_ip(request);
|
|
454
|
-
logger.warn("auth_utility_scope_access_denied", {
|
|
455
|
-
filename: get_filename(),
|
|
456
|
-
line_number: get_line_number(),
|
|
457
|
-
user_id: user.id,
|
|
458
|
-
scope_id: options.scope_id,
|
|
459
|
-
user_scopes: scope_result.user_scopes,
|
|
460
|
-
ip: client_ip,
|
|
461
|
-
correlation_id: getCorrelationId(),
|
|
462
|
-
});
|
|
448
|
+
// Global admin permission grants access to all scopes
|
|
449
|
+
const has_global_admin = permissions.includes(GLOBAL_ADMIN_PERMISSION);
|
|
450
|
+
if (has_global_admin) {
|
|
451
|
+
scope_ok = true;
|
|
452
|
+
scope_access_via = { scope_id: options.scope_id };
|
|
463
453
|
}
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
454
|
+
else {
|
|
455
|
+
const scope_result = await check_scope_access_internal(user.id, options.scope_id);
|
|
456
|
+
scope_ok = scope_result.scope_ok;
|
|
457
|
+
scope_access_via = scope_result.scope_access_via;
|
|
458
|
+
// Log scope denial if permission logging is enabled
|
|
459
|
+
if (!scope_ok && config.log_permission_denials) {
|
|
460
|
+
const client_ip = get_client_ip(request);
|
|
461
|
+
logger.warn("auth_utility_scope_access_denied", {
|
|
462
|
+
filename: get_filename(),
|
|
463
|
+
line_number: get_line_number(),
|
|
464
|
+
user_id: user.id,
|
|
465
|
+
scope_id: options.scope_id,
|
|
466
|
+
user_scopes: scope_result.user_scopes,
|
|
467
|
+
ip: client_ip,
|
|
468
|
+
correlation_id: getCorrelationId(),
|
|
469
|
+
});
|
|
470
|
+
}
|
|
471
|
+
// Throw error if strict mode and scope access denied
|
|
472
|
+
if (!scope_ok && options.strict) {
|
|
473
|
+
throw new ScopeAccessError(options.scope_id, scope_result.user_scopes);
|
|
474
|
+
}
|
|
467
475
|
}
|
|
468
476
|
}
|
|
469
477
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hazo_get_tenant_auth.server.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/hazo_get_tenant_auth.server.ts"],"names":[],"mappings":"AAEA,OAAO,aAAa,CAAC;AAGrB,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"hazo_get_tenant_auth.server.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/hazo_get_tenant_auth.server.ts"],"names":[],"mappings":"AAEA,OAAO,aAAa,CAAC;AAGrB,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAQ1C,OAAO,KAAK,EACV,iBAAiB,EACjB,gBAAgB,EAChB,wBAAwB,EAGzB,MAAM,cAAc,CAAC;AAqBtB;;;;;;GAMG;AACH,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,WAAW,EACpB,OAAO,EAAE,iBAAiB,GACzB,MAAM,GAAG,SAAS,CAYpB;AA8BD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,WAAW,EACpB,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,gBAAgB,CAAC,CAwF3B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,WAAW,EACpB,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,wBAAwB,CAAC,CA0BnC"}
|
|
@@ -4,6 +4,7 @@ import "server-only";
|
|
|
4
4
|
import { hazo_get_auth } from "./hazo_get_auth.server.js";
|
|
5
5
|
import { get_auth_cache } from "./auth_cache.js";
|
|
6
6
|
import { get_scope_by_id } from "../services/scope_service.js";
|
|
7
|
+
import { GLOBAL_ADMIN_PERMISSION } from "../constants.js";
|
|
7
8
|
import { get_hazo_connect_instance } from "../hazo_connect_instance.server.js";
|
|
8
9
|
import { get_cookie_name } from "../cookies_config.server.js";
|
|
9
10
|
import { get_auth_utility_config } from "../auth_utility_config.server.js";
|
|
@@ -39,19 +40,17 @@ export function extract_scope_id_from_request(request, options) {
|
|
|
39
40
|
return cookie_value;
|
|
40
41
|
}
|
|
41
42
|
/**
|
|
42
|
-
* Builds TenantOrganization from scope details
|
|
43
|
+
* Builds TenantOrganization from scope details
|
|
43
44
|
* @param scope_details - Full scope details from cache
|
|
44
|
-
* @param is_super_admin - Whether user is accessing as super admin
|
|
45
45
|
* @returns TenantOrganization object
|
|
46
46
|
*/
|
|
47
|
-
function build_tenant_organization(scope_details
|
|
47
|
+
function build_tenant_organization(scope_details) {
|
|
48
48
|
return {
|
|
49
49
|
id: scope_details.id,
|
|
50
50
|
name: scope_details.name,
|
|
51
51
|
slug: scope_details.slug,
|
|
52
52
|
level: scope_details.level,
|
|
53
53
|
role_id: scope_details.role_id,
|
|
54
|
-
is_super_admin,
|
|
55
54
|
branding: scope_details.logo_url || scope_details.primary_color
|
|
56
55
|
? {
|
|
57
56
|
logo_url: scope_details.logo_url,
|
|
@@ -113,13 +112,15 @@ export async function hazo_get_tenant_auth(request, options = {}) {
|
|
|
113
112
|
// Build organization info if scope access was successful
|
|
114
113
|
let organization = null;
|
|
115
114
|
if (scope_id && auth_result.scope_ok && auth_result.scope_access_via) {
|
|
116
|
-
//
|
|
115
|
+
// Try to find the scope in user's cached scope assignments first.
|
|
116
|
+
// For global admins the scope may not be in their cache (they can access any scope),
|
|
117
|
+
// in which case we fall through to the permission-based fetch below.
|
|
117
118
|
const access_scope = user_scopes.find((s) => { var _a; return s.id === ((_a = auth_result.scope_access_via) === null || _a === void 0 ? void 0 : _a.scope_id); });
|
|
118
119
|
if (access_scope) {
|
|
119
|
-
organization = build_tenant_organization(access_scope
|
|
120
|
+
organization = build_tenant_organization(access_scope);
|
|
120
121
|
}
|
|
121
|
-
else if (auth_result.
|
|
122
|
-
//
|
|
122
|
+
else if (auth_result.permissions.includes(GLOBAL_ADMIN_PERMISSION)) {
|
|
123
|
+
// Global admin accessing a scope they aren't directly assigned to — fetch scope details
|
|
123
124
|
const hazoConnect = get_hazo_connect_instance();
|
|
124
125
|
const scope_result = await get_scope_by_id(hazoConnect, scope_id);
|
|
125
126
|
if (scope_result.success && scope_result.scope) {
|
|
@@ -128,8 +129,7 @@ export async function hazo_get_tenant_auth(request, options = {}) {
|
|
|
128
129
|
name: scope_result.scope.name,
|
|
129
130
|
slug: null, // Could fetch from scope if slug column exists
|
|
130
131
|
level: scope_result.scope.level,
|
|
131
|
-
role_id: "", //
|
|
132
|
-
is_super_admin: true,
|
|
132
|
+
role_id: "", // Global admin doesn't have a role assignment in the scope
|
|
133
133
|
branding: scope_result.scope.logo_url
|
|
134
134
|
? {
|
|
135
135
|
logo_url: scope_result.scope.logo_url,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nextauth_config.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/nextauth_config.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAW,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"nextauth_config.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/nextauth_config.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAW,MAAM,WAAW,CAAC;AActD,MAAM,MAAM,oBAAoB,GAAG;IACjC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B,CAAC;AAGF;;;;GAIG;AACH,wBAAgB,mBAAmB,IAAI,WAAW,CAwQjD;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,OAAO,CAW7C"}
|
|
@@ -7,6 +7,7 @@ import { get_oauth_config } from "../oauth_config.server.js";
|
|
|
7
7
|
import { handle_google_oauth_login } from "../services/oauth_service.js";
|
|
8
8
|
import { get_hazo_connect_instance } from "../hazo_connect_instance.server.js";
|
|
9
9
|
import { create_app_logger } from "../app_logger.js";
|
|
10
|
+
import { store_google_oauth_token, GoogleTokenStorageUnconfigured } from "../services/google_token_service.js";
|
|
10
11
|
// section: config
|
|
11
12
|
/**
|
|
12
13
|
* Gets NextAuth.js configuration with enabled OAuth providers
|
|
@@ -29,6 +30,7 @@ export function get_nextauth_config() {
|
|
|
29
30
|
prompt: "consent",
|
|
30
31
|
access_type: "offline",
|
|
31
32
|
response_type: "code",
|
|
33
|
+
include_granted_scopes: "true",
|
|
32
34
|
},
|
|
33
35
|
},
|
|
34
36
|
}));
|
|
@@ -79,7 +81,7 @@ export function get_nextauth_config() {
|
|
|
79
81
|
* Sign-in callback - handle user creation/linking for Google OAuth
|
|
80
82
|
*/
|
|
81
83
|
async signIn({ account, profile, user, }) {
|
|
82
|
-
var _a;
|
|
84
|
+
var _a, _b, _c;
|
|
83
85
|
const logger = create_app_logger();
|
|
84
86
|
if ((account === null || account === void 0 ? void 0 : account.provider) === "google" && profile) {
|
|
85
87
|
try {
|
|
@@ -113,6 +115,42 @@ export function get_nextauth_config() {
|
|
|
113
115
|
});
|
|
114
116
|
// Store user_id in account for the JWT callback to pick up
|
|
115
117
|
account.hazo_user_id = result.user_id;
|
|
118
|
+
// Capture refresh token when extra scopes were granted
|
|
119
|
+
const BASE_SCOPES = ["openid", "email", "profile"];
|
|
120
|
+
const granted_scopes = ((_b = account.scope) !== null && _b !== void 0 ? _b : "").split(" ").filter(Boolean);
|
|
121
|
+
const has_extra_scopes = granted_scopes.some(s => !BASE_SCOPES.includes(s));
|
|
122
|
+
if (account.refresh_token && has_extra_scopes) {
|
|
123
|
+
try {
|
|
124
|
+
await store_google_oauth_token({
|
|
125
|
+
user_id: result.user_id,
|
|
126
|
+
refresh_token: account.refresh_token,
|
|
127
|
+
access_token: account.access_token,
|
|
128
|
+
scopes: (_c = account.scope) !== null && _c !== void 0 ? _c : "",
|
|
129
|
+
expires_at: account.expires_at
|
|
130
|
+
? new Date(account.expires_at * 1000).toISOString()
|
|
131
|
+
: undefined,
|
|
132
|
+
});
|
|
133
|
+
logger.info("nextauth_google_token_stored", {
|
|
134
|
+
user_id: result.user_id,
|
|
135
|
+
scopes: account.scope,
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
catch (tokenError) {
|
|
139
|
+
if (tokenError instanceof GoogleTokenStorageUnconfigured) {
|
|
140
|
+
logger.error("nextauth_google_token_storage_unconfigured", {
|
|
141
|
+
user_id: result.user_id,
|
|
142
|
+
error: tokenError.message,
|
|
143
|
+
});
|
|
144
|
+
return "/api/auth/error?error=GoogleTokenStorageUnconfigured";
|
|
145
|
+
}
|
|
146
|
+
const errorMsg = tokenError instanceof Error ? tokenError.message : String(tokenError);
|
|
147
|
+
logger.error("nextauth_google_token_store_failed", {
|
|
148
|
+
user_id: result.user_id,
|
|
149
|
+
error: errorMsg,
|
|
150
|
+
});
|
|
151
|
+
// Non-fatal: continue sign-in even if token storage fails
|
|
152
|
+
}
|
|
153
|
+
}
|
|
116
154
|
return true;
|
|
117
155
|
}
|
|
118
156
|
catch (error) {
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { signIn } from "next-auth/react";
|
|
2
|
+
/**
|
|
3
|
+
* Triggers an incremental Google OAuth consent flow to grant additional scopes.
|
|
4
|
+
* Call from a client component when the user needs to grant extra Google API access
|
|
5
|
+
* (e.g. analytics, sheets). On completion, hazo_auth stores the refresh token.
|
|
6
|
+
*/
|
|
7
|
+
export declare function requestGoogleScopes(scopes: string[], opts?: {
|
|
8
|
+
callbackUrl?: string;
|
|
9
|
+
}): ReturnType<typeof signIn>;
|
|
10
|
+
//# sourceMappingURL=request_google_scopes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request_google_scopes.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/request_google_scopes.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAEzC;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,MAAM,EAAE,EAChB,IAAI,CAAC,EAAE;IAAE,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,GAC9B,UAAU,CAAC,OAAO,MAAM,CAAC,CAS3B"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// file_description: client helper to trigger incremental Google OAuth scope consent
|
|
2
|
+
"use client";
|
|
3
|
+
import { signIn } from "next-auth/react";
|
|
4
|
+
/**
|
|
5
|
+
* Triggers an incremental Google OAuth consent flow to grant additional scopes.
|
|
6
|
+
* Call from a client component when the user needs to grant extra Google API access
|
|
7
|
+
* (e.g. analytics, sheets). On completion, hazo_auth stores the refresh token.
|
|
8
|
+
*/
|
|
9
|
+
export function requestGoogleScopes(scopes, opts) {
|
|
10
|
+
var _a;
|
|
11
|
+
const scope = Array.from(new Set(["openid", "email", "profile", ...scopes])).join(" ");
|
|
12
|
+
return signIn("google", { callbackUrl: (_a = opts === null || opts === void 0 ? void 0 : opts.callbackUrl) !== null && _a !== void 0 ? _a : "/" }, { scope, access_type: "offline", include_granted_scopes: "true", prompt: "consent" });
|
|
13
|
+
}
|
package/dist/lib/constants.d.ts
CHANGED
|
@@ -8,4 +8,5 @@ export declare const HAZO_AUTH_PERMISSIONS: {
|
|
|
8
8
|
readonly ADMIN_TEST_ACCESS: "admin_test_access";
|
|
9
9
|
};
|
|
10
10
|
export declare const ALL_ADMIN_PERMISSIONS: string[];
|
|
11
|
+
export declare const GLOBAL_ADMIN_PERMISSION = "hazo_org_global_admin";
|
|
11
12
|
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/lib/constants.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,qBAAqB;;;;;;;;CAQxB,CAAC;AAEX,eAAO,MAAM,qBAAqB,EAAE,MAAM,EAAyC,CAAC"}
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/lib/constants.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,qBAAqB;;;;;;;;CAQxB,CAAC;AAEX,eAAO,MAAM,qBAAqB,EAAE,MAAM,EAAyC,CAAC;AAEpF,eAAO,MAAM,uBAAuB,0BAA0B,CAAC"}
|
package/dist/lib/constants.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import "server-only";
|
|
2
|
-
export type MenuItemType = "info" | "link" | "separator";
|
|
2
|
+
export type MenuItemType = "info" | "link" | "separator" | "action";
|
|
3
3
|
export type ProfilePicMenuMenuItem = {
|
|
4
4
|
type: MenuItemType;
|
|
5
5
|
label?: string;
|
|
6
6
|
value?: string;
|
|
7
7
|
href?: string;
|
|
8
|
+
onSelect?: () => void;
|
|
8
9
|
order: number;
|
|
9
10
|
id: string;
|
|
10
11
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"profile_pic_menu_config.server.d.ts","sourceRoot":"","sources":["../../src/lib/profile_pic_menu_config.server.ts"],"names":[],"mappings":"AAEA,OAAO,aAAa,CAAC;AAQrB,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,MAAM,GAAG,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"profile_pic_menu_config.server.d.ts","sourceRoot":"","sources":["../../src/lib/profile_pic_menu_config.server.ts"],"names":[],"mappings":"AAEA,OAAO,aAAa,CAAC;AAQrB,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,MAAM,GAAG,WAAW,GAAG,QAAQ,CAAC;AAEpE,MAAM,MAAM,sBAAsB,GAAG;IACnC,IAAI,EAAE,YAAY,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;CACZ,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,kBAAkB,EAAE,OAAO,CAAC;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,sBAAsB,EAAE,CAAC;CAC7C,CAAC;AA4EF;;;;GAIG;AACH,wBAAgB,2BAA2B,IAAI,oBAAoB,CA4BlE"}
|
|
@@ -20,7 +20,7 @@ function parse_custom_menu_items(items_string) {
|
|
|
20
20
|
}
|
|
21
21
|
const type = parts[0];
|
|
22
22
|
if (type !== "info" && type !== "link" && type !== "separator") {
|
|
23
|
-
return; // Invalid type,
|
|
23
|
+
return; // Invalid type or action (action items carry callbacks, not expressible in INI)
|
|
24
24
|
}
|
|
25
25
|
if (type === "separator") {
|
|
26
26
|
const order = parseInt(parts[1] || "1", 10);
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const SQLITE_SCHEMA = "\n-- hazo_auth canonical SQLite schema\n-- This schema creates all tables required by hazo_auth\n\n-- Users table (from migration 011)\nCREATE TABLE IF NOT EXISTS hazo_users (\n id TEXT PRIMARY KEY,\n email_address TEXT NOT NULL UNIQUE,\n password_hash TEXT,\n name TEXT,\n email_verified BOOLEAN DEFAULT false,\n login_attempts INTEGER DEFAULT 0,\n last_logon TEXT,\n profile_picture_url TEXT,\n profile_source TEXT CHECK(profile_source IN ('gravatar', 'custom', 'predefined')),\n mfa_secret TEXT,\n url_on_logon TEXT,\n google_id TEXT UNIQUE,\n auth_providers TEXT DEFAULT 'email',\n user_type TEXT,\n app_user_data TEXT,\n status TEXT DEFAULT 'ACTIVE' CHECK(status IN ('PENDING', 'ACTIVE', 'BLOCKED')),\n managed_by_user_id TEXT REFERENCES hazo_users(id) ON DELETE SET NULL,\n pin_hash TEXT,\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n changed_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\n\nCREATE INDEX IF NOT EXISTS idx_hazo_users_email ON hazo_users(email_address);\nCREATE INDEX IF NOT EXISTS idx_hazo_users_google_id ON hazo_users(google_id);\nCREATE INDEX IF NOT EXISTS idx_hazo_users_status ON hazo_users(status);\n\n-- Refresh tokens table\n-- Note: runtime (token_service.ts) writes token_hash (argon2-hashed value) on\n-- insert and verifies via argon2.verify(token_hash, plaintext_token) on read.\n-- The plaintext \"token\" column is retained nullable for legacy compatibility\n-- but new writes only set token_hash.\nCREATE TABLE IF NOT EXISTS hazo_refresh_tokens (\n id TEXT PRIMARY KEY,\n user_id TEXT NOT NULL REFERENCES hazo_users(id) ON DELETE CASCADE,\n token TEXT UNIQUE,\n token_hash TEXT,\n token_type TEXT DEFAULT 'refresh',\n expires_at TEXT NOT NULL,\n created_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\n\nCREATE INDEX IF NOT EXISTS idx_hazo_refresh_tokens_user ON hazo_refresh_tokens(user_id);\nCREATE INDEX IF NOT EXISTS idx_hazo_refresh_tokens_token ON hazo_refresh_tokens(token);\nCREATE INDEX IF NOT EXISTS idx_hazo_refresh_tokens_token_hash ON hazo_refresh_tokens(token_hash);\n\n-- Roles table\nCREATE TABLE IF NOT EXISTS hazo_roles (\n id TEXT PRIMARY KEY,\n role_name TEXT NOT NULL UNIQUE,\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n changed_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\n\n-- Permissions table\nCREATE TABLE IF NOT EXISTS hazo_permissions (\n id TEXT PRIMARY KEY,\n permission_name TEXT NOT NULL UNIQUE,\n description TEXT,\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n changed_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\n\n-- Role-permission assignments (composite PK, no id column)\nCREATE TABLE IF NOT EXISTS hazo_role_permissions (\n role_id TEXT NOT NULL REFERENCES hazo_roles(id) ON DELETE CASCADE,\n permission_id TEXT NOT NULL REFERENCES hazo_permissions(id) ON DELETE CASCADE,\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n PRIMARY KEY (role_id, permission_id)\n);\n\n-- Unified scopes table (hierarchical multi-tenancy)\nCREATE TABLE IF NOT EXISTS hazo_scopes (\n id TEXT PRIMARY KEY,\n parent_id TEXT REFERENCES hazo_scopes(id) ON DELETE CASCADE,\n name TEXT NOT NULL,\n level TEXT NOT NULL,\n logo_url TEXT,\n primary_color TEXT,\n secondary_color TEXT,\n tagline TEXT,\n slug TEXT,\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n changed_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\n\nCREATE INDEX IF NOT EXISTS idx_hazo_scopes_parent ON hazo_scopes(parent_id);\nCREATE INDEX IF NOT EXISTS idx_hazo_scopes_level ON hazo_scopes(level);\nCREATE INDEX IF NOT EXISTS idx_hazo_scopes_slug ON hazo_scopes(slug);\n\n--
|
|
1
|
+
export declare const SQLITE_SCHEMA = "\n-- hazo_auth canonical SQLite schema\n-- This schema creates all tables required by hazo_auth\n\n-- Users table (from migration 011)\nCREATE TABLE IF NOT EXISTS hazo_users (\n id TEXT PRIMARY KEY,\n email_address TEXT NOT NULL UNIQUE,\n password_hash TEXT,\n name TEXT,\n email_verified BOOLEAN DEFAULT false,\n login_attempts INTEGER DEFAULT 0,\n last_logon TEXT,\n profile_picture_url TEXT,\n profile_source TEXT CHECK(profile_source IN ('gravatar', 'custom', 'predefined')),\n mfa_secret TEXT,\n url_on_logon TEXT,\n google_id TEXT UNIQUE,\n auth_providers TEXT DEFAULT 'email',\n user_type TEXT,\n app_user_data TEXT,\n status TEXT DEFAULT 'ACTIVE' CHECK(status IN ('PENDING', 'ACTIVE', 'BLOCKED')),\n managed_by_user_id TEXT REFERENCES hazo_users(id) ON DELETE SET NULL,\n pin_hash TEXT,\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n changed_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\n\nCREATE INDEX IF NOT EXISTS idx_hazo_users_email ON hazo_users(email_address);\nCREATE INDEX IF NOT EXISTS idx_hazo_users_google_id ON hazo_users(google_id);\nCREATE INDEX IF NOT EXISTS idx_hazo_users_status ON hazo_users(status);\n\n-- Refresh tokens table\n-- Note: runtime (token_service.ts) writes token_hash (argon2-hashed value) on\n-- insert and verifies via argon2.verify(token_hash, plaintext_token) on read.\n-- The plaintext \"token\" column is retained nullable for legacy compatibility\n-- but new writes only set token_hash.\nCREATE TABLE IF NOT EXISTS hazo_refresh_tokens (\n id TEXT PRIMARY KEY,\n user_id TEXT NOT NULL REFERENCES hazo_users(id) ON DELETE CASCADE,\n token TEXT UNIQUE,\n token_hash TEXT,\n token_type TEXT DEFAULT 'refresh',\n expires_at TEXT NOT NULL,\n created_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\n\nCREATE INDEX IF NOT EXISTS idx_hazo_refresh_tokens_user ON hazo_refresh_tokens(user_id);\nCREATE INDEX IF NOT EXISTS idx_hazo_refresh_tokens_token ON hazo_refresh_tokens(token);\nCREATE INDEX IF NOT EXISTS idx_hazo_refresh_tokens_token_hash ON hazo_refresh_tokens(token_hash);\n\n-- Roles table\nCREATE TABLE IF NOT EXISTS hazo_roles (\n id TEXT PRIMARY KEY,\n role_name TEXT NOT NULL UNIQUE,\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n changed_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\n\n-- Permissions table\nCREATE TABLE IF NOT EXISTS hazo_permissions (\n id TEXT PRIMARY KEY,\n permission_name TEXT NOT NULL UNIQUE,\n description TEXT,\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n changed_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\n\n-- Role-permission assignments (composite PK, no id column)\nCREATE TABLE IF NOT EXISTS hazo_role_permissions (\n role_id TEXT NOT NULL REFERENCES hazo_roles(id) ON DELETE CASCADE,\n permission_id TEXT NOT NULL REFERENCES hazo_permissions(id) ON DELETE CASCADE,\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n PRIMARY KEY (role_id, permission_id)\n);\n\n-- Unified scopes table (hierarchical multi-tenancy)\nCREATE TABLE IF NOT EXISTS hazo_scopes (\n id TEXT PRIMARY KEY,\n parent_id TEXT REFERENCES hazo_scopes(id) ON DELETE CASCADE,\n name TEXT NOT NULL,\n level TEXT NOT NULL,\n logo_url TEXT,\n primary_color TEXT,\n secondary_color TEXT,\n tagline TEXT,\n slug TEXT,\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n changed_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\n\nCREATE INDEX IF NOT EXISTS idx_hazo_scopes_parent ON hazo_scopes(parent_id);\nCREATE INDEX IF NOT EXISTS idx_hazo_scopes_level ON hazo_scopes(level);\nCREATE INDEX IF NOT EXISTS idx_hazo_scopes_slug ON hazo_scopes(slug);\n\n-- Default system scope (for non-multi-tenancy mode)\nINSERT OR IGNORE INTO hazo_scopes (id, parent_id, name, level, created_at, changed_at)\nVALUES ('00000000-0000-0000-0000-000000000001', NULL, 'System', 'default', datetime('now'), datetime('now'));\n\n-- User-scope assignments (membership model with scope-specific roles)\nCREATE TABLE IF NOT EXISTS hazo_user_scopes (\n user_id TEXT NOT NULL REFERENCES hazo_users(id) ON DELETE CASCADE,\n scope_id TEXT NOT NULL REFERENCES hazo_scopes(id) ON DELETE CASCADE,\n root_scope_id TEXT NOT NULL REFERENCES hazo_scopes(id) ON DELETE CASCADE,\n role_id TEXT NOT NULL REFERENCES hazo_roles(id) ON DELETE CASCADE,\n status TEXT DEFAULT 'ACTIVE' CHECK (status IN ('INVITED', 'ACTIVE', 'SUSPENDED', 'DEPARTED')),\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n changed_at TEXT NOT NULL DEFAULT (datetime('now')),\n PRIMARY KEY (user_id, scope_id)\n);\n\nCREATE INDEX IF NOT EXISTS idx_hazo_user_scopes_scope ON hazo_user_scopes(scope_id);\nCREATE INDEX IF NOT EXISTS idx_hazo_user_scopes_root ON hazo_user_scopes(root_scope_id);\nCREATE INDEX IF NOT EXISTS idx_hazo_user_scopes_role ON hazo_user_scopes(role_id);\n\n-- Invitations table\nCREATE TABLE IF NOT EXISTS hazo_invitations (\n id TEXT PRIMARY KEY,\n email_address TEXT NOT NULL,\n token TEXT NOT NULL UNIQUE,\n scope_id TEXT NOT NULL REFERENCES hazo_scopes(id) ON DELETE CASCADE,\n root_scope_id TEXT NOT NULL REFERENCES hazo_scopes(id) ON DELETE CASCADE,\n role_id TEXT NOT NULL REFERENCES hazo_roles(id) ON DELETE CASCADE,\n invited_by TEXT REFERENCES hazo_users(id) ON DELETE SET NULL,\n status TEXT NOT NULL DEFAULT 'PENDING' CHECK(status IN ('PENDING', 'ACCEPTED', 'EXPIRED', 'REVOKED')),\n expires_at TEXT NOT NULL,\n accepted_at TEXT,\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n changed_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\n\nCREATE INDEX IF NOT EXISTS idx_hazo_invitations_email ON hazo_invitations(email_address);\nCREATE INDEX IF NOT EXISTS idx_hazo_invitations_token ON hazo_invitations(token);\nCREATE INDEX IF NOT EXISTS idx_hazo_invitations_scope ON hazo_invitations(scope_id);\nCREATE INDEX IF NOT EXISTS idx_hazo_invitations_status ON hazo_invitations(status);\nCREATE INDEX IF NOT EXISTS idx_hazo_invitations_expires ON hazo_invitations(expires_at);\n\nCREATE INDEX IF NOT EXISTS idx_hazo_users_managed_by ON hazo_users(managed_by_user_id);\n\n-- Relationships table\nCREATE TABLE IF NOT EXISTS hazo_user_relationships (\n id TEXT PRIMARY KEY,\n parent_user_id TEXT NOT NULL REFERENCES hazo_users(id) ON DELETE CASCADE,\n child_user_id TEXT NOT NULL REFERENCES hazo_users(id) ON DELETE CASCADE,\n relationship_type TEXT NOT NULL DEFAULT 'parent',\n can_view_progress BOOLEAN DEFAULT true,\n can_edit_profile BOOLEAN DEFAULT true,\n can_delete BOOLEAN DEFAULT false,\n is_self BOOLEAN DEFAULT false,\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n UNIQUE(parent_user_id, child_user_id)\n);\n\nCREATE INDEX IF NOT EXISTS idx_hazo_user_relationships_parent ON hazo_user_relationships(parent_user_id);\nCREATE INDEX IF NOT EXISTS idx_hazo_user_relationships_child ON hazo_user_relationships(child_user_id);\n\n-- Firm admin role (for firm creators)\nINSERT OR IGNORE INTO hazo_roles (id, role_name, created_at, changed_at)\nVALUES (lower(hex(randomblob(4)) || '-' || hex(randomblob(2)) || '-4' || substr(hex(randomblob(2)),2) || '-' || substr('89ab',abs(random()) % 4 + 1, 1) || substr(hex(randomblob(2)),2) || '-' || hex(randomblob(6))), 'firm_admin', datetime('now'), datetime('now'));\n\n-- Google OAuth tokens (encrypted refresh/access tokens for extra-scope API access)\nCREATE TABLE IF NOT EXISTS hazo_google_oauth_tokens (\n id TEXT PRIMARY KEY,\n user_id TEXT NOT NULL REFERENCES hazo_users(id) ON DELETE CASCADE,\n provider TEXT NOT NULL DEFAULT 'google',\n refresh_token_enc TEXT NOT NULL,\n access_token_enc TEXT,\n scopes TEXT NOT NULL DEFAULT '',\n expires_at TEXT,\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n changed_at TEXT NOT NULL DEFAULT (datetime('now')),\n UNIQUE(user_id, provider)\n);\n\nCREATE INDEX IF NOT EXISTS idx_hazo_google_oauth_tokens_user ON hazo_google_oauth_tokens(user_id);\n";
|
|
2
2
|
//# sourceMappingURL=sqlite_schema.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sqlite_schema.d.ts","sourceRoot":"","sources":["../../../src/lib/schema/sqlite_schema.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,aAAa,
|
|
1
|
+
{"version":3,"file":"sqlite_schema.d.ts","sourceRoot":"","sources":["../../../src/lib/schema/sqlite_schema.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,aAAa,uoPA+KzB,CAAC"}
|
|
@@ -96,10 +96,6 @@ CREATE INDEX IF NOT EXISTS idx_hazo_scopes_parent ON hazo_scopes(parent_id);
|
|
|
96
96
|
CREATE INDEX IF NOT EXISTS idx_hazo_scopes_level ON hazo_scopes(level);
|
|
97
97
|
CREATE INDEX IF NOT EXISTS idx_hazo_scopes_slug ON hazo_scopes(slug);
|
|
98
98
|
|
|
99
|
-
-- Super admin scope
|
|
100
|
-
INSERT OR IGNORE INTO hazo_scopes (id, parent_id, name, level, created_at, changed_at)
|
|
101
|
-
VALUES ('00000000-0000-0000-0000-000000000000', NULL, 'Super Admin', 'system', datetime('now'), datetime('now'));
|
|
102
|
-
|
|
103
99
|
-- Default system scope (for non-multi-tenancy mode)
|
|
104
100
|
INSERT OR IGNORE INTO hazo_scopes (id, parent_id, name, level, created_at, changed_at)
|
|
105
101
|
VALUES ('00000000-0000-0000-0000-000000000001', NULL, 'System', 'default', datetime('now'), datetime('now'));
|
|
@@ -164,4 +160,20 @@ CREATE INDEX IF NOT EXISTS idx_hazo_user_relationships_child ON hazo_user_relati
|
|
|
164
160
|
-- Firm admin role (for firm creators)
|
|
165
161
|
INSERT OR IGNORE INTO hazo_roles (id, role_name, created_at, changed_at)
|
|
166
162
|
VALUES (lower(hex(randomblob(4)) || '-' || hex(randomblob(2)) || '-4' || substr(hex(randomblob(2)),2) || '-' || substr('89ab',abs(random()) % 4 + 1, 1) || substr(hex(randomblob(2)),2) || '-' || hex(randomblob(6))), 'firm_admin', datetime('now'), datetime('now'));
|
|
163
|
+
|
|
164
|
+
-- Google OAuth tokens (encrypted refresh/access tokens for extra-scope API access)
|
|
165
|
+
CREATE TABLE IF NOT EXISTS hazo_google_oauth_tokens (
|
|
166
|
+
id TEXT PRIMARY KEY,
|
|
167
|
+
user_id TEXT NOT NULL REFERENCES hazo_users(id) ON DELETE CASCADE,
|
|
168
|
+
provider TEXT NOT NULL DEFAULT 'google',
|
|
169
|
+
refresh_token_enc TEXT NOT NULL,
|
|
170
|
+
access_token_enc TEXT,
|
|
171
|
+
scopes TEXT NOT NULL DEFAULT '',
|
|
172
|
+
expires_at TEXT,
|
|
173
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
174
|
+
changed_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
175
|
+
UNIQUE(user_id, provider)
|
|
176
|
+
);
|
|
177
|
+
|
|
178
|
+
CREATE INDEX IF NOT EXISTS idx_hazo_google_oauth_tokens_user ON hazo_google_oauth_tokens(user_id);
|
|
167
179
|
`;
|
|
@@ -10,8 +10,6 @@ export type ScopeHierarchyConfig = {
|
|
|
10
10
|
scope_cache_ttl_minutes: number;
|
|
11
11
|
/** Maximum entries in scope cache (default: 5000) */
|
|
12
12
|
scope_cache_max_entries: number;
|
|
13
|
-
/** Super admin scope ID */
|
|
14
|
-
super_admin_scope_id: string;
|
|
15
13
|
/** Default system scope ID (for non-multi-tenancy mode) */
|
|
16
14
|
default_system_scope_id: string;
|
|
17
15
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scope_hierarchy_config.server.d.ts","sourceRoot":"","sources":["../../src/lib/scope_hierarchy_config.server.ts"],"names":[],"mappings":"AAEA,OAAO,aAAa,CAAC;AAYrB;;;GAGG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,gDAAgD;IAChD,YAAY,EAAE,OAAO,CAAC;IACtB,2DAA2D;IAC3D,uBAAuB,EAAE,MAAM,CAAC;IAChC,qDAAqD;IACrD,uBAAuB,EAAE,MAAM,CAAC;IAChC,
|
|
1
|
+
{"version":3,"file":"scope_hierarchy_config.server.d.ts","sourceRoot":"","sources":["../../src/lib/scope_hierarchy_config.server.ts"],"names":[],"mappings":"AAEA,OAAO,aAAa,CAAC;AAYrB;;;GAGG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,gDAAgD;IAChD,YAAY,EAAE,OAAO,CAAC;IACtB,2DAA2D;IAC3D,uBAAuB,EAAE,MAAM,CAAC;IAChC,qDAAqD;IACrD,uBAAuB,EAAE,MAAM,CAAC;IAChC,2DAA2D;IAC3D,uBAAuB,EAAE,MAAM,CAAC;CACjC,CAAC;AAQF;;;;GAIG;AACH,wBAAgB,0BAA0B,IAAI,oBAAoB,CA6BjE;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,CAE1C"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import "server-only";
|
|
4
4
|
// section: imports
|
|
5
5
|
import { get_config_value, get_config_number, get_config_boolean, } from "./config/config_loader.server.js";
|
|
6
|
-
import {
|
|
6
|
+
import { DEFAULT_SYSTEM_SCOPE_ID } from "./services/scope_service.js";
|
|
7
7
|
// section: constants
|
|
8
8
|
const SECTION_NAME = "hazo_auth__scope_hierarchy";
|
|
9
9
|
// section: helpers
|
|
@@ -19,13 +19,11 @@ export function get_scope_hierarchy_config() {
|
|
|
19
19
|
const scope_cache_ttl_minutes = get_config_number(SECTION_NAME, "scope_cache_ttl_minutes", 15);
|
|
20
20
|
const scope_cache_max_entries = get_config_number(SECTION_NAME, "scope_cache_max_entries", 5000);
|
|
21
21
|
// Scope IDs (with defaults)
|
|
22
|
-
const super_admin_scope_id = get_config_value(SECTION_NAME, "super_admin_scope_id", SUPER_ADMIN_SCOPE_ID);
|
|
23
22
|
const default_system_scope_id = get_config_value(SECTION_NAME, "default_system_scope_id", DEFAULT_SYSTEM_SCOPE_ID);
|
|
24
23
|
return {
|
|
25
24
|
enable_hrbac,
|
|
26
25
|
scope_cache_ttl_minutes,
|
|
27
26
|
scope_cache_max_entries,
|
|
28
|
-
super_admin_scope_id,
|
|
29
27
|
default_system_scope_id,
|
|
30
28
|
};
|
|
31
29
|
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
export declare class GoogleTokenStorageUnconfigured extends Error {
|
|
2
|
+
constructor();
|
|
3
|
+
}
|
|
4
|
+
export type StoreGoogleOAuthTokenParams = {
|
|
5
|
+
user_id: string;
|
|
6
|
+
refresh_token: string;
|
|
7
|
+
access_token?: string;
|
|
8
|
+
scopes: string;
|
|
9
|
+
expires_at?: string;
|
|
10
|
+
};
|
|
11
|
+
export type GoogleTokenResult = {
|
|
12
|
+
ok: true;
|
|
13
|
+
access_token: string;
|
|
14
|
+
scopes: string;
|
|
15
|
+
} | {
|
|
16
|
+
ok: false;
|
|
17
|
+
error: "not_connected" | "reconsent_required" | "refresh_failed" | "unconfigured";
|
|
18
|
+
};
|
|
19
|
+
export type GoogleTokenStatus = {
|
|
20
|
+
connected: boolean;
|
|
21
|
+
scopes: string;
|
|
22
|
+
expires_at: string | null;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Stores (inserts or updates) Google OAuth tokens for a user, encrypting sensitive fields.
|
|
26
|
+
* Throws GoogleTokenStorageUnconfigured if hazo_secure/crypto is unavailable or keys are missing.
|
|
27
|
+
*/
|
|
28
|
+
export declare function store_google_oauth_token(params: StoreGoogleOAuthTokenParams): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Returns a valid access token for the user, refreshing via Google if needed.
|
|
31
|
+
* Returns a typed error result instead of throwing for expected failure modes.
|
|
32
|
+
*/
|
|
33
|
+
export declare function getGoogleToken(userId: string, opts?: {
|
|
34
|
+
scopes?: string[];
|
|
35
|
+
}): Promise<GoogleTokenResult>;
|
|
36
|
+
/**
|
|
37
|
+
* Revokes the user's Google OAuth tokens — best-effort remote revocation, then deletes DB row.
|
|
38
|
+
*/
|
|
39
|
+
export declare function revoke_google_oauth_token(userId: string): Promise<{
|
|
40
|
+
ok: boolean;
|
|
41
|
+
error?: string;
|
|
42
|
+
}>;
|
|
43
|
+
/**
|
|
44
|
+
* Returns connection status and scope information for a user's Google OAuth connection.
|
|
45
|
+
* Does not decrypt or refresh tokens.
|
|
46
|
+
*/
|
|
47
|
+
export declare function get_google_token_status(userId: string): Promise<GoogleTokenStatus>;
|
|
48
|
+
//# sourceMappingURL=google_token_service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"google_token_service.d.ts","sourceRoot":"","sources":["../../../src/lib/services/google_token_service.ts"],"names":[],"mappings":"AAUA,qBAAa,8BAA+B,SAAQ,KAAK;;CAOxD;AAID,MAAM,MAAM,2BAA2B,GAAG;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GACzB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAClD;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,eAAe,GAAG,oBAAoB,GAAG,gBAAgB,GAAG,cAAc,CAAA;CAAE,CAAC;AAErG,MAAM,MAAM,iBAAiB,GAAG;IAC9B,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B,CAAC;AA6CF;;;GAGG;AACH,wBAAsB,wBAAwB,CAC5C,MAAM,EAAE,2BAA2B,GAClC,OAAO,CAAC,IAAI,CAAC,CA0Ef;AAID;;;GAGG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,MAAM,EACd,IAAI,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,GAC3B,OAAO,CAAC,iBAAiB,CAAC,CA6I5B;AAID;;GAEG;AACH,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,MAAM,GACb,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CA6D1C;AAID;;;GAGG;AACH,wBAAsB,uBAAuB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAexF"}
|