hazo_auth 4.2.0 → 4.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/hazo_auth.mjs +35 -0
- package/cli-src/assets/images/forgot_password_default.jpg +0 -0
- package/cli-src/assets/images/login_default.jpg +0 -0
- package/cli-src/assets/images/register_default.jpg +0 -0
- package/cli-src/assets/images/reset_password_default.jpg +0 -0
- package/cli-src/assets/images/verify_email_default.jpg +0 -0
- package/cli-src/cli/generate.ts +276 -0
- package/cli-src/cli/index.ts +207 -0
- package/cli-src/cli/init.ts +254 -0
- package/cli-src/cli/init_users.ts +376 -0
- package/cli-src/cli/validate.ts +581 -0
- package/cli-src/lib/already_logged_in_config.server.ts +46 -0
- package/cli-src/lib/app_logger.ts +24 -0
- package/cli-src/lib/auth/auth_cache.ts +220 -0
- package/cli-src/lib/auth/auth_rate_limiter.ts +121 -0
- package/cli-src/lib/auth/auth_types.ts +117 -0
- package/cli-src/lib/auth/auth_utils.server.ts +196 -0
- package/cli-src/lib/auth/dev_lock_validator.edge.ts +171 -0
- package/cli-src/lib/auth/hazo_get_auth.server.ts +583 -0
- package/cli-src/lib/auth/index.ts +23 -0
- package/cli-src/lib/auth/nextauth_config.ts +227 -0
- package/cli-src/lib/auth/org_cache.ts +148 -0
- package/cli-src/lib/auth/scope_cache.ts +233 -0
- package/cli-src/lib/auth/server_auth.ts +88 -0
- package/cli-src/lib/auth/session_token_validator.edge.ts +92 -0
- package/cli-src/lib/auth_utility_config.server.ts +136 -0
- package/cli-src/lib/config/config_loader.server.ts +164 -0
- package/cli-src/lib/config/default_config.ts +243 -0
- package/cli-src/lib/dev_lock_config.server.ts +148 -0
- package/cli-src/lib/email_verification_config.server.ts +63 -0
- package/cli-src/lib/file_types_config.server.ts +25 -0
- package/cli-src/lib/forgot_password_config.server.ts +63 -0
- package/cli-src/lib/hazo_connect_instance.server.ts +101 -0
- package/cli-src/lib/hazo_connect_setup.server.ts +194 -0
- package/cli-src/lib/hazo_connect_setup.ts +54 -0
- package/cli-src/lib/index.ts +46 -0
- package/cli-src/lib/login_config.server.ts +106 -0
- package/cli-src/lib/messages_config.server.ts +45 -0
- package/cli-src/lib/migrations/apply_migration.ts +105 -0
- package/cli-src/lib/multi_tenancy_config.server.ts +94 -0
- package/cli-src/lib/my_settings_config.server.ts +135 -0
- package/cli-src/lib/oauth_config.server.ts +87 -0
- package/cli-src/lib/password_requirements_config.server.ts +40 -0
- package/cli-src/lib/profile_pic_menu_config.server.ts +138 -0
- package/cli-src/lib/profile_picture_config.server.ts +56 -0
- package/cli-src/lib/register_config.server.ts +101 -0
- package/cli-src/lib/reset_password_config.server.ts +103 -0
- package/cli-src/lib/scope_hierarchy_config.server.ts +151 -0
- package/cli-src/lib/services/email_service.ts +587 -0
- package/cli-src/lib/services/email_verification_service.ts +270 -0
- package/cli-src/lib/services/index.ts +16 -0
- package/cli-src/lib/services/login_service.ts +150 -0
- package/cli-src/lib/services/oauth_service.ts +494 -0
- package/cli-src/lib/services/org_service.ts +965 -0
- package/cli-src/lib/services/password_change_service.ts +154 -0
- package/cli-src/lib/services/password_reset_service.ts +418 -0
- package/cli-src/lib/services/profile_picture_remove_service.ts +120 -0
- package/cli-src/lib/services/profile_picture_service.ts +451 -0
- package/cli-src/lib/services/profile_picture_source_mapper.ts +62 -0
- package/cli-src/lib/services/registration_service.ts +185 -0
- package/cli-src/lib/services/scope_labels_service.ts +348 -0
- package/cli-src/lib/services/scope_service.ts +778 -0
- package/cli-src/lib/services/session_token_service.ts +178 -0
- package/cli-src/lib/services/token_service.ts +240 -0
- package/cli-src/lib/services/user_profiles_cache.ts +189 -0
- package/cli-src/lib/services/user_profiles_service.ts +264 -0
- package/cli-src/lib/services/user_scope_service.ts +554 -0
- package/cli-src/lib/services/user_update_service.ts +141 -0
- package/cli-src/lib/ui_shell_config.server.ts +73 -0
- package/cli-src/lib/ui_sizes_config.server.ts +37 -0
- package/cli-src/lib/user_fields_config.server.ts +31 -0
- package/cli-src/lib/user_management_config.server.ts +39 -0
- package/cli-src/lib/user_profiles_config.server.ts +55 -0
- package/cli-src/lib/utils/api_route_helpers.ts +60 -0
- package/cli-src/lib/utils/error_sanitizer.ts +75 -0
- package/cli-src/lib/utils/password_validator.ts +65 -0
- package/cli-src/lib/utils.ts +11 -0
- package/cli-src/server/logging/logger_service.ts +56 -0
- package/cli-src/server/types/app_types.ts +74 -0
- package/cli-src/server/types/express.d.ts +16 -0
- package/dist/cli/index.js +18 -0
- package/dist/cli/init_users.d.ts +17 -0
- package/dist/cli/init_users.d.ts.map +1 -0
- package/dist/cli/init_users.js +307 -0
- package/dist/components/layouts/dev_lock/index.d.ts +29 -0
- package/dist/components/layouts/dev_lock/index.d.ts.map +1 -0
- package/dist/components/layouts/dev_lock/index.js +60 -0
- package/dist/components/layouts/index.d.ts +2 -0
- package/dist/components/layouts/index.d.ts.map +1 -1
- package/dist/components/layouts/index.js +1 -0
- package/dist/components/layouts/org_management/index.d.ts +26 -0
- package/dist/components/layouts/org_management/index.d.ts.map +1 -0
- package/dist/components/layouts/org_management/index.js +75 -0
- package/dist/components/layouts/shared/config/layout_customization.d.ts +2 -7
- package/dist/components/layouts/shared/config/layout_customization.d.ts.map +1 -1
- package/dist/components/layouts/user_management/components/org_hierarchy_tab.d.ts +13 -0
- package/dist/components/layouts/user_management/components/org_hierarchy_tab.d.ts.map +1 -0
- package/dist/components/layouts/user_management/components/org_hierarchy_tab.js +276 -0
- package/dist/components/layouts/user_management/index.d.ts +3 -1
- package/dist/components/layouts/user_management/index.d.ts.map +1 -1
- package/dist/components/layouts/user_management/index.js +10 -4
- package/dist/lib/auth/auth_types.d.ts +6 -0
- package/dist/lib/auth/auth_types.d.ts.map +1 -1
- package/dist/lib/auth/dev_lock_validator.edge.d.ts +38 -0
- package/dist/lib/auth/dev_lock_validator.edge.d.ts.map +1 -0
- package/dist/lib/auth/dev_lock_validator.edge.js +122 -0
- package/dist/lib/auth/hazo_get_auth.server.d.ts.map +1 -1
- package/dist/lib/auth/hazo_get_auth.server.js +61 -1
- package/dist/lib/auth/org_cache.d.ts +65 -0
- package/dist/lib/auth/org_cache.d.ts.map +1 -0
- package/dist/lib/auth/org_cache.js +103 -0
- package/dist/lib/config/default_config.d.ts +76 -0
- package/dist/lib/config/default_config.d.ts.map +1 -1
- package/dist/lib/config/default_config.js +42 -0
- package/dist/lib/dev_lock_config.server.d.ts +41 -0
- package/dist/lib/dev_lock_config.server.d.ts.map +1 -0
- package/dist/lib/dev_lock_config.server.js +50 -0
- package/dist/lib/multi_tenancy_config.server.d.ts +30 -0
- package/dist/lib/multi_tenancy_config.server.d.ts.map +1 -0
- package/dist/lib/multi_tenancy_config.server.js +41 -0
- package/dist/lib/services/org_service.d.ts +191 -0
- package/dist/lib/services/org_service.d.ts.map +1 -0
- package/dist/lib/services/org_service.js +746 -0
- package/dist/lib/utils/password_validator.d.ts +7 -1
- package/dist/lib/utils/password_validator.d.ts.map +1 -1
- package/dist/page_components/dev_lock.d.ts +11 -0
- package/dist/page_components/dev_lock.d.ts.map +1 -0
- package/dist/page_components/dev_lock.js +17 -0
- package/dist/page_components/index.d.ts +1 -0
- package/dist/page_components/index.d.ts.map +1 -1
- package/dist/page_components/index.js +1 -0
- package/dist/page_components/org_management.d.ts +27 -0
- package/dist/page_components/org_management.d.ts.map +1 -0
- package/dist/page_components/org_management.js +18 -0
- package/hazo_auth_config.example.ini +30 -0
- package/package.json +27 -3
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
// file_description: service for managing HRBAC scope labels using hazo_connect
|
|
2
|
+
// section: imports
|
|
3
|
+
import type { HazoConnectAdapter } from "hazo_connect";
|
|
4
|
+
import { createCrudService } from "hazo_connect/server";
|
|
5
|
+
import { randomUUID } from "crypto";
|
|
6
|
+
import { create_app_logger } from "../app_logger.js";
|
|
7
|
+
import { sanitize_error_for_user } from "../utils/error_sanitizer.js";
|
|
8
|
+
import type { ScopeLevel } from "./scope_service";
|
|
9
|
+
import { SCOPE_LEVELS } from "./scope_service.js";
|
|
10
|
+
|
|
11
|
+
// section: types
|
|
12
|
+
export type ScopeLabel = {
|
|
13
|
+
id: string;
|
|
14
|
+
org: string;
|
|
15
|
+
scope_type: ScopeLevel;
|
|
16
|
+
label: string;
|
|
17
|
+
created_at: string;
|
|
18
|
+
changed_at: string;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export type ScopeLabelResult = {
|
|
22
|
+
success: boolean;
|
|
23
|
+
label?: ScopeLabel;
|
|
24
|
+
labels?: ScopeLabel[];
|
|
25
|
+
error?: string;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
// section: constants
|
|
29
|
+
export const DEFAULT_SCOPE_LABELS: Record<ScopeLevel, string> = {
|
|
30
|
+
hazo_scopes_l1: "Level 1",
|
|
31
|
+
hazo_scopes_l2: "Level 2",
|
|
32
|
+
hazo_scopes_l3: "Level 3",
|
|
33
|
+
hazo_scopes_l4: "Level 4",
|
|
34
|
+
hazo_scopes_l5: "Level 5",
|
|
35
|
+
hazo_scopes_l6: "Level 6",
|
|
36
|
+
hazo_scopes_l7: "Level 7",
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
// section: helpers
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Gets all scope labels for an organization
|
|
43
|
+
*/
|
|
44
|
+
export async function get_scope_labels(
|
|
45
|
+
adapter: HazoConnectAdapter,
|
|
46
|
+
org: string,
|
|
47
|
+
): Promise<ScopeLabelResult> {
|
|
48
|
+
try {
|
|
49
|
+
const label_service = createCrudService(adapter, "hazo_scope_labels");
|
|
50
|
+
const labels = await label_service.findBy({ org });
|
|
51
|
+
|
|
52
|
+
return {
|
|
53
|
+
success: true,
|
|
54
|
+
labels: Array.isArray(labels) ? (labels as ScopeLabel[]) : [],
|
|
55
|
+
};
|
|
56
|
+
} catch (error) {
|
|
57
|
+
const logger = create_app_logger();
|
|
58
|
+
const error_message = sanitize_error_for_user(error, {
|
|
59
|
+
logToConsole: true,
|
|
60
|
+
logToLogger: true,
|
|
61
|
+
logger,
|
|
62
|
+
context: {
|
|
63
|
+
filename: "scope_labels_service.ts",
|
|
64
|
+
line_number: 0,
|
|
65
|
+
operation: "get_scope_labels",
|
|
66
|
+
org,
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
return {
|
|
71
|
+
success: false,
|
|
72
|
+
error: error_message,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Gets all scope labels for an organization, with defaults filled in for missing levels
|
|
79
|
+
*/
|
|
80
|
+
export async function get_scope_labels_with_defaults(
|
|
81
|
+
adapter: HazoConnectAdapter,
|
|
82
|
+
org: string,
|
|
83
|
+
custom_defaults?: Record<ScopeLevel, string>,
|
|
84
|
+
): Promise<ScopeLabelResult> {
|
|
85
|
+
try {
|
|
86
|
+
const result = await get_scope_labels(adapter, org);
|
|
87
|
+
if (!result.success) {
|
|
88
|
+
return result;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const existing_labels = result.labels || [];
|
|
92
|
+
const labels_map = new Map<ScopeLevel, ScopeLabel>();
|
|
93
|
+
|
|
94
|
+
// Add existing labels to map
|
|
95
|
+
for (const label of existing_labels) {
|
|
96
|
+
labels_map.set(label.scope_type, label);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Create synthetic entries for missing levels (with default labels)
|
|
100
|
+
const defaults = custom_defaults || DEFAULT_SCOPE_LABELS;
|
|
101
|
+
const all_labels: ScopeLabel[] = [];
|
|
102
|
+
|
|
103
|
+
for (const level of SCOPE_LEVELS) {
|
|
104
|
+
if (labels_map.has(level)) {
|
|
105
|
+
all_labels.push(labels_map.get(level)!);
|
|
106
|
+
} else {
|
|
107
|
+
// Create a synthetic label entry (not persisted)
|
|
108
|
+
all_labels.push({
|
|
109
|
+
id: "", // Empty ID indicates this is a default, not from DB
|
|
110
|
+
org,
|
|
111
|
+
scope_type: level,
|
|
112
|
+
label: defaults[level],
|
|
113
|
+
created_at: "",
|
|
114
|
+
changed_at: "",
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return {
|
|
120
|
+
success: true,
|
|
121
|
+
labels: all_labels,
|
|
122
|
+
};
|
|
123
|
+
} catch (error) {
|
|
124
|
+
const logger = create_app_logger();
|
|
125
|
+
const error_message = sanitize_error_for_user(error, {
|
|
126
|
+
logToConsole: true,
|
|
127
|
+
logToLogger: true,
|
|
128
|
+
logger,
|
|
129
|
+
context: {
|
|
130
|
+
filename: "scope_labels_service.ts",
|
|
131
|
+
line_number: 0,
|
|
132
|
+
operation: "get_scope_labels_with_defaults",
|
|
133
|
+
org,
|
|
134
|
+
},
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
return {
|
|
138
|
+
success: false,
|
|
139
|
+
error: error_message,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Gets the label for a specific scope level
|
|
146
|
+
* Returns the custom label if set, otherwise returns the default
|
|
147
|
+
*/
|
|
148
|
+
export async function get_label_for_level(
|
|
149
|
+
adapter: HazoConnectAdapter,
|
|
150
|
+
org: string,
|
|
151
|
+
scope_type: ScopeLevel,
|
|
152
|
+
custom_default?: string,
|
|
153
|
+
): Promise<string> {
|
|
154
|
+
try {
|
|
155
|
+
const label_service = createCrudService(adapter, "hazo_scope_labels");
|
|
156
|
+
const labels = await label_service.findBy({ org, scope_type });
|
|
157
|
+
|
|
158
|
+
if (Array.isArray(labels) && labels.length > 0) {
|
|
159
|
+
return (labels[0] as ScopeLabel).label;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return custom_default || DEFAULT_SCOPE_LABELS[scope_type];
|
|
163
|
+
} catch {
|
|
164
|
+
// Return default on any error
|
|
165
|
+
return custom_default || DEFAULT_SCOPE_LABELS[scope_type];
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Creates or updates a scope label for an organization
|
|
171
|
+
* Uses upsert pattern - creates if not exists, updates if exists
|
|
172
|
+
*/
|
|
173
|
+
export async function upsert_scope_label(
|
|
174
|
+
adapter: HazoConnectAdapter,
|
|
175
|
+
org: string,
|
|
176
|
+
scope_type: ScopeLevel,
|
|
177
|
+
label: string,
|
|
178
|
+
): Promise<ScopeLabelResult> {
|
|
179
|
+
try {
|
|
180
|
+
const label_service = createCrudService(adapter, "hazo_scope_labels");
|
|
181
|
+
const now = new Date().toISOString();
|
|
182
|
+
|
|
183
|
+
// Check if label already exists for this org + scope_type
|
|
184
|
+
const existing = await label_service.findBy({ org, scope_type });
|
|
185
|
+
|
|
186
|
+
if (Array.isArray(existing) && existing.length > 0) {
|
|
187
|
+
// Update existing
|
|
188
|
+
const existing_label = existing[0] as ScopeLabel;
|
|
189
|
+
const updated = await label_service.updateById(existing_label.id, {
|
|
190
|
+
label,
|
|
191
|
+
changed_at: now,
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
if (!Array.isArray(updated) || updated.length === 0) {
|
|
195
|
+
return {
|
|
196
|
+
success: false,
|
|
197
|
+
error: "Failed to update scope label",
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
return {
|
|
202
|
+
success: true,
|
|
203
|
+
label: updated[0] as ScopeLabel,
|
|
204
|
+
};
|
|
205
|
+
} else {
|
|
206
|
+
// Create new
|
|
207
|
+
const inserted = await label_service.insert({
|
|
208
|
+
id: randomUUID(),
|
|
209
|
+
org,
|
|
210
|
+
scope_type,
|
|
211
|
+
label,
|
|
212
|
+
created_at: now,
|
|
213
|
+
changed_at: now,
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
if (!Array.isArray(inserted) || inserted.length === 0) {
|
|
217
|
+
return {
|
|
218
|
+
success: false,
|
|
219
|
+
error: "Failed to create scope label",
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
return {
|
|
224
|
+
success: true,
|
|
225
|
+
label: inserted[0] as ScopeLabel,
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
} catch (error) {
|
|
229
|
+
const logger = create_app_logger();
|
|
230
|
+
const error_message = sanitize_error_for_user(error, {
|
|
231
|
+
logToConsole: true,
|
|
232
|
+
logToLogger: true,
|
|
233
|
+
logger,
|
|
234
|
+
context: {
|
|
235
|
+
filename: "scope_labels_service.ts",
|
|
236
|
+
line_number: 0,
|
|
237
|
+
operation: "upsert_scope_label",
|
|
238
|
+
org,
|
|
239
|
+
scope_type,
|
|
240
|
+
label,
|
|
241
|
+
},
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
return {
|
|
245
|
+
success: false,
|
|
246
|
+
error: error_message,
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Batch upsert scope labels for an organization
|
|
253
|
+
* Useful for saving all labels at once from the UI
|
|
254
|
+
*/
|
|
255
|
+
export async function batch_upsert_scope_labels(
|
|
256
|
+
adapter: HazoConnectAdapter,
|
|
257
|
+
org: string,
|
|
258
|
+
labels: Array<{ scope_type: ScopeLevel; label: string }>,
|
|
259
|
+
): Promise<ScopeLabelResult> {
|
|
260
|
+
try {
|
|
261
|
+
const results: ScopeLabel[] = [];
|
|
262
|
+
|
|
263
|
+
for (const { scope_type, label } of labels) {
|
|
264
|
+
const result = await upsert_scope_label(adapter, org, scope_type, label);
|
|
265
|
+
if (!result.success) {
|
|
266
|
+
return {
|
|
267
|
+
success: false,
|
|
268
|
+
error: `Failed to save label for ${scope_type}: ${result.error}`,
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
if (result.label) {
|
|
272
|
+
results.push(result.label);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
return {
|
|
277
|
+
success: true,
|
|
278
|
+
labels: results,
|
|
279
|
+
};
|
|
280
|
+
} catch (error) {
|
|
281
|
+
const logger = create_app_logger();
|
|
282
|
+
const error_message = sanitize_error_for_user(error, {
|
|
283
|
+
logToConsole: true,
|
|
284
|
+
logToLogger: true,
|
|
285
|
+
logger,
|
|
286
|
+
context: {
|
|
287
|
+
filename: "scope_labels_service.ts",
|
|
288
|
+
line_number: 0,
|
|
289
|
+
operation: "batch_upsert_scope_labels",
|
|
290
|
+
org,
|
|
291
|
+
},
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
return {
|
|
295
|
+
success: false,
|
|
296
|
+
error: error_message,
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Deletes a scope label, reverting to default
|
|
303
|
+
*/
|
|
304
|
+
export async function delete_scope_label(
|
|
305
|
+
adapter: HazoConnectAdapter,
|
|
306
|
+
org: string,
|
|
307
|
+
scope_type: ScopeLevel,
|
|
308
|
+
): Promise<ScopeLabelResult> {
|
|
309
|
+
try {
|
|
310
|
+
const label_service = createCrudService(adapter, "hazo_scope_labels");
|
|
311
|
+
|
|
312
|
+
// Find the label
|
|
313
|
+
const existing = await label_service.findBy({ org, scope_type });
|
|
314
|
+
|
|
315
|
+
if (!Array.isArray(existing) || existing.length === 0) {
|
|
316
|
+
return {
|
|
317
|
+
success: true, // Already doesn't exist
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
const existing_label = existing[0] as ScopeLabel;
|
|
322
|
+
await label_service.deleteById(existing_label.id);
|
|
323
|
+
|
|
324
|
+
return {
|
|
325
|
+
success: true,
|
|
326
|
+
label: existing_label,
|
|
327
|
+
};
|
|
328
|
+
} catch (error) {
|
|
329
|
+
const logger = create_app_logger();
|
|
330
|
+
const error_message = sanitize_error_for_user(error, {
|
|
331
|
+
logToConsole: true,
|
|
332
|
+
logToLogger: true,
|
|
333
|
+
logger,
|
|
334
|
+
context: {
|
|
335
|
+
filename: "scope_labels_service.ts",
|
|
336
|
+
line_number: 0,
|
|
337
|
+
operation: "delete_scope_label",
|
|
338
|
+
org,
|
|
339
|
+
scope_type,
|
|
340
|
+
},
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
return {
|
|
344
|
+
success: false,
|
|
345
|
+
error: error_message,
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
}
|