@profoundlogic/coderflow-server 0.7.7 → 0.7.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/coder-server.js +1 -1
- package/dist/config.js +1 -1
- package/dist/lib/agent-keepalive.js +1 -1
- package/dist/lib/agent-models.js +1 -1
- package/dist/lib/api-keys.js +1 -1
- package/dist/lib/apiKeys.js +1 -1
- package/dist/lib/app-server-ports.js +1 -1
- package/dist/lib/auto-judge.js +1 -1
- package/dist/lib/automation-service.js +1 -1
- package/dist/lib/basic-auth.js +1 -1
- package/dist/lib/bindings.js +1 -1
- package/dist/lib/build-history.js +1 -1
- package/dist/lib/build-output-service.js +1 -1
- package/dist/lib/build-scheduler.js +1 -1
- package/dist/lib/build-service.js +1 -1
- package/dist/lib/ca-certificates.js +1 -1
- package/dist/lib/claude-oauth-refresh.js +1 -1
- package/dist/lib/cli/build.js +1 -1
- package/dist/lib/cli/cleanup-users.js +1 -1
- package/dist/lib/cli/config-command.js +1 -1
- package/dist/lib/cli/config.js +1 -1
- package/dist/lib/cli/create-user.js +1 -1
- package/dist/lib/cli/grant-admin.js +1 -1
- package/dist/lib/cli/init.js +1 -1
- package/dist/lib/cli/jira.js +1 -1
- package/dist/lib/cli/license.js +1 -1
- package/dist/lib/cli/list-roles.js +1 -1
- package/dist/lib/cli/list-users.js +1 -1
- package/dist/lib/cli/server-manager.js +1 -1
- package/dist/lib/cli/set-password.js +1 -1
- package/dist/lib/compression-filter.js +1 -0
- package/dist/lib/config-migration.js +1 -1
- package/dist/lib/container-credential-sync.js +1 -1
- package/dist/lib/container-tokens.js +1 -1
- package/dist/lib/data-dir.js +1 -1
- package/dist/lib/deployment-history.js +1 -1
- package/dist/lib/deployment-service.js +1 -1
- package/dist/lib/docker-utils.js +1 -1
- package/dist/lib/email.js +1 -1
- package/dist/lib/emailTemplates.js +1 -1
- package/dist/lib/entitlement.js +1 -1
- package/dist/lib/external-connections.js +1 -1
- package/dist/lib/fetch-utils.js +1 -1
- package/dist/lib/git-commit-details-route.js +1 -1
- package/dist/lib/git-history-diff-guardrails.js +1 -1
- package/dist/lib/git-provider-service.js +1 -1
- package/dist/lib/git-provider-setup/github-setup-handler.js +1 -1
- package/dist/lib/git-provider-setup/index.js +1 -1
- package/dist/lib/git-provider-setup/setup-factory.js +1 -1
- package/dist/lib/git-provider-setup/setup-interface.js +1 -1
- package/dist/lib/git-providers/azure-devops-provider.js +1 -1
- package/dist/lib/git-providers/github-app-provider.js +1 -1
- package/dist/lib/git-providers/index.js +1 -1
- package/dist/lib/git-providers/provider-factory.js +1 -1
- package/dist/lib/git-providers/provider-interface.js +1 -1
- package/dist/lib/github-urls.js +1 -1
- package/dist/lib/group-objective-linking.js +1 -1
- package/dist/lib/ibmi-sync.js +1 -1
- package/dist/lib/jira-client.js +1 -1
- package/dist/lib/judge-blinding.js +1 -1
- package/dist/lib/logger.js +1 -1
- package/dist/lib/memory-utils.js +1 -1
- package/dist/lib/migration-to-scoped-rbac.js +1 -1
- package/dist/lib/model-fetcher.js +1 -1
- package/dist/lib/notifications.js +1 -1
- package/dist/lib/objective-context.js +1 -1
- package/dist/lib/oidc-auth.js +1 -1
- package/dist/lib/oidc-device-flow.js +1 -1
- package/dist/lib/passwordTokens.js +1 -1
- package/dist/lib/permission-resolver.js +1 -1
- package/dist/lib/pin-cascade.js +1 -1
- package/dist/lib/provider-accounts.js +1 -1
- package/dist/lib/provider-oauth.js +1 -1
- package/dist/lib/provider-profile.js +1 -1
- package/dist/lib/provider-token-refresh.js +1 -1
- package/dist/lib/rbac-user-state.js +1 -1
- package/dist/lib/request-url.js +1 -1
- package/dist/lib/rewind.js +1 -1
- package/dist/lib/role-definitions.js +1 -1
- package/dist/lib/roles.js +1 -1
- package/dist/lib/secrets.js +1 -1
- package/dist/lib/setup-repo-git-auth.js +1 -1
- package/dist/lib/state-capture.js +1 -1
- package/dist/lib/static-files.js +1 -1
- package/dist/lib/task-aliases.js +1 -1
- package/dist/lib/task-name-format.js +1 -1
- package/dist/lib/task-name-generator.js +1 -1
- package/dist/lib/task-source-metadata.js +1 -1
- package/dist/lib/teams.js +1 -1
- package/dist/lib/user-git-oauth.js +1 -1
- package/dist/lib/user-git-tokens.js +1 -1
- package/dist/lib/users.js +1 -1
- package/dist/middleware/requireAuth.js +1 -1
- package/dist/middleware/requireInit.js +1 -1
- package/dist/middleware/requirePermission.js +1 -1
- package/dist/package.json +1 -1
- package/dist/playwright.config.js +1 -1
- package/dist/playwright.task-terminal.config.js +1 -1
- package/dist/routes/apiKeys.js +1 -1
- package/dist/routes/auth-oidc.js +1 -1
- package/dist/routes/auth.js +1 -1
- package/dist/routes/automations.js +1 -1
- package/dist/routes/bindings.js +1 -1
- package/dist/routes/build.js +1 -1
- package/dist/routes/containers.js +1 -1
- package/dist/routes/deploy-task.js +1 -1
- package/dist/routes/environment-management.js +1 -1
- package/dist/routes/environments.js +1 -1
- package/dist/routes/external-skills.js +1 -1
- package/dist/routes/git-credentials.js +1 -1
- package/dist/routes/git-oauth.js +1 -1
- package/dist/routes/git-provider-setup.js +1 -1
- package/dist/routes/health.js +1 -1
- package/dist/routes/jira.js +1 -1
- package/dist/routes/logs.js +1 -0
- package/dist/routes/objective-management.js +1 -1
- package/dist/routes/password.js +1 -1
- package/dist/routes/prompt.js +1 -1
- package/dist/routes/provider-auth.js +1 -1
- package/dist/routes/qa.js +1 -1
- package/dist/routes/roles.js +1 -1
- package/dist/routes/settings.js +1 -1
- package/dist/routes/skill-management.js +1 -1
- package/dist/routes/skills.js +1 -1
- package/dist/routes/stats.js +1 -0
- package/dist/routes/tasks.js +1 -1
- package/dist/routes/teams.js +1 -1
- package/dist/routes/templates.js +1 -1
- package/dist/routes/test-task.js +1 -1
- package/dist/routes/test.js +1 -1
- package/dist/routes/users.js +1 -1
- package/dist/routes/visualizations.js +1 -1
- package/dist/scripts/create-user.js +1 -1
- package/dist/scripts/migrate-config-to-data-dir.js +1 -1
- package/dist/start.js +1 -1
- package/dist/web-ui/public/activity-detail-modal.js +1 -1
- package/dist/web-ui/public/activity-feed.js +1 -1
- package/dist/web-ui/public/activity-formatters.js +1 -1
- package/dist/web-ui/public/admin.css +682 -0
- package/dist/web-ui/public/admin.html +648 -0
- package/dist/web-ui/public/admin.js +1 -0
- package/dist/web-ui/public/agent-event-parser.js +1 -1
- package/dist/web-ui/public/app.js +1 -1
- package/dist/web-ui/public/approve-dialog.js +1 -1
- package/dist/web-ui/public/automation-links.js +1 -1
- package/dist/web-ui/public/automation-schedule.js +1 -1
- package/dist/web-ui/public/comments-widget.js +1 -1
- package/dist/web-ui/public/diff-utils.js +1 -1
- package/dist/web-ui/public/environments.html +3 -3
- package/dist/web-ui/public/environments.js +1 -1
- package/dist/web-ui/public/feedback-widget.js +1 -1
- package/dist/web-ui/public/file-selection-tree.js +1 -1
- package/dist/web-ui/public/git-history-lazy-utils.js +1 -1
- package/dist/web-ui/public/git-history.html +2 -2
- package/dist/web-ui/public/git-history.js +1 -1
- package/dist/web-ui/public/git-status.js +1 -1
- package/dist/web-ui/public/ibmi-file-filter.js +1 -1
- package/dist/web-ui/public/index.html +2 -170
- package/dist/web-ui/public/index.js +1 -1
- package/dist/web-ui/public/login.js +1 -1
- package/dist/web-ui/public/markdown-editor.js +1 -1
- package/dist/web-ui/public/markdown-file-editor.js +1 -1
- package/dist/web-ui/public/modal-maximize.js +1 -1
- package/dist/web-ui/public/notifications.js +1 -1
- package/dist/web-ui/public/permissions.js +1 -1
- package/dist/web-ui/public/pr-dialog.js +1 -1
- package/dist/web-ui/public/roles.html +2 -2
- package/dist/web-ui/public/roles.js +1 -1
- package/dist/web-ui/public/settings.html +66 -4
- package/dist/web-ui/public/settings.js +1 -1
- package/dist/web-ui/public/setup-password.js +1 -1
- package/dist/web-ui/public/skills.html +2 -2
- package/dist/web-ui/public/skills.js +1 -1
- package/dist/web-ui/public/sse-client.js +1 -1
- package/dist/web-ui/public/sse-shared-worker.js +1 -1
- package/dist/web-ui/public/styles.css +10 -2
- package/dist/web-ui/public/task-judging-helpers.js +1 -1
- package/dist/web-ui/public/task.js +1 -1
- package/dist/web-ui/public/teams.html +2 -2
- package/dist/web-ui/public/teams.js +1 -1
- package/dist/web-ui/public/terminal.js +1 -1
- package/dist/web-ui/public/theme.js +1 -1
- package/dist/web-ui/public/users.html +2 -2
- package/dist/web-ui/public/users.js +1 -1
- package/dist/web-ui/public/variant-grouping.js +1 -1
- package/package.json +1 -1
- package/dist/web-ui/public/server-health.js +0 -1
|
@@ -95,11 +95,11 @@
|
|
|
95
95
|
</svg>
|
|
96
96
|
<span class="option-text">Server Settings</span>
|
|
97
97
|
</button>
|
|
98
|
-
<button type="button" class="dropdown-item admin-menu-item"
|
|
98
|
+
<button type="button" class="dropdown-item admin-menu-item" onclick="window.location.href='admin.html'">
|
|
99
99
|
<svg class="option-icon icon-health" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
100
100
|
<path d="M22 12h-4l-3 9L9 3l-3 9H2"></path>
|
|
101
101
|
</svg>
|
|
102
|
-
<span class="option-text">Server
|
|
102
|
+
<span class="option-text">Server Administration</span>
|
|
103
103
|
</button>
|
|
104
104
|
<button type="button" class="dropdown-item admin-menu-item" onclick="window.location.href='git-history.html'">
|
|
105
105
|
<svg class="option-icon icon-git-history" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{API,Utils,initializeAdminMenu}from'./app.js';import{initTheme,mountThemeToggle}from'./theme.js';const state={'teams':[],'users':[],'roles':[],'environments':[],'teamBindings':[],'currentUser':null,'editingTeamId':null,'bindingsTeamId':null,'deletingTeamId':null,'modalSnapshot':null};document['addEventListener']('DOMContentLoaded',async()=>{initTheme(),mountThemeToggle();try{state['currentUser']=await API['getCurrentUser']();}catch{window['location']['href']='login.html';return;}await initializeAdminMenu(state['currentUser']);const _0x2b3968=state['currentUser'];if(!Permissions['hasServerPermission'](_0x2b3968,'teams:view')&&!Permissions['hasTeamPermission'](_0x2b3968,'teams:manage')){Utils['showToast']('Access\x20denied:\x20You\x20do\x20not\x20have\x20permission\x20to\x20view\x20teams','error'),setTimeout(()=>{window['location']['href']='index.html';},0x7d0);return;}(Permissions['hasServerPermission'](_0x2b3968,'*')||Permissions['hasTeamPermission'](_0x2b3968,'teams:manage'))&&(document['getElementById']('create-team-btn')['hidden']=![]),bindEventListeners(),await Promise['all']([loadTeams(),loadUsers(),loadRoles(),loadEnvironments()]),renderTeams();});async function loadTeams(){const _0x237645=document['getElementById']('teams-loading'),_0x3f1e3e=document['getElementById']('teams-error'),_0x4960e1=document['getElementById']('teams-content');try{_0x237645['hidden']=![],_0x3f1e3e['hidden']=!![],_0x4960e1['hidden']=!![];const {teams:_0xf178b7}=await API['getTeams']();state['teams']=_0xf178b7||[],renderTeams(),_0x237645['hidden']=!![],_0x4960e1['hidden']=![];}catch(_0x4e598a){_0x237645['hidden']=!![],_0x3f1e3e['hidden']=![],document['getElementById']('teams-error-message')['textContent']=_0x4e598a['message'];}}async function loadUsers(){try{const {users:_0x3c13d8}=await API['getUsers']();state['users']=_0x3c13d8||[];}catch{state['users']=[];}}async function loadRoles(){try{const {roles:_0xd73f2}=await API['getRoleDefinitions']();state['roles']=_0xd73f2||[];}catch{state['roles']=[];}}async function loadEnvironments(){try{const _0x3b3e29=await API['getEnvironments']();state['environments']=_0x3b3e29['environments']||[];}catch{state['environments']=[];}}function renderTeams(){const _0x1fc47c=document['getElementById']('teams-table-body'),_0x2e0b83=document['getElementById']('team-count');if(!_0x1fc47c)return;_0x2e0b83&&(_0x2e0b83['textContent']=state['teams']['length']+'\x20team'+(state['teams']['length']===0x1?'':'s'));if(state['teams']['length']===0x0){_0x1fc47c['innerHTML']='\x0a\x20\x20\x20\x20\x20\x20<tr>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<td\x20colspan=\x223\x22\x20style=\x22text-align:\x20center;\x20color:\x20var(--color-text-secondary);\x20padding:\x202rem;\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20No\x20teams\x20yet.\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20'+(Permissions['hasServerPermission'](state['currentUser'],'*')||Permissions['hasTeamPermission'](state['currentUser'],'teams:manage')?'Click\x20<strong>Create\x20Team</strong>\x20to\x20get\x20started.':'')+'\x0a\x20\x20\x20\x20\x20\x20\x20\x20</td>\x0a\x20\x20\x20\x20\x20\x20</tr>';return;}const _0x1f4a1e=Permissions['hasServerPermission'](state['currentUser'],'*');_0x1fc47c['innerHTML']=state['teams']['map'](_0x306eb4=>{const _0x203593=_0x1f4a1e||_0x306eb4['canManageTeam'],_0x36229d=_0x1f4a1e||_0x306eb4['canManageMembers'],_0x469659=_0x203593||_0x36229d,_0x528cf6=(_0x306eb4['members']||[])['length'];return'\x0a\x20\x20\x20\x20\x20\x20<tr>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<td>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<span\x20style=\x22font-weight:\x20600;\x22>'+Utils['escapeHtml'](_0x306eb4['name'])+'</span>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20'+(_0x306eb4['description']?'<div\x20style=\x22font-size:\x200.8em;\x20color:\x20var(--color-text-secondary);\x20margin-top:\x200.15rem;\x22>'+Utils['escapeHtml'](_0x306eb4['description'])+'</div>':'')+'\x0a\x20\x20\x20\x20\x20\x20\x20\x20</td>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<td>'+_0x528cf6+'</td>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<td>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<div\x20class=\x22user-actions\x22\x20style=\x22display:\x20flex;\x20gap:\x200.25rem;\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20'+(_0x469659?'<button\x20class=\x22btn-icon\x22\x20title=\x22Edit\x20team\x22\x20onclick=\x22window.openTeamModal(\x27'+_0x306eb4['id']+'\x27)\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<svg\x20width=\x2216\x22\x20height=\x2216\x22\x20viewBox=\x220\x200\x2024\x2024\x22\x20fill=\x22none\x22\x20stroke=\x22currentColor\x22\x20stroke-width=\x222\x22\x20stroke-linecap=\x22round\x22\x20stroke-linejoin=\x22round\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<path\x20d=\x22M11\x204H4a2\x202\x200\x200\x200-2\x202v14a2\x202\x200\x200\x200\x202\x202h14a2\x202\x200\x200\x200\x202-2v-7\x22></path>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<path\x20d=\x22M18.5\x202.5a2.121\x202.121\x200\x200\x201\x203\x203L12\x2015l-4\x201\x201-4\x209.5-9.5z\x22></path>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</svg>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</button>':'')+'\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20'+(_0x203593?'<button\x20class=\x22btn-icon\x22\x20title=\x22Access\x20bindings\x22\x20onclick=\x22window.openBindingsModal(\x27'+_0x306eb4['id']+'\x27)\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<svg\x20width=\x2216\x22\x20height=\x2216\x22\x20viewBox=\x220\x200\x2024\x2024\x22\x20fill=\x22none\x22\x20stroke=\x22currentColor\x22\x20stroke-width=\x222\x22\x20stroke-linecap=\x22round\x22\x20stroke-linejoin=\x22round\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<path\x20d=\x22M12\x2022s8-4\x208-10V5l-8-3-8\x203v7c0\x206\x208\x2010\x208\x2010z\x22></path>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</svg>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</button>':'')+'\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20'+(_0x203593?'<button\x20class=\x22btn-icon\x20btn-danger\x22\x20title=\x22Delete\x20team\x22\x20onclick=\x22window.deleteTeam(\x27'+_0x306eb4['id']+'\x27)\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<svg\x20width=\x2216\x22\x20height=\x2216\x22\x20viewBox=\x220\x200\x2024\x2024\x22\x20fill=\x22none\x22\x20stroke=\x22currentColor\x22\x20stroke-width=\x222\x22\x20stroke-linecap=\x22round\x22\x20stroke-linejoin=\x22round\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<polyline\x20points=\x223\x206\x205\x206\x2021\x206\x22></polyline>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<path\x20d=\x22M19\x206v14a2\x202\x200\x200\x201-2\x202H7a2\x202\x200\x200\x201-2-2V6m3\x200V4a2\x202\x200\x200\x201\x202-2h4a2\x202\x200\x200\x201\x202\x202v2\x22></path>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</svg>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</button>':'')+'\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20\x20\x20</td>\x0a\x20\x20\x20\x20\x20\x20</tr>';})['join']('');}function bindEventListeners(){document['getElementById']('create-team-btn')?.['addEventListener']('click',showCreateTeamModal),document['getElementById']('retry-teams-btn')?.['addEventListener']('click',loadTeams),document['getElementById']('close-team-modal')?.['addEventListener']('click',requestHideTeamModal),document['getElementById']('cancel-team')?.['addEventListener']('click',requestHideTeamModal),document['getElementById']('save-team')?.['addEventListener']('click',saveTeam),document['querySelector']('#team-modal\x20.modal-overlay')?.['addEventListener']('click',requestHideTeamModal),document['getElementById']('add-member-btn')?.['addEventListener']('click',addMember),document['getElementById']('close-bindings-modal')?.['addEventListener']('click',hideBindingsModal),document['querySelector']('#bindings-modal\x20.modal-overlay')?.['addEventListener']('click',hideBindingsModal),document['getElementById']('add-binding-btn')?.['addEventListener']('click',()=>{document['getElementById']('add-binding-form')['hidden']=![],document['getElementById']('add-binding-btn')['hidden']=!![],populateBindingForm();}),document['getElementById']('cancel-binding-btn')?.['addEventListener']('click',()=>{document['getElementById']('add-binding-form')['hidden']=!![],document['getElementById']('add-binding-btn')['hidden']=![];}),document['getElementById']('save-binding-btn')?.['addEventListener']('click',saveBinding),document['getElementById']('binding-resource-type')?.['addEventListener']('change',onBindingResourceTypeChange),document['getElementById']('close-delete-team-modal')?.['addEventListener']('click',hideDeleteModal),document['getElementById']('cancel-delete-team')?.['addEventListener']('click',hideDeleteModal),document['getElementById']('confirm-delete-team')?.['addEventListener']('click',confirmDeleteTeam),document['querySelector']('#delete-team-modal\x20.modal-overlay')?.['addEventListener']('click',hideDeleteModal);}function showCreateTeamModal(){state['editingTeamId']=null,state['modalSnapshot']={'name':'','description':''},document['getElementById']('team-modal-title')['textContent']='Create\x20Team',document['getElementById']('team-name')['value']='',document['getElementById']('team-name')['disabled']=![],document['getElementById']('team-description')['value']='',document['getElementById']('team-description')['disabled']=![],document['getElementById']('team-form-error')['hidden']=!![],document['getElementById']('members-section')['hidden']=!![],document['getElementById']('save-team')['hidden']=![],document['getElementById']('team-modal-footer')['hidden']=![],document['getElementById']('team-modal')['hidden']=![],setTimeout(()=>document['getElementById']('team-name')['focus'](),0x64);}window['openTeamModal']=function(_0x594cef){const _0x5ba752=state['teams']['find'](_0x483015=>_0x483015['id']===_0x594cef);if(!_0x5ba752)return;state['editingTeamId']=_0x594cef;const _0x1792a4=Permissions['hasServerPermission'](state['currentUser'],'*'),_0x442217=_0x1792a4||_0x5ba752['canManageTeam'],_0xc5eb54=_0x1792a4||_0x5ba752['canManageMembers'],_0x1055d4=_0x442217,_0x3ee43e=_0x442217||_0xc5eb54,_0x27d4b3=_0x5ba752['name'],_0xa0f6bd=_0x5ba752['description']||'';state['modalSnapshot']={'name':_0x27d4b3,'description':_0xa0f6bd},document['getElementById']('team-modal-title')['textContent']=_0x27d4b3,document['getElementById']('team-name')['value']=_0x27d4b3,document['getElementById']('team-name')['disabled']=!_0x1055d4,document['getElementById']('team-description')['value']=_0xa0f6bd,document['getElementById']('team-description')['disabled']=!_0x1055d4,document['getElementById']('team-form-error')['hidden']=!![],document['getElementById']('members-section')['hidden']=![],document['getElementById']('save-team')['hidden']=!_0x1055d4,renderMembersList(_0x5ba752),updateMemberSelect(_0x5ba752),document['getElementById']('team-modal')['hidden']=![];};function isTeamModalDirty(){if(!state['modalSnapshot'])return![];const _0x47c9a2=document['getElementById']('team-name')['value']['trim'](),_0x41a473=document['getElementById']('team-description')['value']['trim']();return _0x47c9a2!==state['modalSnapshot']['name']||_0x41a473!==state['modalSnapshot']['description'];}function requestHideTeamModal(){if(isTeamModalDirty()){if(!confirm('You\x20have\x20unsaved\x20changes.\x20Discard\x20them?'))return;}hideTeamModal();}function hideTeamModal(){document['getElementById']('team-modal')['hidden']=!![],document['getElementById']('team-name')['disabled']=![],document['getElementById']('team-description')['disabled']=![],state['editingTeamId']=null,state['modalSnapshot']=null;}window['openBindingsModal']=function(_0x289b87){const _0x4319b1=state['teams']['find'](_0x11dd91=>_0x11dd91['id']===_0x289b87);if(!_0x4319b1)return;state['bindingsTeamId']=_0x289b87,document['getElementById']('bindings-modal-title')['textContent']='Access\x20Bindings\x20—\x20'+_0x4319b1['name'],document['getElementById']('add-binding-form')['hidden']=!![],document['getElementById']('bindings-modal')['hidden']=![],loadTeamBindings(_0x289b87);};function hideBindingsModal(){document['getElementById']('bindings-modal')['hidden']=!![],state['bindingsTeamId']=null;}function renderMembersList(_0x2e44e0){const _0x25244c=Permissions['hasServerPermission'](state['currentUser'],'*'),_0xf4db39=_0x25244c||_0x2e44e0['canManageMembers']||_0x2e44e0['canManageTeam'],_0x59f6fe=_0x2e44e0['members']||[],_0x42397b=document['getElementById']('members-list');if(_0x59f6fe['length']===0x0){_0x42397b['innerHTML']='<p\x20style=\x22font-size:\x200.875rem;\x20color:\x20var(--color-text-secondary);\x20margin:\x200.25rem\x200;\x22>No\x20members\x20yet</p>';return;}_0x42397b['innerHTML']=_0x59f6fe['map'](_0x25d04c=>{const _0x690ca0=state['users']['find'](_0x2caf53=>_0x2caf53['id']===_0x25d04c),_0xf9bf7=_0x690ca0?''+Utils['escapeHtml'](_0x690ca0['username'])+(_0x690ca0['name']?'\x20<span\x20style=\x22color:\x20var(--color-text-secondary);\x20font-size:\x200.85em;\x22>('+Utils['escapeHtml'](_0x690ca0['name'])+')</span>':''):Utils['escapeHtml'](_0x25d04c);return'\x0a\x20\x20\x20\x20\x20\x20<div\x20style=\x22display:\x20flex;\x20align-items:\x20center;\x20justify-content:\x20space-between;\x20padding:\x200.35rem\x200;\x20border-bottom:\x201px\x20solid\x20var(--color-border);\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<span\x20style=\x22font-size:\x200.875rem;\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20'+_0xf9bf7+'\x0a\x20\x20\x20\x20\x20\x20\x20\x20</span>\x0a\x20\x20\x20\x20\x20\x20\x20\x20'+(_0xf4db39?'<button\x20type=\x22button\x22\x20class=\x22btn-ghost\x20btn-small\x22\x20onclick=\x22window.removeMemberClick(\x27'+_0x25d04c+'\x27)\x22\x20style=\x22color:\x20var(--color-danger);\x20padding:\x200.15rem\x200.4rem;\x20font-size:\x200.8rem;\x22>Remove</button>':'')+'\x0a\x20\x20\x20\x20\x20\x20</div>';})['join']('');const _0x5115c1=document['getElementById']('add-member-row');if(_0x5115c1)_0x5115c1['style']['display']=_0xf4db39?'flex':'none';}function updateMemberSelect(_0x2dec5a){const _0x521c32=document['getElementById']('add-member-select');if(!_0x521c32)return;const _0x5b7e27=new Set(_0x2dec5a['members']||[]),_0x411583=state['users']['filter'](_0x3d2ea0=>!_0x5b7e27['has'](_0x3d2ea0['id']));_0x521c32['innerHTML']='<option\x20value=\x22\x22>Add\x20a\x20member…</option>'+_0x411583['map'](_0x27195a=>'<option\x20value=\x22'+_0x27195a['id']+'\x22>'+Utils['escapeHtml'](_0x27195a['username'])+(_0x27195a['name']?'\x20('+Utils['escapeHtml'](_0x27195a['name'])+')':'')+'</option>')['join']('');}async function addMember(){const _0x3171c0=document['getElementById']('add-member-select'),_0x4e558d=_0x3171c0['value'];if(!_0x4e558d||!state['editingTeamId'])return;try{const {team:_0x63463f}=await API['addTeamMember'](state['editingTeamId'],_0x4e558d);syncTeamInState(_0x63463f),renderMembersList(_0x63463f),updateMemberSelect(_0x63463f),_0x3171c0['value']='',Utils['showToast']('Member\x20added','success');}catch(_0x4dc70e){Utils['showToast'](_0x4dc70e['message'],'error');}}window['removeMemberClick']=async function(_0x2b408b){if(!state['editingTeamId'])return;try{const {team:_0x18068d}=await API['removeTeamMember'](state['editingTeamId'],_0x2b408b);syncTeamInState(_0x18068d),renderMembersList(_0x18068d),updateMemberSelect(_0x18068d),Utils['showToast']('Member\x20removed','success');}catch(_0x4a8422){Utils['showToast'](_0x4a8422['message'],'error');}};async function loadTeamBindings(_0xfd50cb){const _0xaf34b=document['getElementById']('bindings-loading'),_0x5863ac=document['getElementById']('bindings-empty'),_0x99819b=document['getElementById']('bindings-list-container'),_0xc23a9a=document['getElementById']('add-binding-btn');_0xaf34b['hidden']=![],_0x5863ac['hidden']=!![],_0x99819b['style']['display']='none',_0xc23a9a['hidden']=!![],document['getElementById']('add-binding-form')['hidden']=!![];try{const {bindings:_0x5d3cd5}=await API['getBindings']({'subject_type':'team','subject_id':_0xfd50cb});state['teamBindings']=_0x5d3cd5||[],_0xaf34b['hidden']=!![],state['teamBindings']['length']===0x0?_0x5863ac['hidden']=![]:(_0x99819b['style']['display']='',renderBindingsTable()),(Permissions['hasServerPermission'](state['currentUser'],'*')||Permissions['hasTeamPermission'](state['currentUser'],'teams:manage'))&&(_0xc23a9a['hidden']=![]);}catch(_0x229d91){_0xaf34b['hidden']=!![],Utils['showToast']('Failed\x20to\x20load\x20bindings:\x20'+_0x229d91['message'],'error');}}function renderBindingsTable(){const _0x32d9e5=document['getElementById']('bindings-table-body');if(!_0x32d9e5)return;const _0x195bf5=Permissions['hasServerPermission'](state['currentUser'],'*')||Permissions['hasTeamPermission'](state['currentUser'],'teams:manage');_0x32d9e5['innerHTML']=state['teamBindings']['map'](_0x3533cc=>{const _0x760546=_0x3533cc['resource_type']==='server'?'Server':_0x3533cc['resource_id']==='*'?'All\x20'+_0x3533cc['resource_type']+'s':Utils['escapeHtml'](_0x3533cc['resource_name']||_0x3533cc['resource_id']||'');return'\x0a\x20\x20\x20\x20<tr>\x0a\x20\x20\x20\x20\x20\x20<td>'+_0x760546+'</td>\x0a\x20\x20\x20\x20\x20\x20<td>'+Utils['escapeHtml'](_0x3533cc['role_name']||_0x3533cc['role_id'])+'</td>\x0a\x20\x20\x20\x20\x20\x20<td>\x0a\x20\x20\x20\x20\x20\x20\x20\x20'+(_0x195bf5?'<button\x20class=\x22btn-ghost\x20btn-small\x22\x20onclick=\x22window.deleteBindingClick(\x27'+_0x3533cc['id']+'\x27)\x22\x20style=\x22color:\x20var(--color-danger);\x22>Remove</button>':'—')+'\x0a\x20\x20\x20\x20\x20\x20</td>\x0a\x20\x20\x20\x20</tr>';})['join']('');}function populateBindingForm(){const _0x1ad785=document['getElementById']('binding-resource-type');_0x1ad785['value']='environment',updateBindingFormForResourceType('environment');}function onBindingResourceTypeChange(){const _0x4dcf28=document['getElementById']('binding-resource-type')['value'];updateBindingFormForResourceType(_0x4dcf28);}function updateBindingFormForResourceType(_0x39b1e3){const _0xa7c268=document['getElementById']('binding-resource-container'),_0x5c01c7=document['getElementById']('binding-resource'),_0x17760b=document['getElementById']('binding-role');if(_0x39b1e3==='server')_0xa7c268['style']['display']='none';else{_0xa7c268['style']['display']='';if(_0x39b1e3==='environment'){const _0x1ccba9=new Set(state['teamBindings']['filter'](_0x110f4c=>_0x110f4c['resource_type']==='environment')['map'](_0x37c498=>_0x37c498['resource_id'])),_0x2fcabe=state['environments']['filter'](_0x370891=>!_0x1ccba9['has'](_0x370891['name']));_0x5c01c7['innerHTML']=_0x2fcabe['length']?_0x2fcabe['map'](_0x44f06e=>'<option\x20value=\x22'+Utils['escapeHtml'](_0x44f06e['name'])+'\x22>'+Utils['escapeHtml'](_0x44f06e['name'])+'</option>')['join'](''):'<option\x20value=\x22\x22>All\x20environments\x20already\x20bound</option>';}else{if(_0x39b1e3==='team'){const _0x2404b4=new Set(state['teamBindings']['filter'](_0x2327be=>_0x2327be['resource_type']==='team')['map'](_0x6ea127=>_0x6ea127['resource_id'])),_0x141d2e=state['teams']['filter'](_0x5a96a5=>!_0x2404b4['has'](_0x5a96a5['id']));_0x5c01c7['innerHTML']=_0x141d2e['length']?_0x141d2e['map'](_0x198a98=>'<option\x20value=\x22'+_0x198a98['id']+'\x22>'+Utils['escapeHtml'](_0x198a98['name'])+'</option>')['join'](''):'<option\x20value=\x22\x22>All\x20teams\x20already\x20bound</option>';}}}const _0x293b2a=state['roles']['filter'](_0x54066d=>_0x54066d['resource_type']===_0x39b1e3);_0x17760b['innerHTML']=_0x293b2a['length']?_0x293b2a['filter'](_0x3e7f68=>{const _0x4e8b57=_0x39b1e3==='server'?undefined:_0x5c01c7['value'];return!state['teamBindings']['some'](_0x546924=>_0x546924['resource_type']===_0x39b1e3&&_0x546924['role_id']===_0x3e7f68['id']&&(_0x39b1e3==='server'||_0x546924['resource_id']===_0x4e8b57));})['map'](_0x4c7a94=>'<option\x20value=\x22'+_0x4c7a94['id']+'\x22>'+Utils['escapeHtml'](_0x4c7a94['name'])+'</option>')['join']('')||'<option\x20value=\x22\x22>No\x20available\x20roles</option>':'<option\x20value=\x22\x22>No\x20roles\x20for\x20this\x20resource\x20type</option>';}async function saveBinding(){const _0x29b354=document['getElementById']('binding-resource-type')['value'],_0x1f5932=document['getElementById']('binding-role')['value'];if(!_0x1f5932||!state['bindingsTeamId'])return;const _0x46e55e=_0x29b354==='server'?undefined:document['getElementById']('binding-resource')['value'];if(_0x29b354!=='server'&&!_0x46e55e)return;const _0x138596=document['getElementById']('save-binding-btn');_0x138596['disabled']=!![],_0x138596['textContent']='Adding…';try{const _0x55ac95={'subject_type':'team','subject_id':state['bindingsTeamId'],'role_id':_0x1f5932,'resource_type':_0x29b354};if(_0x46e55e)_0x55ac95['resource_id']=_0x46e55e;await API['createBinding'](_0x55ac95),Utils['showToast']('Binding\x20added','success'),document['getElementById']('add-binding-form')['hidden']=!![],document['getElementById']('add-binding-btn')['hidden']=![],await loadTeamBindings(state['bindingsTeamId']);}catch(_0x4e95af){Utils['showToast'](_0x4e95af['message'],'error');}finally{_0x138596['disabled']=![],_0x138596['textContent']='Add\x20Binding';}}window['deleteBindingClick']=async function(_0x21b4b3){try{await API['deleteBinding'](_0x21b4b3),Utils['showToast']('Binding\x20removed','success'),await loadTeamBindings(state['bindingsTeamId']);}catch(_0x24a9ed){Utils['showToast'](_0x24a9ed['message'],'error');}};async function saveTeam(){const _0x157837=document['getElementById']('team-name')['value']['trim'](),_0x26d6e5=document['getElementById']('team-description')['value']['trim'](),_0x1e1b82=document['getElementById']('team-form-error'),_0xb1d16=document['getElementById']('save-team');if(!_0x157837){_0x1e1b82['textContent']='Team\x20name\x20is\x20required',_0x1e1b82['hidden']=![];return;}_0x1e1b82['hidden']=!![];const _0x599f07=_0xb1d16['textContent'];_0xb1d16['disabled']=!![],_0xb1d16['textContent']=state['editingTeamId']?'Saving…':'Creating…';try{if(state['editingTeamId']){const {team:_0x3ee370}=await API['updateTeam'](state['editingTeamId'],{'name':_0x157837,'description':_0x26d6e5});syncTeamInState(_0x3ee370),document['getElementById']('team-modal-title')['textContent']=_0x3ee370['name'],Utils['showToast']('Team\x20updated','success');}else await API['createTeam']({'name':_0x157837,'description':_0x26d6e5}),Utils['showToast']('Team\x20created','success');_0xb1d16['disabled']=![],_0xb1d16['textContent']=_0x599f07,hideTeamModal(),await loadTeams();}catch(_0x3cb739){_0x1e1b82['textContent']=_0x3cb739['message'],_0x1e1b82['hidden']=![],_0xb1d16['disabled']=![],_0xb1d16['textContent']=_0x599f07;}}window['deleteTeam']=function(_0x14a617){const _0x405ff2=state['teams']['find'](_0x219338=>_0x219338['id']===_0x14a617);if(!_0x405ff2)return;state['deletingTeamId']=_0x14a617,document['getElementById']('delete-team-name')['textContent']=_0x405ff2['name'],document['getElementById']('delete-team-modal')['hidden']=![];};function hideDeleteModal(){document['getElementById']('delete-team-modal')['hidden']=!![],state['deletingTeamId']=null;}async function confirmDeleteTeam(){if(!state['deletingTeamId'])return;const _0x3fc675=document['getElementById']('confirm-delete-team');_0x3fc675['disabled']=!![],_0x3fc675['textContent']='Deleting…';try{await API['deleteTeam'](state['deletingTeamId']),Utils['showToast']('Team\x20deleted','success'),_0x3fc675['disabled']=![],_0x3fc675['textContent']='Delete\x20Team',hideDeleteModal(),await loadTeams();}catch(_0x5dfc80){Utils['showToast']('Failed\x20to\x20delete\x20team:\x20'+_0x5dfc80['message'],'error'),_0x3fc675['disabled']=![],_0x3fc675['textContent']='Delete\x20Team';}}function syncTeamInState(_0x41fb9c){const _0x58299e=state['teams']['findIndex'](_0x184466=>_0x184466['id']===_0x41fb9c['id']);if(_0x58299e>=0x0)state['teams'][_0x58299e]=_0x41fb9c;renderTeams();}
|
|
1
|
+
import{API,Utils,initializeAdminMenu}from'./app.js';import{initTheme,mountThemeToggle}from'./theme.js';const state={'teams':[],'users':[],'roles':[],'environments':[],'teamBindings':[],'currentUser':null,'editingTeamId':null,'bindingsTeamId':null,'deletingTeamId':null,'modalSnapshot':null};document['addEventListener']('DOMContentLoaded',async()=>{initTheme(),mountThemeToggle();try{state['currentUser']=await API['getCurrentUser']();}catch{window['location']['href']='login.html';return;}await initializeAdminMenu(state['currentUser']);const _0x172748=state['currentUser'];if(!Permissions['hasServerPermission'](_0x172748,'teams:view')&&!Permissions['hasTeamPermission'](_0x172748,'teams:manage')){Utils['showToast']('Access\x20denied:\x20You\x20do\x20not\x20have\x20permission\x20to\x20view\x20teams','error'),setTimeout(()=>{window['location']['href']='index.html';},0x7d0);return;}(Permissions['hasServerPermission'](_0x172748,'*')||Permissions['hasTeamPermission'](_0x172748,'teams:manage'))&&(document['getElementById']('create-team-btn')['hidden']=![]),bindEventListeners(),await Promise['all']([loadTeams(),loadUsers(),loadRoles(),loadEnvironments()]),renderTeams();});async function loadTeams(){const _0x2c9448=document['getElementById']('teams-loading'),_0x6d72d7=document['getElementById']('teams-error'),_0x26bed3=document['getElementById']('teams-content');try{_0x2c9448['hidden']=![],_0x6d72d7['hidden']=!![],_0x26bed3['hidden']=!![];const {teams:_0x4bd078}=await API['getTeams']();state['teams']=_0x4bd078||[],renderTeams(),_0x2c9448['hidden']=!![],_0x26bed3['hidden']=![];}catch(_0x9b46b7){_0x2c9448['hidden']=!![],_0x6d72d7['hidden']=![],document['getElementById']('teams-error-message')['textContent']=_0x9b46b7['message'];}}async function loadUsers(){try{const {users:_0x5e3c4a}=await API['getUsers']();state['users']=_0x5e3c4a||[];}catch{state['users']=[];}}async function loadRoles(){try{const {roles:_0x18dc49}=await API['getRoleDefinitions']();state['roles']=_0x18dc49||[];}catch{state['roles']=[];}}async function loadEnvironments(){try{const _0x1c5aa2=await API['getEnvironments']();state['environments']=_0x1c5aa2['environments']||[];}catch{state['environments']=[];}}function renderTeams(){const _0x32811f=document['getElementById']('teams-table-body'),_0x3cf92c=document['getElementById']('team-count');if(!_0x32811f)return;_0x3cf92c&&(_0x3cf92c['textContent']=state['teams']['length']+'\x20team'+(state['teams']['length']===0x1?'':'s'));if(state['teams']['length']===0x0){_0x32811f['innerHTML']='\x0a\x20\x20\x20\x20\x20\x20<tr>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<td\x20colspan=\x223\x22\x20style=\x22text-align:\x20center;\x20color:\x20var(--color-text-secondary);\x20padding:\x202rem;\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20No\x20teams\x20yet.\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20'+(Permissions['hasServerPermission'](state['currentUser'],'*')||Permissions['hasTeamPermission'](state['currentUser'],'teams:manage')?'Click\x20<strong>Create\x20Team</strong>\x20to\x20get\x20started.':'')+'\x0a\x20\x20\x20\x20\x20\x20\x20\x20</td>\x0a\x20\x20\x20\x20\x20\x20</tr>';return;}const _0x58accc=Permissions['hasServerPermission'](state['currentUser'],'*');_0x32811f['innerHTML']=state['teams']['map'](_0x5b96ea=>{const _0x136350=_0x58accc||_0x5b96ea['canManageTeam'],_0x93bf9=_0x58accc||_0x5b96ea['canManageMembers'],_0x497e16=_0x136350||_0x93bf9,_0x12b79e=(_0x5b96ea['members']||[])['length'];return'\x0a\x20\x20\x20\x20\x20\x20<tr>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<td>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<span\x20style=\x22font-weight:\x20600;\x22>'+Utils['escapeHtml'](_0x5b96ea['name'])+'</span>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20'+(_0x5b96ea['description']?'<div\x20style=\x22font-size:\x200.8em;\x20color:\x20var(--color-text-secondary);\x20margin-top:\x200.15rem;\x22>'+Utils['escapeHtml'](_0x5b96ea['description'])+'</div>':'')+'\x0a\x20\x20\x20\x20\x20\x20\x20\x20</td>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<td>'+_0x12b79e+'</td>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<td>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<div\x20class=\x22user-actions\x22\x20style=\x22display:\x20flex;\x20gap:\x200.25rem;\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20'+(_0x497e16?'<button\x20class=\x22btn-icon\x22\x20title=\x22Edit\x20team\x22\x20onclick=\x22window.openTeamModal(\x27'+_0x5b96ea['id']+'\x27)\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<svg\x20width=\x2216\x22\x20height=\x2216\x22\x20viewBox=\x220\x200\x2024\x2024\x22\x20fill=\x22none\x22\x20stroke=\x22currentColor\x22\x20stroke-width=\x222\x22\x20stroke-linecap=\x22round\x22\x20stroke-linejoin=\x22round\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<path\x20d=\x22M11\x204H4a2\x202\x200\x200\x200-2\x202v14a2\x202\x200\x200\x200\x202\x202h14a2\x202\x200\x200\x200\x202-2v-7\x22></path>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<path\x20d=\x22M18.5\x202.5a2.121\x202.121\x200\x200\x201\x203\x203L12\x2015l-4\x201\x201-4\x209.5-9.5z\x22></path>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</svg>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</button>':'')+'\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20'+(_0x136350?'<button\x20class=\x22btn-icon\x22\x20title=\x22Access\x20bindings\x22\x20onclick=\x22window.openBindingsModal(\x27'+_0x5b96ea['id']+'\x27)\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<svg\x20width=\x2216\x22\x20height=\x2216\x22\x20viewBox=\x220\x200\x2024\x2024\x22\x20fill=\x22none\x22\x20stroke=\x22currentColor\x22\x20stroke-width=\x222\x22\x20stroke-linecap=\x22round\x22\x20stroke-linejoin=\x22round\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<path\x20d=\x22M12\x2022s8-4\x208-10V5l-8-3-8\x203v7c0\x206\x208\x2010\x208\x2010z\x22></path>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</svg>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</button>':'')+'\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20'+(_0x136350?'<button\x20class=\x22btn-icon\x20btn-danger\x22\x20title=\x22Delete\x20team\x22\x20onclick=\x22window.deleteTeam(\x27'+_0x5b96ea['id']+'\x27)\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<svg\x20width=\x2216\x22\x20height=\x2216\x22\x20viewBox=\x220\x200\x2024\x2024\x22\x20fill=\x22none\x22\x20stroke=\x22currentColor\x22\x20stroke-width=\x222\x22\x20stroke-linecap=\x22round\x22\x20stroke-linejoin=\x22round\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<polyline\x20points=\x223\x206\x205\x206\x2021\x206\x22></polyline>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<path\x20d=\x22M19\x206v14a2\x202\x200\x200\x201-2\x202H7a2\x202\x200\x200\x201-2-2V6m3\x200V4a2\x202\x200\x200\x201\x202-2h4a2\x202\x200\x200\x201\x202\x202v2\x22></path>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</svg>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</button>':'')+'\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20\x20\x20</td>\x0a\x20\x20\x20\x20\x20\x20</tr>';})['join']('');}function bindEventListeners(){document['getElementById']('create-team-btn')?.['addEventListener']('click',showCreateTeamModal),document['getElementById']('retry-teams-btn')?.['addEventListener']('click',loadTeams),document['getElementById']('close-team-modal')?.['addEventListener']('click',requestHideTeamModal),document['getElementById']('cancel-team')?.['addEventListener']('click',requestHideTeamModal),document['getElementById']('save-team')?.['addEventListener']('click',saveTeam),document['querySelector']('#team-modal\x20.modal-overlay')?.['addEventListener']('click',requestHideTeamModal),document['getElementById']('add-member-btn')?.['addEventListener']('click',addMember),document['getElementById']('close-bindings-modal')?.['addEventListener']('click',hideBindingsModal),document['querySelector']('#bindings-modal\x20.modal-overlay')?.['addEventListener']('click',hideBindingsModal),document['getElementById']('add-binding-btn')?.['addEventListener']('click',()=>{document['getElementById']('add-binding-form')['hidden']=![],document['getElementById']('add-binding-btn')['hidden']=!![],populateBindingForm();}),document['getElementById']('cancel-binding-btn')?.['addEventListener']('click',()=>{document['getElementById']('add-binding-form')['hidden']=!![],document['getElementById']('add-binding-btn')['hidden']=![];}),document['getElementById']('save-binding-btn')?.['addEventListener']('click',saveBinding),document['getElementById']('binding-resource-type')?.['addEventListener']('change',onBindingResourceTypeChange),document['getElementById']('close-delete-team-modal')?.['addEventListener']('click',hideDeleteModal),document['getElementById']('cancel-delete-team')?.['addEventListener']('click',hideDeleteModal),document['getElementById']('confirm-delete-team')?.['addEventListener']('click',confirmDeleteTeam),document['querySelector']('#delete-team-modal\x20.modal-overlay')?.['addEventListener']('click',hideDeleteModal);}function showCreateTeamModal(){state['editingTeamId']=null,state['modalSnapshot']={'name':'','description':''},document['getElementById']('team-modal-title')['textContent']='Create\x20Team',document['getElementById']('team-name')['value']='',document['getElementById']('team-name')['disabled']=![],document['getElementById']('team-description')['value']='',document['getElementById']('team-description')['disabled']=![],document['getElementById']('team-form-error')['hidden']=!![],document['getElementById']('members-section')['hidden']=!![],document['getElementById']('save-team')['hidden']=![],document['getElementById']('team-modal-footer')['hidden']=![],document['getElementById']('team-modal')['hidden']=![],setTimeout(()=>document['getElementById']('team-name')['focus'](),0x64);}window['openTeamModal']=function(_0x276425){const _0x26e124=state['teams']['find'](_0x2e5a40=>_0x2e5a40['id']===_0x276425);if(!_0x26e124)return;state['editingTeamId']=_0x276425;const _0x116752=Permissions['hasServerPermission'](state['currentUser'],'*'),_0x4fcf5f=_0x116752||_0x26e124['canManageTeam'],_0x5be77d=_0x116752||_0x26e124['canManageMembers'],_0xb96161=_0x4fcf5f,_0x398ecb=_0x4fcf5f||_0x5be77d,_0x25a286=_0x26e124['name'],_0x16f76c=_0x26e124['description']||'';state['modalSnapshot']={'name':_0x25a286,'description':_0x16f76c},document['getElementById']('team-modal-title')['textContent']=_0x25a286,document['getElementById']('team-name')['value']=_0x25a286,document['getElementById']('team-name')['disabled']=!_0xb96161,document['getElementById']('team-description')['value']=_0x16f76c,document['getElementById']('team-description')['disabled']=!_0xb96161,document['getElementById']('team-form-error')['hidden']=!![],document['getElementById']('members-section')['hidden']=![],document['getElementById']('save-team')['hidden']=!_0xb96161,renderMembersList(_0x26e124),updateMemberSelect(_0x26e124),document['getElementById']('team-modal')['hidden']=![];};function isTeamModalDirty(){if(!state['modalSnapshot'])return![];const _0x466dc9=document['getElementById']('team-name')['value']['trim'](),_0x1285c0=document['getElementById']('team-description')['value']['trim']();return _0x466dc9!==state['modalSnapshot']['name']||_0x1285c0!==state['modalSnapshot']['description'];}function requestHideTeamModal(){if(isTeamModalDirty()){if(!confirm('You\x20have\x20unsaved\x20changes.\x20Discard\x20them?'))return;}hideTeamModal();}function hideTeamModal(){document['getElementById']('team-modal')['hidden']=!![],document['getElementById']('team-name')['disabled']=![],document['getElementById']('team-description')['disabled']=![],state['editingTeamId']=null,state['modalSnapshot']=null;}window['openBindingsModal']=function(_0xa7d7a){const _0x350260=state['teams']['find'](_0x5d6a24=>_0x5d6a24['id']===_0xa7d7a);if(!_0x350260)return;state['bindingsTeamId']=_0xa7d7a,document['getElementById']('bindings-modal-title')['textContent']='Access\x20Bindings\x20—\x20'+_0x350260['name'],document['getElementById']('add-binding-form')['hidden']=!![],document['getElementById']('bindings-modal')['hidden']=![],loadTeamBindings(_0xa7d7a);};function hideBindingsModal(){document['getElementById']('bindings-modal')['hidden']=!![],state['bindingsTeamId']=null;}function renderMembersList(_0xa1b274){const _0x24aa31=Permissions['hasServerPermission'](state['currentUser'],'*'),_0x209747=_0x24aa31||_0xa1b274['canManageMembers']||_0xa1b274['canManageTeam'],_0x3a21a3=_0xa1b274['members']||[],_0x57b676=document['getElementById']('members-list');if(_0x3a21a3['length']===0x0){_0x57b676['innerHTML']='<p\x20style=\x22font-size:\x200.875rem;\x20color:\x20var(--color-text-secondary);\x20margin:\x200.25rem\x200;\x22>No\x20members\x20yet</p>';return;}_0x57b676['innerHTML']=_0x3a21a3['map'](_0x2e6482=>{const _0x4a98c1=state['users']['find'](_0x35aaa4=>_0x35aaa4['id']===_0x2e6482),_0x23b3b4=_0x4a98c1?''+Utils['escapeHtml'](_0x4a98c1['username'])+(_0x4a98c1['name']?'\x20<span\x20style=\x22color:\x20var(--color-text-secondary);\x20font-size:\x200.85em;\x22>('+Utils['escapeHtml'](_0x4a98c1['name'])+')</span>':''):Utils['escapeHtml'](_0x2e6482);return'\x0a\x20\x20\x20\x20\x20\x20<div\x20style=\x22display:\x20flex;\x20align-items:\x20center;\x20justify-content:\x20space-between;\x20padding:\x200.35rem\x200;\x20border-bottom:\x201px\x20solid\x20var(--color-border);\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<span\x20style=\x22font-size:\x200.875rem;\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20'+_0x23b3b4+'\x0a\x20\x20\x20\x20\x20\x20\x20\x20</span>\x0a\x20\x20\x20\x20\x20\x20\x20\x20'+(_0x209747?'<button\x20type=\x22button\x22\x20class=\x22btn-ghost\x20btn-small\x22\x20onclick=\x22window.removeMemberClick(\x27'+_0x2e6482+'\x27)\x22\x20style=\x22color:\x20var(--color-danger);\x20padding:\x200.15rem\x200.4rem;\x20font-size:\x200.8rem;\x22>Remove</button>':'')+'\x0a\x20\x20\x20\x20\x20\x20</div>';})['join']('');const _0xf84f55=document['getElementById']('add-member-row');if(_0xf84f55)_0xf84f55['style']['display']=_0x209747?'flex':'none';}function updateMemberSelect(_0x4cca33){const _0x84b371=document['getElementById']('add-member-select');if(!_0x84b371)return;const _0x2ebd18=new Set(_0x4cca33['members']||[]),_0x5ecca5=state['users']['filter'](_0x42a9d7=>!_0x2ebd18['has'](_0x42a9d7['id']));_0x84b371['innerHTML']='<option\x20value=\x22\x22>Add\x20a\x20member…</option>'+_0x5ecca5['map'](_0x47e3b1=>'<option\x20value=\x22'+_0x47e3b1['id']+'\x22>'+Utils['escapeHtml'](_0x47e3b1['username'])+(_0x47e3b1['name']?'\x20('+Utils['escapeHtml'](_0x47e3b1['name'])+')':'')+'</option>')['join']('');}async function addMember(){const _0x10c170=document['getElementById']('add-member-select'),_0xb7c5b3=_0x10c170['value'];if(!_0xb7c5b3||!state['editingTeamId'])return;try{const {team:_0x43d871}=await API['addTeamMember'](state['editingTeamId'],_0xb7c5b3);syncTeamInState(_0x43d871),renderMembersList(_0x43d871),updateMemberSelect(_0x43d871),_0x10c170['value']='',Utils['showToast']('Member\x20added','success');}catch(_0x39a95f){Utils['showToast'](_0x39a95f['message'],'error');}}window['removeMemberClick']=async function(_0x39d4b8){if(!state['editingTeamId'])return;try{const {team:_0x4c08c1}=await API['removeTeamMember'](state['editingTeamId'],_0x39d4b8);syncTeamInState(_0x4c08c1),renderMembersList(_0x4c08c1),updateMemberSelect(_0x4c08c1),Utils['showToast']('Member\x20removed','success');}catch(_0x21d99d){Utils['showToast'](_0x21d99d['message'],'error');}};async function loadTeamBindings(_0x2fb9d5){const _0x46a4d9=document['getElementById']('bindings-loading'),_0x3021b6=document['getElementById']('bindings-empty'),_0x28a6a5=document['getElementById']('bindings-list-container'),_0x2e1e70=document['getElementById']('add-binding-btn');_0x46a4d9['hidden']=![],_0x3021b6['hidden']=!![],_0x28a6a5['style']['display']='none',_0x2e1e70['hidden']=!![],document['getElementById']('add-binding-form')['hidden']=!![];try{const {bindings:_0x4013c5}=await API['getBindings']({'subject_type':'team','subject_id':_0x2fb9d5});state['teamBindings']=_0x4013c5||[],_0x46a4d9['hidden']=!![],state['teamBindings']['length']===0x0?_0x3021b6['hidden']=![]:(_0x28a6a5['style']['display']='',renderBindingsTable()),(Permissions['hasServerPermission'](state['currentUser'],'*')||Permissions['hasTeamPermission'](state['currentUser'],'teams:manage'))&&(_0x2e1e70['hidden']=![]);}catch(_0x4ef3d9){_0x46a4d9['hidden']=!![],Utils['showToast']('Failed\x20to\x20load\x20bindings:\x20'+_0x4ef3d9['message'],'error');}}function renderBindingsTable(){const _0x17ed27=document['getElementById']('bindings-table-body');if(!_0x17ed27)return;const _0x571b7a=Permissions['hasServerPermission'](state['currentUser'],'*')||Permissions['hasTeamPermission'](state['currentUser'],'teams:manage');_0x17ed27['innerHTML']=state['teamBindings']['map'](_0x88fd6c=>{const _0x5f32a4=_0x88fd6c['resource_type']==='server'?'Server':_0x88fd6c['resource_id']==='*'?'All\x20'+_0x88fd6c['resource_type']+'s':Utils['escapeHtml'](_0x88fd6c['resource_name']||_0x88fd6c['resource_id']||'');return'\x0a\x20\x20\x20\x20<tr>\x0a\x20\x20\x20\x20\x20\x20<td>'+_0x5f32a4+'</td>\x0a\x20\x20\x20\x20\x20\x20<td>'+Utils['escapeHtml'](_0x88fd6c['role_name']||_0x88fd6c['role_id'])+'</td>\x0a\x20\x20\x20\x20\x20\x20<td>\x0a\x20\x20\x20\x20\x20\x20\x20\x20'+(_0x571b7a?'<button\x20class=\x22btn-ghost\x20btn-small\x22\x20onclick=\x22window.deleteBindingClick(\x27'+_0x88fd6c['id']+'\x27)\x22\x20style=\x22color:\x20var(--color-danger);\x22>Remove</button>':'—')+'\x0a\x20\x20\x20\x20\x20\x20</td>\x0a\x20\x20\x20\x20</tr>';})['join']('');}function populateBindingForm(){const _0x228cba=document['getElementById']('binding-resource-type');_0x228cba['value']='environment',updateBindingFormForResourceType('environment');}function onBindingResourceTypeChange(){const _0x50c4ac=document['getElementById']('binding-resource-type')['value'];updateBindingFormForResourceType(_0x50c4ac);}function updateBindingFormForResourceType(_0x1058ae){const _0x124b68=document['getElementById']('binding-resource-container'),_0x11b4fe=document['getElementById']('binding-resource'),_0x283eaa=document['getElementById']('binding-role');if(_0x1058ae==='server')_0x124b68['style']['display']='none';else{_0x124b68['style']['display']='';if(_0x1058ae==='environment'){const _0x519a03=new Set(state['teamBindings']['filter'](_0x526e95=>_0x526e95['resource_type']==='environment')['map'](_0x549868=>_0x549868['resource_id'])),_0x397a47=state['environments']['filter'](_0x58b88f=>!_0x519a03['has'](_0x58b88f['name']));_0x11b4fe['innerHTML']=_0x397a47['length']?_0x397a47['map'](_0x29755f=>'<option\x20value=\x22'+Utils['escapeHtml'](_0x29755f['name'])+'\x22>'+Utils['escapeHtml'](_0x29755f['name'])+'</option>')['join'](''):'<option\x20value=\x22\x22>All\x20environments\x20already\x20bound</option>';}else{if(_0x1058ae==='team'){const _0x2b494=new Set(state['teamBindings']['filter'](_0x3ff45e=>_0x3ff45e['resource_type']==='team')['map'](_0x554112=>_0x554112['resource_id'])),_0x1644c6=state['teams']['filter'](_0x2fc87b=>!_0x2b494['has'](_0x2fc87b['id']));_0x11b4fe['innerHTML']=_0x1644c6['length']?_0x1644c6['map'](_0x53cef9=>'<option\x20value=\x22'+_0x53cef9['id']+'\x22>'+Utils['escapeHtml'](_0x53cef9['name'])+'</option>')['join'](''):'<option\x20value=\x22\x22>All\x20teams\x20already\x20bound</option>';}}}const _0x19c740=state['roles']['filter'](_0x1966a9=>_0x1966a9['resource_type']===_0x1058ae);_0x283eaa['innerHTML']=_0x19c740['length']?_0x19c740['filter'](_0x38d600=>{const _0x4bbb1c=_0x1058ae==='server'?undefined:_0x11b4fe['value'];return!state['teamBindings']['some'](_0x89cfb1=>_0x89cfb1['resource_type']===_0x1058ae&&_0x89cfb1['role_id']===_0x38d600['id']&&(_0x1058ae==='server'||_0x89cfb1['resource_id']===_0x4bbb1c));})['map'](_0x323658=>'<option\x20value=\x22'+_0x323658['id']+'\x22>'+Utils['escapeHtml'](_0x323658['name'])+'</option>')['join']('')||'<option\x20value=\x22\x22>No\x20available\x20roles</option>':'<option\x20value=\x22\x22>No\x20roles\x20for\x20this\x20resource\x20type</option>';}async function saveBinding(){const _0x557b2e=document['getElementById']('binding-resource-type')['value'],_0x2f721e=document['getElementById']('binding-role')['value'];if(!_0x2f721e||!state['bindingsTeamId'])return;const _0x3a15c7=_0x557b2e==='server'?undefined:document['getElementById']('binding-resource')['value'];if(_0x557b2e!=='server'&&!_0x3a15c7)return;const _0x22de37=document['getElementById']('save-binding-btn');_0x22de37['disabled']=!![],_0x22de37['textContent']='Adding…';try{const _0x3041ec={'subject_type':'team','subject_id':state['bindingsTeamId'],'role_id':_0x2f721e,'resource_type':_0x557b2e};if(_0x3a15c7)_0x3041ec['resource_id']=_0x3a15c7;await API['createBinding'](_0x3041ec),Utils['showToast']('Binding\x20added','success'),document['getElementById']('add-binding-form')['hidden']=!![],document['getElementById']('add-binding-btn')['hidden']=![],await loadTeamBindings(state['bindingsTeamId']);}catch(_0x451a44){Utils['showToast'](_0x451a44['message'],'error');}finally{_0x22de37['disabled']=![],_0x22de37['textContent']='Add\x20Binding';}}window['deleteBindingClick']=async function(_0x470a0d){try{await API['deleteBinding'](_0x470a0d),Utils['showToast']('Binding\x20removed','success'),await loadTeamBindings(state['bindingsTeamId']);}catch(_0x49e27d){Utils['showToast'](_0x49e27d['message'],'error');}};async function saveTeam(){const _0x484621=document['getElementById']('team-name')['value']['trim'](),_0x454085=document['getElementById']('team-description')['value']['trim'](),_0xf28bdd=document['getElementById']('team-form-error'),_0x462826=document['getElementById']('save-team');if(!_0x484621){_0xf28bdd['textContent']='Team\x20name\x20is\x20required',_0xf28bdd['hidden']=![];return;}_0xf28bdd['hidden']=!![];const _0x3df4b7=_0x462826['textContent'];_0x462826['disabled']=!![],_0x462826['textContent']=state['editingTeamId']?'Saving…':'Creating…';try{if(state['editingTeamId']){const {team:_0x30efdc}=await API['updateTeam'](state['editingTeamId'],{'name':_0x484621,'description':_0x454085});syncTeamInState(_0x30efdc),document['getElementById']('team-modal-title')['textContent']=_0x30efdc['name'],Utils['showToast']('Team\x20updated','success');}else await API['createTeam']({'name':_0x484621,'description':_0x454085}),Utils['showToast']('Team\x20created','success');_0x462826['disabled']=![],_0x462826['textContent']=_0x3df4b7,hideTeamModal(),await loadTeams();}catch(_0x518dfd){_0xf28bdd['textContent']=_0x518dfd['message'],_0xf28bdd['hidden']=![],_0x462826['disabled']=![],_0x462826['textContent']=_0x3df4b7;}}window['deleteTeam']=function(_0x3e427a){const _0x563d3f=state['teams']['find'](_0x4a10d4=>_0x4a10d4['id']===_0x3e427a);if(!_0x563d3f)return;state['deletingTeamId']=_0x3e427a,document['getElementById']('delete-team-name')['textContent']=_0x563d3f['name'],document['getElementById']('delete-team-modal')['hidden']=![];};function hideDeleteModal(){document['getElementById']('delete-team-modal')['hidden']=!![],state['deletingTeamId']=null;}async function confirmDeleteTeam(){if(!state['deletingTeamId'])return;const _0x244fdf=document['getElementById']('confirm-delete-team');_0x244fdf['disabled']=!![],_0x244fdf['textContent']='Deleting…';try{await API['deleteTeam'](state['deletingTeamId']),Utils['showToast']('Team\x20deleted','success'),_0x244fdf['disabled']=![],_0x244fdf['textContent']='Delete\x20Team',hideDeleteModal(),await loadTeams();}catch(_0x411eaf){Utils['showToast']('Failed\x20to\x20delete\x20team:\x20'+_0x411eaf['message'],'error'),_0x244fdf['disabled']=![],_0x244fdf['textContent']='Delete\x20Team';}}function syncTeamInState(_0x8c3b21){const _0x5db37f=state['teams']['findIndex'](_0x1cc104=>_0x1cc104['id']===_0x8c3b21['id']);if(_0x5db37f>=0x0)state['teams'][_0x5db37f]=_0x8c3b21;renderTeams();}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{API,Utils}from'./app.js';import{Terminal}from'/vendor/xterm/5.3.0/xterm.esm.js';import{FitAddon}from'/vendor/xterm-addon-fit/0.7.0/xterm-addon-fit.esm.js';import{getCurrentTheme,initTheme,mountThemeToggle,onThemeChange}from'./theme.js';const params=Utils['getQueryParams'](),containerId=params['container'],command=(params['cmd']||'')['trim'](),useServerExec=params['server_exec']==='true',isEmbedded=params['embedded']==='true',terminalTabId=params['tabId']||'',titleEl=document['getElementById']('terminal-title'),subtitleEl=document['getElementById']('terminal-subtitle'),statusEl=document['getElementById']('terminal-status'),terminalEl=document['getElementById']('terminal-container'),closeBtn=document['getElementById']('close-terminal');initTheme();isEmbedded?(document['documentElement']['classList']['add']('terminal-embedded'),document['body']['classList']['add']('terminal-embedded')):mountThemeToggle({'targetSelectors':['.terminal-actions']});const getXtermTheme=()=>{return{'background':'#0f172a','foreground':'#e2e8f0','cursor':'#e2e8f0','cursorAccent':'#0f172a'};};closeBtn&&closeBtn['addEventListener']('click',()=>{if(isEmbedded&&window['parent']&&window['parent']!==window){window['parent']['postMessage']({'type':'coderflow-terminal-close','tabId':terminalTabId},window['location']['origin']);return;}window['close']();});if(!containerId){updateStatus('Missing\x20container\x20identifier','error');throw new Error('container\x20parameter\x20is\x20required');}document['title']='Terminal\x20·\x20'+containerId['slice'](0x0,0xc),enrichContainerDetails(containerId)['catch'](()=>{subtitleEl['textContent']='Container\x20'+containerId['substring'](0x0,0xc);});const term=new Terminal({'convertEol':!![],'cursorBlink':!![],'fontFamily':'JetBrains\x20Mono,\x20SFMono-Regular,\x20Consolas,\x20monospace','fontSize':0x10,'theme':getXtermTheme()}),fitAddon=new FitAddon();term['loadAddon'](fitAddon),term['open'](terminalEl),term['focus']();let isFitting=![];const doFit=()=>{if(isFitting)return;isFitting=!![],fitAddon['fit'](),sendResize(),term['scrollToBottom'](),setTimeout(()=>{isFitting=![];},0x32);};window['addEventListener']('resize',()=>{requestAnimationFrame(()=>{!isFitting&&doFit();});});const resizeObserver=new ResizeObserver(()=>{requestAnimationFrame(()=>{!isFitting&&doFit();});});resizeObserver['observe'](terminalEl);const socketProtocol=window['location']['protocol']==='https:'?'wss':'ws',socketUrl=new URL('/ws/containers/'+encodeURIComponent(containerId),window['location']['href']);command&&useServerExec&&socketUrl['searchParams']['set']('cmd',command);socketUrl['protocol']=socketProtocol+':';const socket=new WebSocket(socketUrl['toString']());term['onData'](
|
|
1
|
+
import{API,Utils}from'./app.js';import{Terminal}from'/vendor/xterm/5.3.0/xterm.esm.js';import{FitAddon}from'/vendor/xterm-addon-fit/0.7.0/xterm-addon-fit.esm.js';import{getCurrentTheme,initTheme,mountThemeToggle,onThemeChange}from'./theme.js';const params=Utils['getQueryParams'](),containerId=params['container'],command=(params['cmd']||'')['trim'](),useServerExec=params['server_exec']==='true',isEmbedded=params['embedded']==='true',terminalTabId=params['tabId']||'',titleEl=document['getElementById']('terminal-title'),subtitleEl=document['getElementById']('terminal-subtitle'),statusEl=document['getElementById']('terminal-status'),terminalEl=document['getElementById']('terminal-container'),closeBtn=document['getElementById']('close-terminal');initTheme();isEmbedded?(document['documentElement']['classList']['add']('terminal-embedded'),document['body']['classList']['add']('terminal-embedded')):mountThemeToggle({'targetSelectors':['.terminal-actions']});const getXtermTheme=()=>{return{'background':'#0f172a','foreground':'#e2e8f0','cursor':'#e2e8f0','cursorAccent':'#0f172a'};};closeBtn&&closeBtn['addEventListener']('click',()=>{if(isEmbedded&&window['parent']&&window['parent']!==window){window['parent']['postMessage']({'type':'coderflow-terminal-close','tabId':terminalTabId},window['location']['origin']);return;}window['close']();});if(!containerId){updateStatus('Missing\x20container\x20identifier','error');throw new Error('container\x20parameter\x20is\x20required');}document['title']='Terminal\x20·\x20'+containerId['slice'](0x0,0xc),enrichContainerDetails(containerId)['catch'](()=>{subtitleEl['textContent']='Container\x20'+containerId['substring'](0x0,0xc);});const term=new Terminal({'convertEol':!![],'cursorBlink':!![],'fontFamily':'JetBrains\x20Mono,\x20SFMono-Regular,\x20Consolas,\x20monospace','fontSize':0x10,'theme':getXtermTheme()}),fitAddon=new FitAddon();term['loadAddon'](fitAddon),term['open'](terminalEl),term['focus']();let isFitting=![];const doFit=()=>{if(isFitting)return;isFitting=!![],fitAddon['fit'](),sendResize(),term['scrollToBottom'](),setTimeout(()=>{isFitting=![];},0x32);};window['addEventListener']('resize',()=>{requestAnimationFrame(()=>{!isFitting&&doFit();});});const resizeObserver=new ResizeObserver(()=>{requestAnimationFrame(()=>{!isFitting&&doFit();});});resizeObserver['observe'](terminalEl);const socketProtocol=window['location']['protocol']==='https:'?'wss':'ws',socketUrl=new URL('/ws/containers/'+encodeURIComponent(containerId),window['location']['href']);command&&useServerExec&&socketUrl['searchParams']['set']('cmd',command);socketUrl['protocol']=socketProtocol+':';const socket=new WebSocket(socketUrl['toString']());term['onData'](_0x1e2548=>{socket['readyState']===WebSocket['OPEN']&&socket['send'](JSON['stringify']({'type':'data','data':_0x1e2548}));});let commandSent=![],hasReceivedOutput=![];socket['addEventListener']('message',_0x1d535f=>{try{const _0x55b6bb=JSON['parse'](_0x1d535f['data']);if(_0x55b6bb['type']==='data'&&typeof _0x55b6bb['data']==='string')term['write'](_0x55b6bb['data']),!hasReceivedOutput&&_0x55b6bb['data']['length']>0x0&&(hasReceivedOutput=!![],command&&!useServerExec&&!commandSent&&(commandSent=!![],setTimeout(()=>{socket['readyState']===WebSocket['OPEN']&&socket['send'](JSON['stringify']({'type':'data','data':command+'\x0d'}));},0xc8)));else{if(_0x55b6bb['type']==='status'&&_0x55b6bb['status']){if(_0x55b6bb['status']==='connected'){if(command&&useServerExec)updateStatus('Running:\x20'+command,'info');else command?updateStatus('Preparing:\x20'+command,'info'):updateStatus('Terminal\x20connected','success');doFit(),term['focus'](),command&&!useServerExec&&!commandSent&&setTimeout(()=>{!commandSent&&socket['readyState']===WebSocket['OPEN']&&(commandSent=!![],socket['send'](JSON['stringify']({'type':'data','data':command+'\x0d'})),updateStatus('Running:\x20'+command,'info'));},0x7d0);}else updateStatus('Session\x20'+_0x55b6bb['status'],_0x55b6bb['status']==='connected'?'success':'info');}else _0x55b6bb['type']==='error'&&_0x55b6bb['message']&&updateStatus(_0x55b6bb['message'],'error');}}catch(_0x2cf499){console['error']('Failed\x20to\x20parse\x20terminal\x20message',_0x2cf499);}}),socket['addEventListener']('close',_0x29eec4=>{const _0x28bc9b=_0x29eec4['reason']||'Connection\x20closed';updateStatus(_0x28bc9b,_0x29eec4['wasClean']?'info':'error'),isEmbedded&&terminalTabId&&window['parent']&&window['parent']!==window&&window['parent']['postMessage']({'type':'coderflow-terminal-disconnected','tabId':terminalTabId},window['location']['origin']);}),socket['addEventListener']('error',_0x189304=>{console['error']('Terminal\x20websocket\x20error',_0x189304),updateStatus('Connection\x20error','error');});function sendResize(){if(socket['readyState']!==WebSocket['OPEN'])return;const _0x573168=term['cols'],_0x41a49f=term['rows'];socket['send'](JSON['stringify']({'type':'resize','cols':_0x573168,'rows':_0x41a49f}));}function updateStatus(_0x13bd4b,_0x2e507e='info'){if(!statusEl)return;statusEl['textContent']=_0x13bd4b,statusEl['dataset']['variant']=_0x2e507e;}async function enrichContainerDetails(_0x679381){try{const _0xb2c8fd=await API['getContainer'](_0x679381);updateTerminalDetails(_0xb2c8fd);}catch{try{const _0x55b339=await API['getContainers'](),_0x22ecd7=(_0x55b339['containers']||[])['find'](_0xf21691=>_0xf21691['containerId']===_0x679381||_0xf21691['name']===_0x679381||_0xf21691['fullContainerId']?.['startsWith'](_0x679381));if(_0x22ecd7){updateTerminalDetails(_0x22ecd7);return;}subtitleEl['textContent']='Container\x20'+_0x679381['substring'](0x0,0xc);}catch{subtitleEl['textContent']='Container\x20'+_0x679381['substring'](0x0,0xc);}}}function updateTerminalDetails(_0x28cf36){const _0x4df213=_0x28cf36['containerId']||_0x28cf36['name']||_0x28cf36['fullContainerId']||containerId,_0x247148=_0x28cf36['environment']?'Environment\x20'+_0x28cf36['environment']:'Environment\x20unknown',_0x19e36b=_0x28cf36['defaultAgent']?'\x20·\x20Agent\x20'+_0x28cf36['defaultAgent']:'',_0x364dad=_0x28cf36['createdAt']?'\x20·\x20Started\x20'+Utils['formatRelativeTime'](_0x28cf36['createdAt']):'';titleEl['textContent']='Terminal\x20·\x20'+_0x4df213['substring'](0x0,0xc);const _0x274af0=command?'\x20·\x20Command\x20'+command:'';subtitleEl['textContent']=''+_0x247148+_0x19e36b+_0x364dad+_0x274af0;}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const THEME_STORAGE_KEY='profound-coder-theme',THEME_CHANGE_EVENT='profound-theme-change',VALID_THEMES=new Set(['light','dark']),DEFAULT_TARGET_SELECTORS=['#theme-toggle-container','.header-actions','.status-actions','.terminal-actions','.top-bar'];function readStoredTheme(){try{const
|
|
1
|
+
const THEME_STORAGE_KEY='profound-coder-theme',THEME_CHANGE_EVENT='profound-theme-change',VALID_THEMES=new Set(['light','dark']),DEFAULT_TARGET_SELECTORS=['#theme-toggle-container','.header-actions','.status-actions','.terminal-actions','.top-bar'];function readStoredTheme(){try{const _0x57b9c6=localStorage['getItem'](THEME_STORAGE_KEY);if(_0x57b9c6&&VALID_THEMES['has'](_0x57b9c6))return _0x57b9c6;}catch(_0x4ce70d){console['warn']('[Theme]\x20Failed\x20to\x20read\x20stored\x20theme\x20preference:',_0x4ce70d);}return null;}export function getPreferredTheme(){const _0x5f1fd4=readStoredTheme();if(_0x5f1fd4)return _0x5f1fd4;const _0x485ce6=window['matchMedia']&&window['matchMedia']('(prefers-color-scheme:\x20dark)')['matches'];return _0x485ce6?'dark':'light';}export function getCurrentTheme(){const _0x1bf9bc=document['documentElement']['dataset']['theme'];if(_0x1bf9bc&&VALID_THEMES['has'](_0x1bf9bc))return _0x1bf9bc;return getPreferredTheme();}export function applyTheme(_0x38d347,{persist:persist=!![],emitEvent:emitEvent=!![]}={}){const _0x36fb02=VALID_THEMES['has'](_0x38d347)?_0x38d347:'light';document['documentElement']['dataset']['theme']=_0x36fb02,document['documentElement']['style']['colorScheme']=_0x36fb02==='dark'?'dark':'light';if(persist)try{localStorage['setItem'](THEME_STORAGE_KEY,_0x36fb02);}catch(_0x2819d1){console['warn']('[Theme]\x20Failed\x20to\x20persist\x20theme\x20preference:',_0x2819d1);}return emitEvent&&window['dispatchEvent'](new CustomEvent(THEME_CHANGE_EVENT,{'detail':{'theme':_0x36fb02}})),_0x36fb02;}export function initTheme(_0x15cfe1={}){const {emitEvent:emitEvent=![]}=_0x15cfe1;return applyTheme(getPreferredTheme(),{'persist':![],'emitEvent':emitEvent});}export function toggleTheme(){const _0x7eab8=getCurrentTheme()==='dark'?'light':'dark';return applyTheme(_0x7eab8);}export function onThemeChange(_0x4337d8,{runImmediately:runImmediately=![]}={}){const _0x2cb04b=_0x52c23d=>{_0x4337d8(_0x52c23d['detail']['theme']);};return window['addEventListener'](THEME_CHANGE_EVENT,_0x2cb04b),runImmediately&&_0x4337d8(getCurrentTheme()),()=>window['removeEventListener'](THEME_CHANGE_EVENT,_0x2cb04b);}export function mountThemeToggle(_0x2b214a={}){const {targetSelectors:targetSelectors=DEFAULT_TARGET_SELECTORS}=_0x2b214a,_0x361f33=targetSelectors['map'](_0xb5f737=>document['querySelector'](_0xb5f737))['find'](Boolean),_0xb21a12=document['createElement']('button');_0xb21a12['type']='button',_0xb21a12['className']='btn-ghost\x20theme-toggle-btn',_0xb21a12['id']='theme-toggle-btn',_0xb21a12['setAttribute']('aria-pressed','false'),_0xb21a12['style']['padding']='8px',_0xb21a12['style']['lineHeight']='0',_0xb21a12['style']['width']='36px',_0xb21a12['style']['height']='36px',_0xb21a12['style']['display']='flex',_0xb21a12['style']['alignItems']='center',_0xb21a12['style']['justifyContent']='center';const _0x5c14a2=document['createElement']('span');_0x5c14a2['className']='theme-icon',_0x5c14a2['style']['display']='flex',_0xb21a12['append'](_0x5c14a2);const _0x5b5d96='<svg\x20xmlns=\x22http://www.w3.org/2000/svg\x22\x20width=\x2220\x22\x20height=\x2220\x22\x20viewBox=\x220\x200\x2024\x2024\x22\x20fill=\x22none\x22\x20stroke=\x22currentColor\x22\x20stroke-width=\x222\x22\x20stroke-linecap=\x22round\x22\x20stroke-linejoin=\x22round\x22><path\x20d=\x22M21\x2012.79A9\x209\x200\x201\x201\x2011.21\x203\x207\x207\x200\x200\x200\x2021\x2012.79z\x22></path></svg>',_0x2630ad='<svg\x20xmlns=\x22http://www.w3.org/2000/svg\x22\x20width=\x2220\x22\x20height=\x2220\x22\x20viewBox=\x220\x200\x2024\x2024\x22\x20fill=\x22none\x22\x20stroke=\x22currentColor\x22\x20stroke-width=\x222\x22\x20stroke-linecap=\x22round\x22\x20stroke-linejoin=\x22round\x22><circle\x20cx=\x2212\x22\x20cy=\x2212\x22\x20r=\x225\x22></circle><line\x20x1=\x2212\x22\x20y1=\x221\x22\x20x2=\x2212\x22\x20y2=\x223\x22></line><line\x20x1=\x2212\x22\x20y1=\x2221\x22\x20x2=\x2212\x22\x20y2=\x2223\x22></line><line\x20x1=\x224.22\x22\x20y1=\x224.22\x22\x20x2=\x225.64\x22\x20y2=\x225.64\x22></line><line\x20x1=\x2218.36\x22\x20y1=\x2218.36\x22\x20x2=\x2219.78\x22\x20y2=\x2219.78\x22></line><line\x20x1=\x221\x22\x20y1=\x2212\x22\x20x2=\x223\x22\x20y2=\x2212\x22></line><line\x20x1=\x2221\x22\x20y1=\x2212\x22\x20x2=\x2223\x22\x20y2=\x2212\x22></line><line\x20x1=\x224.22\x22\x20y1=\x2219.78\x22\x20x2=\x225.64\x22\x20y2=\x2218.36\x22></line><line\x20x1=\x2218.36\x22\x20y1=\x225.64\x22\x20x2=\x2219.78\x22\x20y2=\x224.22\x22></line></svg>',_0x20f5c7=_0x5b8e47=>{const _0x173da0=_0x5b8e47==='dark';_0x5c14a2['innerHTML']=_0x173da0?_0x5b5d96:_0x2630ad,_0xb21a12['title']=_0x173da0?'Switch\x20to\x20light\x20mode':'Switch\x20to\x20dark\x20mode',_0xb21a12['dataset']['theme']=_0x5b8e47,_0xb21a12['setAttribute']('aria-pressed',String(_0x173da0));};return _0xb21a12['addEventListener']('click',()=>{const _0x149546=getCurrentTheme()==='dark'?'light':'dark';applyTheme(_0x149546);}),_0x361f33?_0x361f33['appendChild'](_0xb21a12):(_0xb21a12['classList']['add']('theme-toggle-floating'),document['body']['appendChild'](_0xb21a12)),_0x20f5c7(initTheme()),onThemeChange(_0x20f5c7),_0xb21a12;}export{THEME_STORAGE_KEY,THEME_CHANGE_EVENT};
|
|
@@ -95,11 +95,11 @@
|
|
|
95
95
|
</svg>
|
|
96
96
|
<span class="option-text">Server Settings</span>
|
|
97
97
|
</button>
|
|
98
|
-
<button type="button" class="dropdown-item admin-menu-item"
|
|
98
|
+
<button type="button" class="dropdown-item admin-menu-item" onclick="window.location.href='admin.html'">
|
|
99
99
|
<svg class="option-icon icon-health" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
100
100
|
<path d="M22 12h-4l-3 9L9 3l-3 9H2"></path>
|
|
101
101
|
</svg>
|
|
102
|
-
<span class="option-text">Server
|
|
102
|
+
<span class="option-text">Server Administration</span>
|
|
103
103
|
</button>
|
|
104
104
|
<button type="button" class="dropdown-item admin-menu-item" onclick="window.location.href='git-history.html'">
|
|
105
105
|
<svg class="option-icon icon-git-history" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{API,Utils,ConfirmDialog,initializeAdminMenu}from'./app.js';import{initTheme,mountThemeToggle}from'./theme.js';const state={'users':[],'editingUserId':null,'bindingsUserId':null,'deletingUserId':null,'setupLinkData':null,'emailConfigured':![],'currentUser':null,'roles':[],'environments':[],'teams':[],'userBindings':[],'bindingsDirty':![]};document['addEventListener']('DOMContentLoaded',async()=>{initTheme(),mountThemeToggle(),await checkAdminAccess(),await initializeAdminMenu(state['currentUser']),await Promise['all']([checkEmailConfig(),loadRoles(),loadEnvironments(),loadTeams()]),bindEventListeners(),await loadUsers();});async function checkAdminAccess(){try{const _0x5cf1ca=await API['getCurrentUser']();state['currentUser']=_0x5cf1ca;if(!Permissions['hasServerPermission'](_0x5cf1ca,'*')&&!Permissions['hasServerPermission'](_0x5cf1ca,'users:create')){Utils['showToast']('Access\x20denied:\x20Server\x20admin\x20privileges\x20required','error'),setTimeout(()=>{window['location']['href']='index.html';},0x7d0);return;}}catch(_0x341d20){window['location']['href']='login.html';}}async function checkEmailConfig(){try{const _0x5b4ac3=await API['getEmailConfig']();state['emailConfigured']=_0x5b4ac3['configured'];}catch(_0x55051e){console['error']('Failed\x20to\x20check\x20email\x20config',_0x55051e),state['emailConfigured']=![];}}async function loadRoles(){try{const {roles:_0x5662d7}=await API['getRoleDefinitions']();state['roles']=_0x5662d7||[];}catch{state['roles']=[];}}async function loadEnvironments(){try{const _0x1fbad2=await API['getEnvironments']();state['environments']=_0x1fbad2['environments']||[];}catch{state['environments']=[];}}async function loadTeams(){try{const {teams:_0xaafce8}=await API['getTeams']();state['teams']=_0xaafce8||[];}catch{state['teams']=[];}}function bindEventListeners(){document['getElementById']('create-user-btn')?.['addEventListener']('click',showCreateUserModal),document['getElementById']('close-user-modal')?.['addEventListener']('click',hideUserModal),document['getElementById']('cancel-user')?.['addEventListener']('click',hideUserModal),document['getElementById']('save-user')?.['addEventListener']('click',saveUser),document['querySelector']('#user-modal\x20.modal-overlay')?.['addEventListener']('click',hideUserModal),document['getElementById']('close-delete-modal')?.['addEventListener']('click',hideDeleteModal),document['getElementById']('cancel-delete')?.['addEventListener']('click',hideDeleteModal),document['getElementById']('confirm-delete')?.['addEventListener']('click',confirmDeleteUser),document['querySelector']('#delete-modal\x20.modal-overlay')?.['addEventListener']('click',hideDeleteModal),document['getElementById']('close-setup-link-modal')?.['addEventListener']('click',hideSetupLinkModal),document['getElementById']('close-setup-link')?.['addEventListener']('click',hideSetupLinkModal),document['getElementById']('copy-setup-link')?.['addEventListener']('click',copySetupLink),document['getElementById']('email-setup-link')?.['addEventListener']('click',emailSetupLink),document['querySelector']('#setup-link-modal\x20.modal-overlay')?.['addEventListener']('click',hideSetupLinkModal),document['getElementById']('skip-password')?.['addEventListener']('change',handleSkipPasswordChange),document['getElementById']('retry-users-btn')?.['addEventListener']('click',loadUsers),document['getElementById']('close-bindings-modal')?.['addEventListener']('click',hideAccessBindingsModal),document['getElementById']('close-bindings-modal-footer')?.['addEventListener']('click',hideAccessBindingsModal),document['querySelector']('#bindings-modal\x20.modal-overlay')?.['addEventListener']('click',hideAccessBindingsModal),document['getElementById']('add-user-binding-btn')?.['addEventListener']('click',()=>{document['getElementById']('add-user-binding-form')['hidden']=![],document['getElementById']('add-user-binding-btn')['hidden']=!![],populateUserBindingForm();}),document['getElementById']('cancel-user-binding-btn')?.['addEventListener']('click',()=>{document['getElementById']('add-user-binding-form')['hidden']=!![],document['getElementById']('add-user-binding-btn')['hidden']=![];}),document['getElementById']('save-user-binding-btn')?.['addEventListener']('click',saveUserBinding),document['getElementById']('user-binding-resource-type')?.['addEventListener']('change',onUserBindingResourceTypeChange);}async function loadUsers(){const _0x49a968=document['getElementById']('users-loading'),_0x43c372=document['getElementById']('users-error'),_0x17be17=document['getElementById']('users-content');try{_0x49a968['hidden']=![],_0x43c372['hidden']=!![],_0x17be17['hidden']=!![];const _0x24bddd=await API['getUsers']();state['users']=_0x24bddd['users']||[],renderUsers(),_0x49a968['hidden']=!![],_0x17be17['hidden']=![];}catch(_0x165768){console['error']('Failed\x20to\x20load\x20users',_0x165768),_0x49a968['hidden']=!![],_0x43c372['hidden']=![],document['getElementById']('users-error-message')['textContent']=_0x165768['message'];}}function renderUsers(){const _0x9fc1d3=document['getElementById']('users-table-body'),_0x4fd354=document['getElementById']('user-count');if(!_0x9fc1d3)return;_0x4fd354&&(_0x4fd354['textContent']=state['users']['length']+'\x20user'+(state['users']['length']===0x1?'':'s'));const _0x320ab2=[...state['users']]['sort']((_0x311b96,_0x1c7585)=>{const _0x4b3482=new Date(_0x311b96['created_at'])['getTime'](),_0x5ab575=new Date(_0x1c7585['created_at'])['getTime']();return _0x5ab575-_0x4b3482;});_0x9fc1d3['innerHTML']=_0x320ab2['map'](_0x147e91=>'\x0a\x20\x20\x20\x20<tr>\x0a\x20\x20\x20\x20\x20\x20<td>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<div\x20class=\x22user-username\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20'+Utils['escapeHtml'](_0x147e91['username'])+'\x0a\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20</td>\x0a\x20\x20\x20\x20\x20\x20<td>'+Utils['escapeHtml'](_0x147e91['name'])+'</td>\x0a\x20\x20\x20\x20\x20\x20<td>'+Utils['escapeHtml'](_0x147e91['email'])+'</td>\x0a\x20\x20\x20\x20\x20\x20<td>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<div\x20class=\x22access-badges\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20'+(_0x147e91['isServerAdmin']?'<span\x20class=\x22role-badge\x20role-admin\x22>Server\x20Admin</span>':'')+'\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20'+(_0x147e91['hasUserBinding']?'<span\x20class=\x22role-badge\x20role-user-binding\x22>User\x20Binding</span>':'')+'\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20'+(_0x147e91['hasTeamBinding']?'<span\x20class=\x22role-badge\x20role-team-binding\x22>Team\x20Binding</span>':'')+'\x0a\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20</td>\x0a\x20\x20\x20\x20\x20\x20<td>'+Utils['formatRelativeTime'](_0x147e91['created_at'])+'</td>\x0a\x20\x20\x20\x20\x20\x20<td>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<div\x20class=\x22user-actions\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<button\x20class=\x22btn-icon\x20btn-small\x22\x20onclick=\x22window.editUser(\x27'+_0x147e91['id']+'\x27)\x22\x20title=\x22Edit\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<svg\x20width=\x2214\x22\x20height=\x2214\x22\x20viewBox=\x220\x200\x2024\x2024\x22\x20fill=\x22none\x22\x20stroke=\x22currentColor\x22\x20stroke-width=\x222\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<path\x20d=\x22M11\x204H4a2\x202\x200\x200\x200-2\x202v14a2\x202\x200\x200\x200\x202\x202h14a2\x202\x200\x200\x200\x202-2v-7\x22></path>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<path\x20d=\x22M18.5\x202.5a2.121\x202.121\x200\x200\x201\x203\x203L12\x2015l-4\x201\x201-4\x209.5-9.5z\x22></path>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</svg>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</button>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<button\x20class=\x22btn-icon\x20btn-small\x22\x20onclick=\x22window.showAccessBindings(\x27'+_0x147e91['id']+'\x27)\x22\x20title=\x22Access\x20Bindings\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<svg\x20width=\x2214\x22\x20height=\x2214\x22\x20viewBox=\x220\x200\x2024\x2024\x22\x20fill=\x22none\x22\x20stroke=\x22currentColor\x22\x20stroke-width=\x222\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<path\x20d=\x22M12\x2022s8-4\x208-10V5l-8-3-8\x203v7c0\x206\x208\x2010\x208\x2010z\x22></path>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</svg>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</button>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<button\x20class=\x22btn-icon\x20btn-small\x20btn-danger\x22\x20onclick=\x22window.deleteUser(\x27'+_0x147e91['id']+'\x27)\x22\x20title=\x22Delete\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<svg\x20width=\x2214\x22\x20height=\x2214\x22\x20viewBox=\x220\x200\x2024\x2024\x22\x20fill=\x22none\x22\x20stroke=\x22currentColor\x22\x20stroke-width=\x222\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<polyline\x20points=\x223\x206\x205\x206\x2021\x206\x22></polyline>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<path\x20d=\x22M19\x206v14a2\x202\x200\x200\x201-2\x202H7a2\x202\x200\x200\x201-2-2V6m3\x200V4a2\x202\x200\x200\x201\x202-2h4a2\x202\x200\x200\x201\x202\x202v2\x22></path>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</svg>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</button>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<button\x20class=\x22btn-secondary\x20btn-small\x22\x20onclick=\x22window.resetPassword(\x27'+_0x147e91['id']+'\x27)\x22>Reset\x20Password</button>\x0a\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20</td>\x0a\x20\x20\x20\x20</tr>\x0a\x20\x20')['join']('');}window['showAccessBindings']=function(_0x100f8d){const _0x3382f3=state['users']['find'](_0x53dd84=>_0x53dd84['id']===_0x100f8d);if(!_0x3382f3)return;state['bindingsUserId']=_0x100f8d,state['bindingsDirty']=![];const _0x313056=document['getElementById']('bindings-modal'),_0x373f51=document['getElementById']('bindings-modal-title');_0x373f51['textContent']='Access\x20Bindings\x20—\x20'+_0x3382f3['name'],document['getElementById']('add-user-binding-form')['hidden']=!![],document['getElementById']('add-user-binding-btn')['hidden']=![],_0x313056['hidden']=![],loadUserBindings(_0x100f8d);};function hasUnsavedBindingChanges(){const _0xab563=document['getElementById']('add-user-binding-form');return _0xab563&&!_0xab563['hidden'];}async function hideAccessBindingsModal(){if(hasUnsavedBindingChanges()){if(!confirm('You\x20have\x20an\x20unsaved\x20binding.\x20Discard\x20changes?'))return;document['getElementById']('add-user-binding-form')['hidden']=!![],document['getElementById']('add-user-binding-btn')['hidden']=![];}const _0x37dba2=document['getElementById']('bindings-modal');_0x37dba2['hidden']=!![];const _0x4b0276=state['bindingsDirty'];state['bindingsUserId']=null,state['userBindings']=[],state['bindingsDirty']=![],_0x4b0276&&await loadUsers();}async function loadUserBindings(_0x185fa5){const _0x6a7d94=document['getElementById']('user-bindings-loading'),_0x50f02d=document['getElementById']('user-bindings-empty'),_0x5008f7=document['getElementById']('user-bindings-list-container'),_0x322fdb=document['getElementById']('add-user-binding-btn'),_0x49436b=document['getElementById']('user-team-bindings-note'),_0x4123d7=document['getElementById']('user-team-bindings-text');_0x6a7d94['hidden']=![],_0x50f02d['hidden']=!![],_0x5008f7['style']['display']='none',_0x322fdb['hidden']=!![],_0x49436b['hidden']=!![],document['getElementById']('add-user-binding-form')['hidden']=!![];try{const [_0x3d798a,_0x4fff58]=await Promise['all']([API['getBindings']({'subject_type':'user','subject_id':_0x185fa5}),API['getTeams']()]);state['userBindings']=_0x3d798a['bindings']||[];const _0x3fa99b=(_0x4fff58['teams']||[])['filter'](_0x3f7d60=>(_0x3f7d60['members']||[])['includes'](_0x185fa5)),_0x169179=[];if(_0x3fa99b['length']>0x0){const _0x5e2d88=await Promise['all'](_0x3fa99b['map'](_0x329a93=>API['getBindings']({'subject_type':'team','subject_id':_0x329a93['id']})));for(let _0x429aac=0x0;_0x429aac<_0x3fa99b['length'];_0x429aac++){const _0x2722e5=_0x5e2d88[_0x429aac]['bindings']||[];_0x2722e5['length']>0x0&&_0x169179['push'](_0x3fa99b[_0x429aac]);}}_0x6a7d94['hidden']=!![];state['userBindings']['length']===0x0?_0x50f02d['hidden']=![]:(_0x5008f7['style']['display']='',renderUserBindingsTable());if(_0x169179['length']>0x0){const _0x3ef6d9=_0x169179['map'](_0x435be1=>_0x435be1['name']),_0x423261=_0x3ef6d9['length']<=0x3?_0x3ef6d9['join'](',\x20'):_0x3ef6d9['slice'](0x0,0x3)['join'](',\x20')+(',\x20and\x20'+(_0x3ef6d9['length']-0x3)+'\x20more');_0x4123d7['textContent']='This\x20user\x20also\x20has\x20access\x20via\x20team\x20memberships\x20('+_0x423261+').';}else _0x4123d7['textContent']='This\x20user\x20has\x20no\x20access\x20via\x20team\x20memberships.';_0x49436b['hidden']=![],_0x322fdb['hidden']=![];}catch(_0x357eb6){_0x6a7d94['hidden']=!![],Utils['showToast']('Failed\x20to\x20load\x20bindings:\x20'+_0x357eb6['message'],'error');}}function renderUserBindingsTable(){const _0x48b9b7=document['getElementById']('user-bindings-table-body');if(!_0x48b9b7)return;_0x48b9b7['innerHTML']=state['userBindings']['map'](_0x566270=>{const _0x2b1e45=_0x566270['resource_type']==='server'?'Server':_0x566270['resource_id']==='*'?'All\x20'+_0x566270['resource_type']+'s':Utils['escapeHtml'](_0x566270['resource_id']||'');return'\x0a\x20\x20\x20\x20<tr>\x0a\x20\x20\x20\x20\x20\x20<td>'+_0x2b1e45+'</td>\x0a\x20\x20\x20\x20\x20\x20<td>'+Utils['escapeHtml'](_0x566270['role_name']||_0x566270['role_id'])+'</td>\x0a\x20\x20\x20\x20\x20\x20<td>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<button\x20class=\x22btn-ghost\x20btn-small\x22\x20onclick=\x22window.deleteUserBindingClick(\x27'+_0x566270['id']+'\x27)\x22\x20style=\x22color:\x20var(--color-danger);\x22>Remove</button>\x0a\x20\x20\x20\x20\x20\x20</td>\x0a\x20\x20\x20\x20</tr>';})['join']('');}function populateUserBindingForm(){const _0x370151=document['getElementById']('user-binding-resource-type');_0x370151['value']='environment',updateUserBindingFormForResourceType('environment');}function onUserBindingResourceTypeChange(){const _0x5cc1f1=document['getElementById']('user-binding-resource-type')['value'];updateUserBindingFormForResourceType(_0x5cc1f1);}function updateUserBindingFormForResourceType(_0x25f065){const _0x5517af=document['getElementById']('user-binding-resource-container'),_0x350ff6=document['getElementById']('user-binding-resource'),_0x36c075=document['getElementById']('user-binding-role');if(_0x25f065==='server')_0x5517af['style']['display']='none';else{_0x5517af['style']['display']='';if(_0x25f065==='environment'){const _0x237638=new Set(state['userBindings']['filter'](_0x74c6a2=>_0x74c6a2['resource_type']==='environment')['map'](_0x281132=>_0x281132['resource_id'])),_0x20c834=state['environments']['filter'](_0x2ac99b=>!_0x237638['has'](_0x2ac99b['name']));_0x350ff6['innerHTML']=_0x20c834['length']?_0x20c834['map'](_0x180dc9=>'<option\x20value=\x22'+Utils['escapeHtml'](_0x180dc9['name'])+'\x22>'+Utils['escapeHtml'](_0x180dc9['name'])+'</option>')['join'](''):'<option\x20value=\x22\x22>All\x20environments\x20already\x20bound</option>';}else{if(_0x25f065==='team'){const _0x46d0a3=new Set(state['userBindings']['filter'](_0x48b525=>_0x48b525['resource_type']==='team')['map'](_0x5e21d1=>_0x5e21d1['resource_id'])),_0x8f8eb5=state['teams']['filter'](_0x11b1bd=>!_0x46d0a3['has'](_0x11b1bd['id']));_0x350ff6['innerHTML']=_0x8f8eb5['length']?_0x8f8eb5['map'](_0x13d086=>'<option\x20value=\x22'+_0x13d086['id']+'\x22>'+Utils['escapeHtml'](_0x13d086['name'])+'</option>')['join'](''):'<option\x20value=\x22\x22>All\x20teams\x20already\x20bound</option>';}}}const _0x115507=state['roles']['filter'](_0x146426=>_0x146426['resource_type']===_0x25f065);_0x36c075['innerHTML']=_0x115507['length']?_0x115507['filter'](_0xe7fb24=>{const _0x220f14=_0x25f065==='server'?undefined:_0x350ff6['value'];return!state['userBindings']['some'](_0x52205c=>_0x52205c['resource_type']===_0x25f065&&_0x52205c['role_id']===_0xe7fb24['id']&&(_0x25f065==='server'||_0x52205c['resource_id']===_0x220f14));})['map'](_0x183416=>'<option\x20value=\x22'+_0x183416['id']+'\x22>'+Utils['escapeHtml'](_0x183416['name'])+'</option>')['join']('')||'<option\x20value=\x22\x22>No\x20available\x20roles</option>':'<option\x20value=\x22\x22>No\x20roles\x20for\x20this\x20resource\x20type</option>';}async function saveUserBinding(){const _0x123ba5=document['getElementById']('user-binding-resource-type')['value'],_0x56e7e1=document['getElementById']('user-binding-role')['value'];if(!_0x56e7e1||!state['bindingsUserId'])return;const _0x5d7c3d=_0x123ba5==='server'?undefined:document['getElementById']('user-binding-resource')['value'];if(_0x123ba5!=='server'&&!_0x5d7c3d)return;const _0x72c6c6=document['getElementById']('save-user-binding-btn');_0x72c6c6['disabled']=!![],_0x72c6c6['textContent']='Adding…';try{const _0x2b8a6={'subject_type':'user','subject_id':state['bindingsUserId'],'role_id':_0x56e7e1,'resource_type':_0x123ba5};if(_0x5d7c3d)_0x2b8a6['resource_id']=_0x5d7c3d;await API['createBinding'](_0x2b8a6),Utils['showToast']('Binding\x20added','success'),state['bindingsDirty']=!![],document['getElementById']('add-user-binding-form')['hidden']=!![],document['getElementById']('add-user-binding-btn')['hidden']=![],await loadUserBindings(state['bindingsUserId']);}catch(_0x263256){Utils['showToast'](_0x263256['message'],'error');}finally{_0x72c6c6['disabled']=![],_0x72c6c6['textContent']='Add\x20Binding';}}window['deleteUserBindingClick']=async function(_0x576f07){try{await API['deleteBinding'](_0x576f07),Utils['showToast']('Binding\x20removed','success'),state['bindingsDirty']=!![],await loadUserBindings(state['bindingsUserId']);}catch(_0x2686c5){Utils['showToast'](_0x2686c5['message'],'error');}};function showCreateUserModal(){state['editingUserId']=null;const _0x1e05af=document['getElementById']('user-modal'),_0x39f7c0=document['getElementById']('modal-title'),_0x833472=document['getElementById']('user-password'),_0x141507=document['getElementById']('password-required'),_0x56ba3b=document['getElementById']('password-hint'),_0x290748=document['getElementById']('skip-password-container'),_0x28bc34=document['getElementById']('skip-password');_0x39f7c0['textContent']='Create\x20User',document['getElementById']('user-form')['reset'](),_0x833472['required']=!![];if(_0x141507)_0x141507['textContent']='*';_0x290748&&(_0x290748['style']['display']='block',_0x28bc34['checked']=![]),_0x56ba3b&&(_0x56ba3b['textContent']='Minimum\x208\x20characters'),_0x1e05af['hidden']=![],setTimeout(()=>{document['getElementById']('user-username')['focus']();},0x64);}window['editUser']=function(_0x3d3b82){const _0x32669f=state['users']['find'](_0x56b556=>_0x56b556['id']===_0x3d3b82);if(!_0x32669f)return;state['editingUserId']=_0x3d3b82;const _0x1258f1=document['getElementById']('user-modal'),_0x643e5f=document['getElementById']('modal-title'),_0x3e8f0a=document['getElementById']('user-password'),_0x507d5b=document['getElementById']('password-required'),_0x4bc282=document['getElementById']('password-hint'),_0x43c0ac=document['getElementById']('skip-password-container');_0x643e5f['textContent']='Edit\x20User',document['getElementById']('user-username')['value']=_0x32669f['username'],document['getElementById']('user-name')['value']=_0x32669f['name'],document['getElementById']('user-email')['value']=_0x32669f['email'],_0x3e8f0a['value']='',_0x3e8f0a['required']=![];if(_0x507d5b)_0x507d5b['textContent']='';_0x43c0ac&&(_0x43c0ac['style']['display']='none'),_0x4bc282&&(_0x4bc282['textContent']='Leave\x20blank\x20to\x20keep\x20current\x20password'),_0x1258f1['hidden']=![],setTimeout(()=>{document['getElementById']('user-username')['focus']();},0x64);};function hideUserModal(){const _0x10f697=document['getElementById']('user-modal'),_0x5366f1=document['getElementById']('form-error'),_0x3e4340=document['getElementById']('save-user');_0x10f697['hidden']=!![],_0x5366f1['hidden']=!![],state['editingUserId']=null,_0x3e4340&&(_0x3e4340['disabled']=![],_0x3e4340['textContent']='Save\x20User');}async function saveUser(){const _0x47d61f=document['getElementById']('user-form'),_0x26672b=document['getElementById']('skip-password')?.['checked']||![];if(!_0x26672b&&!_0x47d61f['checkValidity']()){_0x47d61f['reportValidity']();return;}const _0x56f2fd=document['getElementById']('form-error'),_0x579f2f=document['getElementById']('save-user'),_0x452638=document['getElementById']('user-username')['value']['trim'](),_0x3adc26=document['getElementById']('user-name')['value']['trim'](),_0x50eb52=document['getElementById']('user-email')['value']['trim'](),_0x2a8a30=document['getElementById']('user-password')['value'];if(!_0x452638||!_0x3adc26||!_0x50eb52){_0x56f2fd['textContent']='Please\x20fill\x20in\x20all\x20required\x20fields',_0x56f2fd['hidden']=![],_0x56f2fd['scrollIntoView']({'behavior':'smooth','block':'nearest'});return;}_0x56f2fd['hidden']=!![];const _0x1844b0=_0x579f2f['textContent'];_0x579f2f['disabled']=!![],_0x579f2f['textContent']=state['editingUserId']?'Updating...':'Creating...';try{if(state['editingUserId']){const _0x504f25={'username':_0x452638,'name':_0x3adc26,'email':_0x50eb52};_0x2a8a30&&(_0x504f25['password']=_0x2a8a30),await API['updateUser'](state['editingUserId'],_0x504f25),Utils['showToast']('User\x20updated\x20successfully','success'),await loadUsers(),hideUserModal();}else{const _0x590aa8={'username':_0x452638,'name':_0x3adc26,'email':_0x50eb52};if(!_0x26672b){if(!_0x2a8a30)throw new Error('Password\x20is\x20required\x20for\x20new\x20users');_0x590aa8['password']=_0x2a8a30;}const _0xb0d5ff=await API['createUser'](_0x590aa8),_0x2a9956=_0xb0d5ff['user'];if(_0x26672b||!_0x2a8a30){const _0x1f373b=await API['createPasswordToken'](_0x2a9956['id'],'setup',![]);state['setupLinkData']={'username':_0x2a9956['username'],'email':_0x2a9956['email'],'url':_0x1f373b['token']['setupUrl'],'userId':_0x2a9956['id'],'type':'setup','emailSent':![]},await loadUsers(),hideUserModal(),showSetupLinkModal();}else Utils['showToast']('User\x20created\x20successfully','success'),await loadUsers(),hideUserModal();}}catch(_0x2532af){console['error']('Failed\x20to\x20save\x20user',_0x2532af),_0x56f2fd['textContent']=_0x2532af['message'],_0x56f2fd['hidden']=![],_0x56f2fd['scrollIntoView']({'behavior':'smooth','block':'nearest'}),_0x579f2f['disabled']=![],_0x579f2f['textContent']=_0x1844b0;}}window['deleteUser']=function(_0x29746a){const _0x2c59ff=state['users']['find'](_0x59bf70=>_0x59bf70['id']===_0x29746a);if(!_0x2c59ff)return;state['deletingUserId']=_0x29746a;const _0x4e52f4=document['getElementById']('delete-modal'),_0x36c707=document['getElementById']('delete-user-name');_0x36c707['textContent']=_0x2c59ff['name']+'\x20('+_0x2c59ff['username']+')',_0x4e52f4['hidden']=![];};function hideDeleteModal(){const _0x3ee7cc=document['getElementById']('delete-modal');_0x3ee7cc['hidden']=!![],state['deletingUserId']=null;const _0x11e1af=document['getElementById']('confirm-delete');_0x11e1af&&(_0x11e1af['disabled']=![],_0x11e1af['textContent']='Delete\x20User');}async function confirmDeleteUser(){if(!state['deletingUserId'])return;const _0x24c04d=document['getElementById']('confirm-delete'),_0x459b6e=_0x24c04d['textContent'];_0x24c04d['disabled']=!![],_0x24c04d['textContent']='Deleting...';try{await API['deleteUser'](state['deletingUserId']),Utils['showToast']('User\x20deleted\x20successfully','success'),await loadUsers(),hideDeleteModal();}catch(_0x178b3b){console['error']('Failed\x20to\x20delete\x20user',_0x178b3b),Utils['showToast']('Failed\x20to\x20delete\x20user:\x20'+_0x178b3b['message'],'error'),_0x24c04d['disabled']=![],_0x24c04d['textContent']=_0x459b6e;}}function handleSkipPasswordChange(_0x34c624){const _0x87b23f=document['getElementById']('user-password'),_0x3a901a=_0x34c624['target']['checked'];_0x3a901a?(_0x87b23f['required']=![],_0x87b23f['disabled']=!![],_0x87b23f['value']=''):(_0x87b23f['required']=!![],_0x87b23f['disabled']=![]);}function showSetupLinkModal(){if(!state['setupLinkData'])return;const _0x521531=document['getElementById']('setup-link-modal'),_0x21d200=document['getElementById']('setup-link-username'),_0x9ff544=document['getElementById']('setup-link-url'),_0x52e780=document['getElementById']('email-setup-link'),_0x5507d4=document['getElementById']('email-button-text');_0x21d200['textContent']=state['setupLinkData']['username'],_0x9ff544['textContent']=state['setupLinkData']['url'],_0x52e780&&_0x5507d4&&(_0x52e780['disabled']=![],_0x5507d4['textContent']='Email\x20Link',state['emailConfigured']&&!state['setupLinkData']['emailSent']?_0x52e780['style']['display']='inline-block':_0x52e780['style']['display']='none'),_0x521531['hidden']=![];}function hideSetupLinkModal(){const _0x81522b=document['getElementById']('setup-link-modal');_0x81522b['hidden']=!![],state['setupLinkData']=null;}async function copySetupLink(){if(!state['setupLinkData'])return;try{await navigator['clipboard']['writeText'](state['setupLinkData']['url']),Utils['showToast']('Link\x20copied\x20to\x20clipboard','success');}catch(_0xf70c0e){console['error']('Failed\x20to\x20copy\x20link',_0xf70c0e),Utils['showToast']('Failed\x20to\x20copy\x20link','error');}}async function emailSetupLink(){if(!state['setupLinkData'])return;const _0x550d28=document['getElementById']('email-setup-link'),_0x1f507b=document['getElementById']('email-button-text');if(!_0x550d28||!_0x1f507b)return;const _0x71405e=_0x1f507b['textContent'];_0x550d28['disabled']=!![],_0x1f507b['textContent']='Sending...';try{const _0x517f2a=await API['createPasswordToken'](state['setupLinkData']['userId'],state['setupLinkData']['type'],!![]);if(_0x517f2a['emailSent'])Utils['showToast']('Email\x20sent\x20to\x20'+state['setupLinkData']['email'],'success'),state['setupLinkData']['emailSent']=!![],_0x550d28['style']['display']='none';else{const _0x48fc5f=_0x517f2a['emailError']||'Failed\x20to\x20send\x20email';Utils['showToast'](_0x48fc5f,'error'),_0x550d28['disabled']=![],_0x1f507b['textContent']=_0x71405e;}}catch(_0x2cbb69){console['error']('Failed\x20to\x20email\x20setup\x20link',_0x2cbb69),Utils['showToast']('Failed\x20to\x20send\x20email:\x20'+_0x2cbb69['message'],'error'),_0x550d28['disabled']=![],_0x1f507b['textContent']=_0x71405e;}}window['resetPassword']=async function(_0x364541){const _0x5116bf=state['users']['find'](_0x4ab6b8=>_0x4ab6b8['id']===_0x364541);if(!_0x5116bf)return;const _0xbbd5f6=await ConfirmDialog['show']({'title':'Reset\x20Password','message':'Generate\x20a\x20password\x20reset\x20link\x20for\x20'+_0x5116bf['name']+'\x20('+_0x5116bf['username']+')?\x20This\x20will\x20create\x20a\x20link\x20that\x20they\x20can\x20use\x20to\x20set\x20a\x20new\x20password.','confirmText':'Generate\x20Link'});if(!_0xbbd5f6)return;try{const _0xd1bbcb=await API['createPasswordToken'](_0x364541,'reset',![]);state['setupLinkData']={'username':_0x5116bf['username'],'email':_0x5116bf['email'],'url':_0xd1bbcb['token']['setupUrl'],'userId':_0x5116bf['id'],'type':'reset','emailSent':![]},showSetupLinkModal();}catch(_0x36437f){console['error']('Failed\x20to\x20create\x20password\x20reset\x20link',_0x36437f),Utils['showToast']('Failed\x20to\x20create\x20password\x20reset\x20link:\x20'+_0x36437f['message'],'error');}};
|
|
1
|
+
import{API,Utils,ConfirmDialog,initializeAdminMenu}from'./app.js';import{initTheme,mountThemeToggle}from'./theme.js';const state={'users':[],'editingUserId':null,'bindingsUserId':null,'deletingUserId':null,'setupLinkData':null,'emailConfigured':![],'currentUser':null,'roles':[],'environments':[],'teams':[],'userBindings':[],'bindingsDirty':![]};document['addEventListener']('DOMContentLoaded',async()=>{initTheme(),mountThemeToggle(),await checkAdminAccess(),await initializeAdminMenu(state['currentUser']),await Promise['all']([checkEmailConfig(),loadRoles(),loadEnvironments(),loadTeams()]),bindEventListeners(),await loadUsers();});async function checkAdminAccess(){try{const _0x613256=await API['getCurrentUser']();state['currentUser']=_0x613256;if(!Permissions['hasServerPermission'](_0x613256,'*')&&!Permissions['hasServerPermission'](_0x613256,'users:create')){Utils['showToast']('Access\x20denied:\x20Server\x20admin\x20privileges\x20required','error'),setTimeout(()=>{window['location']['href']='index.html';},0x7d0);return;}}catch(_0x192e5b){window['location']['href']='login.html';}}async function checkEmailConfig(){try{const _0x31b73c=await API['getEmailConfig']();state['emailConfigured']=_0x31b73c['configured'];}catch(_0x33db98){console['error']('Failed\x20to\x20check\x20email\x20config',_0x33db98),state['emailConfigured']=![];}}async function loadRoles(){try{const {roles:_0x41566c}=await API['getRoleDefinitions']();state['roles']=_0x41566c||[];}catch{state['roles']=[];}}async function loadEnvironments(){try{const _0x2284f0=await API['getEnvironments']();state['environments']=_0x2284f0['environments']||[];}catch{state['environments']=[];}}async function loadTeams(){try{const {teams:_0x367f05}=await API['getTeams']();state['teams']=_0x367f05||[];}catch{state['teams']=[];}}function bindEventListeners(){document['getElementById']('create-user-btn')?.['addEventListener']('click',showCreateUserModal),document['getElementById']('close-user-modal')?.['addEventListener']('click',hideUserModal),document['getElementById']('cancel-user')?.['addEventListener']('click',hideUserModal),document['getElementById']('save-user')?.['addEventListener']('click',saveUser),document['querySelector']('#user-modal\x20.modal-overlay')?.['addEventListener']('click',hideUserModal),document['getElementById']('close-delete-modal')?.['addEventListener']('click',hideDeleteModal),document['getElementById']('cancel-delete')?.['addEventListener']('click',hideDeleteModal),document['getElementById']('confirm-delete')?.['addEventListener']('click',confirmDeleteUser),document['querySelector']('#delete-modal\x20.modal-overlay')?.['addEventListener']('click',hideDeleteModal),document['getElementById']('close-setup-link-modal')?.['addEventListener']('click',hideSetupLinkModal),document['getElementById']('close-setup-link')?.['addEventListener']('click',hideSetupLinkModal),document['getElementById']('copy-setup-link')?.['addEventListener']('click',copySetupLink),document['getElementById']('email-setup-link')?.['addEventListener']('click',emailSetupLink),document['querySelector']('#setup-link-modal\x20.modal-overlay')?.['addEventListener']('click',hideSetupLinkModal),document['getElementById']('skip-password')?.['addEventListener']('change',handleSkipPasswordChange),document['getElementById']('retry-users-btn')?.['addEventListener']('click',loadUsers),document['getElementById']('close-bindings-modal')?.['addEventListener']('click',hideAccessBindingsModal),document['getElementById']('close-bindings-modal-footer')?.['addEventListener']('click',hideAccessBindingsModal),document['querySelector']('#bindings-modal\x20.modal-overlay')?.['addEventListener']('click',hideAccessBindingsModal),document['getElementById']('add-user-binding-btn')?.['addEventListener']('click',()=>{document['getElementById']('add-user-binding-form')['hidden']=![],document['getElementById']('add-user-binding-btn')['hidden']=!![],populateUserBindingForm();}),document['getElementById']('cancel-user-binding-btn')?.['addEventListener']('click',()=>{document['getElementById']('add-user-binding-form')['hidden']=!![],document['getElementById']('add-user-binding-btn')['hidden']=![];}),document['getElementById']('save-user-binding-btn')?.['addEventListener']('click',saveUserBinding),document['getElementById']('user-binding-resource-type')?.['addEventListener']('change',onUserBindingResourceTypeChange);}async function loadUsers(){const _0x3d8a2e=document['getElementById']('users-loading'),_0x2c68aa=document['getElementById']('users-error'),_0x5669ac=document['getElementById']('users-content');try{_0x3d8a2e['hidden']=![],_0x2c68aa['hidden']=!![],_0x5669ac['hidden']=!![];const _0x454124=await API['getUsers']();state['users']=_0x454124['users']||[],renderUsers(),_0x3d8a2e['hidden']=!![],_0x5669ac['hidden']=![];}catch(_0x207180){console['error']('Failed\x20to\x20load\x20users',_0x207180),_0x3d8a2e['hidden']=!![],_0x2c68aa['hidden']=![],document['getElementById']('users-error-message')['textContent']=_0x207180['message'];}}function renderUsers(){const _0x54aa6f=document['getElementById']('users-table-body'),_0x11f089=document['getElementById']('user-count');if(!_0x54aa6f)return;_0x11f089&&(_0x11f089['textContent']=state['users']['length']+'\x20user'+(state['users']['length']===0x1?'':'s'));const _0x27dfb2=[...state['users']]['sort']((_0x5eeb30,_0x12c758)=>{const _0x8d028f=new Date(_0x5eeb30['created_at'])['getTime'](),_0x3ad3d5=new Date(_0x12c758['created_at'])['getTime']();return _0x3ad3d5-_0x8d028f;});_0x54aa6f['innerHTML']=_0x27dfb2['map'](_0x3881ce=>'\x0a\x20\x20\x20\x20<tr>\x0a\x20\x20\x20\x20\x20\x20<td>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<div\x20class=\x22user-username\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20'+Utils['escapeHtml'](_0x3881ce['username'])+'\x0a\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20</td>\x0a\x20\x20\x20\x20\x20\x20<td>'+Utils['escapeHtml'](_0x3881ce['name'])+'</td>\x0a\x20\x20\x20\x20\x20\x20<td>'+Utils['escapeHtml'](_0x3881ce['email'])+'</td>\x0a\x20\x20\x20\x20\x20\x20<td>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<div\x20class=\x22access-badges\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20'+(_0x3881ce['isServerAdmin']?'<span\x20class=\x22role-badge\x20role-admin\x22>Server\x20Admin</span>':'')+'\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20'+(_0x3881ce['hasUserBinding']?'<span\x20class=\x22role-badge\x20role-user-binding\x22>User\x20Binding</span>':'')+'\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20'+(_0x3881ce['hasTeamBinding']?'<span\x20class=\x22role-badge\x20role-team-binding\x22>Team\x20Binding</span>':'')+'\x0a\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20</td>\x0a\x20\x20\x20\x20\x20\x20<td>'+Utils['formatRelativeTime'](_0x3881ce['created_at'])+'</td>\x0a\x20\x20\x20\x20\x20\x20<td>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<div\x20class=\x22user-actions\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<button\x20class=\x22btn-icon\x20btn-small\x22\x20onclick=\x22window.editUser(\x27'+_0x3881ce['id']+'\x27)\x22\x20title=\x22Edit\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<svg\x20width=\x2214\x22\x20height=\x2214\x22\x20viewBox=\x220\x200\x2024\x2024\x22\x20fill=\x22none\x22\x20stroke=\x22currentColor\x22\x20stroke-width=\x222\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<path\x20d=\x22M11\x204H4a2\x202\x200\x200\x200-2\x202v14a2\x202\x200\x200\x200\x202\x202h14a2\x202\x200\x200\x200\x202-2v-7\x22></path>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<path\x20d=\x22M18.5\x202.5a2.121\x202.121\x200\x200\x201\x203\x203L12\x2015l-4\x201\x201-4\x209.5-9.5z\x22></path>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</svg>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</button>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<button\x20class=\x22btn-icon\x20btn-small\x22\x20onclick=\x22window.showAccessBindings(\x27'+_0x3881ce['id']+'\x27)\x22\x20title=\x22Access\x20Bindings\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<svg\x20width=\x2214\x22\x20height=\x2214\x22\x20viewBox=\x220\x200\x2024\x2024\x22\x20fill=\x22none\x22\x20stroke=\x22currentColor\x22\x20stroke-width=\x222\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<path\x20d=\x22M12\x2022s8-4\x208-10V5l-8-3-8\x203v7c0\x206\x208\x2010\x208\x2010z\x22></path>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</svg>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</button>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<button\x20class=\x22btn-icon\x20btn-small\x20btn-danger\x22\x20onclick=\x22window.deleteUser(\x27'+_0x3881ce['id']+'\x27)\x22\x20title=\x22Delete\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<svg\x20width=\x2214\x22\x20height=\x2214\x22\x20viewBox=\x220\x200\x2024\x2024\x22\x20fill=\x22none\x22\x20stroke=\x22currentColor\x22\x20stroke-width=\x222\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<polyline\x20points=\x223\x206\x205\x206\x2021\x206\x22></polyline>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<path\x20d=\x22M19\x206v14a2\x202\x200\x200\x201-2\x202H7a2\x202\x200\x200\x201-2-2V6m3\x200V4a2\x202\x200\x200\x201\x202-2h4a2\x202\x200\x200\x201\x202\x202v2\x22></path>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</svg>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</button>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<button\x20class=\x22btn-secondary\x20btn-small\x22\x20onclick=\x22window.resetPassword(\x27'+_0x3881ce['id']+'\x27)\x22>Reset\x20Password</button>\x0a\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20</td>\x0a\x20\x20\x20\x20</tr>\x0a\x20\x20')['join']('');}window['showAccessBindings']=function(_0x21e62a){const _0x28ba57=state['users']['find'](_0x57d734=>_0x57d734['id']===_0x21e62a);if(!_0x28ba57)return;state['bindingsUserId']=_0x21e62a,state['bindingsDirty']=![];const _0x3e9aa7=document['getElementById']('bindings-modal'),_0x12f9b0=document['getElementById']('bindings-modal-title');_0x12f9b0['textContent']='Access\x20Bindings\x20—\x20'+_0x28ba57['name'],document['getElementById']('add-user-binding-form')['hidden']=!![],document['getElementById']('add-user-binding-btn')['hidden']=![],_0x3e9aa7['hidden']=![],loadUserBindings(_0x21e62a);};function hasUnsavedBindingChanges(){const _0x31e849=document['getElementById']('add-user-binding-form');return _0x31e849&&!_0x31e849['hidden'];}async function hideAccessBindingsModal(){if(hasUnsavedBindingChanges()){if(!confirm('You\x20have\x20an\x20unsaved\x20binding.\x20Discard\x20changes?'))return;document['getElementById']('add-user-binding-form')['hidden']=!![],document['getElementById']('add-user-binding-btn')['hidden']=![];}const _0x7ccc00=document['getElementById']('bindings-modal');_0x7ccc00['hidden']=!![];const _0x2ea47=state['bindingsDirty'];state['bindingsUserId']=null,state['userBindings']=[],state['bindingsDirty']=![],_0x2ea47&&await loadUsers();}async function loadUserBindings(_0x51dbe4){const _0x9119fc=document['getElementById']('user-bindings-loading'),_0x3d332d=document['getElementById']('user-bindings-empty'),_0x268e3c=document['getElementById']('user-bindings-list-container'),_0x5ab7fc=document['getElementById']('add-user-binding-btn'),_0x46d580=document['getElementById']('user-team-bindings-note'),_0x32a131=document['getElementById']('user-team-bindings-text');_0x9119fc['hidden']=![],_0x3d332d['hidden']=!![],_0x268e3c['style']['display']='none',_0x5ab7fc['hidden']=!![],_0x46d580['hidden']=!![],document['getElementById']('add-user-binding-form')['hidden']=!![];try{const [_0x403084,_0x189af9]=await Promise['all']([API['getBindings']({'subject_type':'user','subject_id':_0x51dbe4}),API['getTeams']()]);state['userBindings']=_0x403084['bindings']||[];const _0x7751cd=(_0x189af9['teams']||[])['filter'](_0x2a15f6=>(_0x2a15f6['members']||[])['includes'](_0x51dbe4)),_0x48d367=[];if(_0x7751cd['length']>0x0){const _0x2d9b9f=await Promise['all'](_0x7751cd['map'](_0x5da131=>API['getBindings']({'subject_type':'team','subject_id':_0x5da131['id']})));for(let _0x15f4e4=0x0;_0x15f4e4<_0x7751cd['length'];_0x15f4e4++){const _0x335c2b=_0x2d9b9f[_0x15f4e4]['bindings']||[];_0x335c2b['length']>0x0&&_0x48d367['push'](_0x7751cd[_0x15f4e4]);}}_0x9119fc['hidden']=!![];state['userBindings']['length']===0x0?_0x3d332d['hidden']=![]:(_0x268e3c['style']['display']='',renderUserBindingsTable());if(_0x48d367['length']>0x0){const _0xa7cedd=_0x48d367['map'](_0x323bcc=>_0x323bcc['name']),_0x251aa5=_0xa7cedd['length']<=0x3?_0xa7cedd['join'](',\x20'):_0xa7cedd['slice'](0x0,0x3)['join'](',\x20')+(',\x20and\x20'+(_0xa7cedd['length']-0x3)+'\x20more');_0x32a131['textContent']='This\x20user\x20also\x20has\x20access\x20via\x20team\x20memberships\x20('+_0x251aa5+').';}else _0x32a131['textContent']='This\x20user\x20has\x20no\x20access\x20via\x20team\x20memberships.';_0x46d580['hidden']=![],_0x5ab7fc['hidden']=![];}catch(_0x2b08e9){_0x9119fc['hidden']=!![],Utils['showToast']('Failed\x20to\x20load\x20bindings:\x20'+_0x2b08e9['message'],'error');}}function renderUserBindingsTable(){const _0x5b48c8=document['getElementById']('user-bindings-table-body');if(!_0x5b48c8)return;_0x5b48c8['innerHTML']=state['userBindings']['map'](_0x35cb4e=>{const _0x2a565b=_0x35cb4e['resource_type']==='server'?'Server':_0x35cb4e['resource_id']==='*'?'All\x20'+_0x35cb4e['resource_type']+'s':Utils['escapeHtml'](_0x35cb4e['resource_id']||'');return'\x0a\x20\x20\x20\x20<tr>\x0a\x20\x20\x20\x20\x20\x20<td>'+_0x2a565b+'</td>\x0a\x20\x20\x20\x20\x20\x20<td>'+Utils['escapeHtml'](_0x35cb4e['role_name']||_0x35cb4e['role_id'])+'</td>\x0a\x20\x20\x20\x20\x20\x20<td>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<button\x20class=\x22btn-ghost\x20btn-small\x22\x20onclick=\x22window.deleteUserBindingClick(\x27'+_0x35cb4e['id']+'\x27)\x22\x20style=\x22color:\x20var(--color-danger);\x22>Remove</button>\x0a\x20\x20\x20\x20\x20\x20</td>\x0a\x20\x20\x20\x20</tr>';})['join']('');}function populateUserBindingForm(){const _0x2c02dc=document['getElementById']('user-binding-resource-type');_0x2c02dc['value']='environment',updateUserBindingFormForResourceType('environment');}function onUserBindingResourceTypeChange(){const _0x178aee=document['getElementById']('user-binding-resource-type')['value'];updateUserBindingFormForResourceType(_0x178aee);}function updateUserBindingFormForResourceType(_0x9f8e9f){const _0x4f03e3=document['getElementById']('user-binding-resource-container'),_0x5ce406=document['getElementById']('user-binding-resource'),_0x4c8104=document['getElementById']('user-binding-role');if(_0x9f8e9f==='server')_0x4f03e3['style']['display']='none';else{_0x4f03e3['style']['display']='';if(_0x9f8e9f==='environment'){const _0x1f0552=new Set(state['userBindings']['filter'](_0x41b283=>_0x41b283['resource_type']==='environment')['map'](_0x58dd0c=>_0x58dd0c['resource_id'])),_0x143a9a=state['environments']['filter'](_0xc1cfe4=>!_0x1f0552['has'](_0xc1cfe4['name']));_0x5ce406['innerHTML']=_0x143a9a['length']?_0x143a9a['map'](_0x3e98a7=>'<option\x20value=\x22'+Utils['escapeHtml'](_0x3e98a7['name'])+'\x22>'+Utils['escapeHtml'](_0x3e98a7['name'])+'</option>')['join'](''):'<option\x20value=\x22\x22>All\x20environments\x20already\x20bound</option>';}else{if(_0x9f8e9f==='team'){const _0x1c9c5e=new Set(state['userBindings']['filter'](_0x122953=>_0x122953['resource_type']==='team')['map'](_0x1ac330=>_0x1ac330['resource_id'])),_0x498d44=state['teams']['filter'](_0x4e315c=>!_0x1c9c5e['has'](_0x4e315c['id']));_0x5ce406['innerHTML']=_0x498d44['length']?_0x498d44['map'](_0x5eb788=>'<option\x20value=\x22'+_0x5eb788['id']+'\x22>'+Utils['escapeHtml'](_0x5eb788['name'])+'</option>')['join'](''):'<option\x20value=\x22\x22>All\x20teams\x20already\x20bound</option>';}}}const _0x452991=state['roles']['filter'](_0x1adf24=>_0x1adf24['resource_type']===_0x9f8e9f);_0x4c8104['innerHTML']=_0x452991['length']?_0x452991['filter'](_0x3a09d7=>{const _0x16e7f0=_0x9f8e9f==='server'?undefined:_0x5ce406['value'];return!state['userBindings']['some'](_0x524c3d=>_0x524c3d['resource_type']===_0x9f8e9f&&_0x524c3d['role_id']===_0x3a09d7['id']&&(_0x9f8e9f==='server'||_0x524c3d['resource_id']===_0x16e7f0));})['map'](_0x234e5e=>'<option\x20value=\x22'+_0x234e5e['id']+'\x22>'+Utils['escapeHtml'](_0x234e5e['name'])+'</option>')['join']('')||'<option\x20value=\x22\x22>No\x20available\x20roles</option>':'<option\x20value=\x22\x22>No\x20roles\x20for\x20this\x20resource\x20type</option>';}async function saveUserBinding(){const _0x189a06=document['getElementById']('user-binding-resource-type')['value'],_0x52a90d=document['getElementById']('user-binding-role')['value'];if(!_0x52a90d||!state['bindingsUserId'])return;const _0x1a1406=_0x189a06==='server'?undefined:document['getElementById']('user-binding-resource')['value'];if(_0x189a06!=='server'&&!_0x1a1406)return;const _0x4ec109=document['getElementById']('save-user-binding-btn');_0x4ec109['disabled']=!![],_0x4ec109['textContent']='Adding…';try{const _0x26b301={'subject_type':'user','subject_id':state['bindingsUserId'],'role_id':_0x52a90d,'resource_type':_0x189a06};if(_0x1a1406)_0x26b301['resource_id']=_0x1a1406;await API['createBinding'](_0x26b301),Utils['showToast']('Binding\x20added','success'),state['bindingsDirty']=!![],document['getElementById']('add-user-binding-form')['hidden']=!![],document['getElementById']('add-user-binding-btn')['hidden']=![],await loadUserBindings(state['bindingsUserId']);}catch(_0x3a3017){Utils['showToast'](_0x3a3017['message'],'error');}finally{_0x4ec109['disabled']=![],_0x4ec109['textContent']='Add\x20Binding';}}window['deleteUserBindingClick']=async function(_0x591a0d){try{await API['deleteBinding'](_0x591a0d),Utils['showToast']('Binding\x20removed','success'),state['bindingsDirty']=!![],await loadUserBindings(state['bindingsUserId']);}catch(_0x5d293b){Utils['showToast'](_0x5d293b['message'],'error');}};function showCreateUserModal(){state['editingUserId']=null;const _0x3ed8d9=document['getElementById']('user-modal'),_0x885f10=document['getElementById']('modal-title'),_0x48fd5a=document['getElementById']('user-password'),_0x3f8eb1=document['getElementById']('password-required'),_0x42f79f=document['getElementById']('password-hint'),_0x403e3c=document['getElementById']('skip-password-container'),_0xad9724=document['getElementById']('skip-password');_0x885f10['textContent']='Create\x20User',document['getElementById']('user-form')['reset'](),_0x48fd5a['required']=!![];if(_0x3f8eb1)_0x3f8eb1['textContent']='*';_0x403e3c&&(_0x403e3c['style']['display']='block',_0xad9724['checked']=![]),_0x42f79f&&(_0x42f79f['textContent']='Minimum\x208\x20characters'),_0x3ed8d9['hidden']=![],setTimeout(()=>{document['getElementById']('user-username')['focus']();},0x64);}window['editUser']=function(_0x365166){const _0x362c1f=state['users']['find'](_0x277341=>_0x277341['id']===_0x365166);if(!_0x362c1f)return;state['editingUserId']=_0x365166;const _0x2ce4e9=document['getElementById']('user-modal'),_0x122295=document['getElementById']('modal-title'),_0x242fde=document['getElementById']('user-password'),_0x3aa22f=document['getElementById']('password-required'),_0x331241=document['getElementById']('password-hint'),_0x3bb1cf=document['getElementById']('skip-password-container');_0x122295['textContent']='Edit\x20User',document['getElementById']('user-username')['value']=_0x362c1f['username'],document['getElementById']('user-name')['value']=_0x362c1f['name'],document['getElementById']('user-email')['value']=_0x362c1f['email'],_0x242fde['value']='',_0x242fde['required']=![];if(_0x3aa22f)_0x3aa22f['textContent']='';_0x3bb1cf&&(_0x3bb1cf['style']['display']='none'),_0x331241&&(_0x331241['textContent']='Leave\x20blank\x20to\x20keep\x20current\x20password'),_0x2ce4e9['hidden']=![],setTimeout(()=>{document['getElementById']('user-username')['focus']();},0x64);};function hideUserModal(){const _0x3153ee=document['getElementById']('user-modal'),_0x4b38d2=document['getElementById']('form-error'),_0x55fd26=document['getElementById']('save-user');_0x3153ee['hidden']=!![],_0x4b38d2['hidden']=!![],state['editingUserId']=null,_0x55fd26&&(_0x55fd26['disabled']=![],_0x55fd26['textContent']='Save\x20User');}async function saveUser(){const _0x501a35=document['getElementById']('user-form'),_0x8f0753=document['getElementById']('skip-password')?.['checked']||![];if(!_0x8f0753&&!_0x501a35['checkValidity']()){_0x501a35['reportValidity']();return;}const _0x20b735=document['getElementById']('form-error'),_0x382c80=document['getElementById']('save-user'),_0x51a8b1=document['getElementById']('user-username')['value']['trim'](),_0x345a7b=document['getElementById']('user-name')['value']['trim'](),_0x36a610=document['getElementById']('user-email')['value']['trim'](),_0x45e553=document['getElementById']('user-password')['value'];if(!_0x51a8b1||!_0x345a7b||!_0x36a610){_0x20b735['textContent']='Please\x20fill\x20in\x20all\x20required\x20fields',_0x20b735['hidden']=![],_0x20b735['scrollIntoView']({'behavior':'smooth','block':'nearest'});return;}_0x20b735['hidden']=!![];const _0x28e6dd=_0x382c80['textContent'];_0x382c80['disabled']=!![],_0x382c80['textContent']=state['editingUserId']?'Updating...':'Creating...';try{if(state['editingUserId']){const _0x573efd={'username':_0x51a8b1,'name':_0x345a7b,'email':_0x36a610};_0x45e553&&(_0x573efd['password']=_0x45e553),await API['updateUser'](state['editingUserId'],_0x573efd),Utils['showToast']('User\x20updated\x20successfully','success'),await loadUsers(),hideUserModal();}else{const _0x3b9a57={'username':_0x51a8b1,'name':_0x345a7b,'email':_0x36a610};if(!_0x8f0753){if(!_0x45e553)throw new Error('Password\x20is\x20required\x20for\x20new\x20users');_0x3b9a57['password']=_0x45e553;}const _0x5a98bd=await API['createUser'](_0x3b9a57),_0x10a220=_0x5a98bd['user'];if(_0x8f0753||!_0x45e553){const _0x4afb88=await API['createPasswordToken'](_0x10a220['id'],'setup',![]);state['setupLinkData']={'username':_0x10a220['username'],'email':_0x10a220['email'],'url':_0x4afb88['token']['setupUrl'],'userId':_0x10a220['id'],'type':'setup','emailSent':![]},await loadUsers(),hideUserModal(),showSetupLinkModal();}else Utils['showToast']('User\x20created\x20successfully','success'),await loadUsers(),hideUserModal();}}catch(_0x28934e){console['error']('Failed\x20to\x20save\x20user',_0x28934e),_0x20b735['textContent']=_0x28934e['message'],_0x20b735['hidden']=![],_0x20b735['scrollIntoView']({'behavior':'smooth','block':'nearest'}),_0x382c80['disabled']=![],_0x382c80['textContent']=_0x28e6dd;}}window['deleteUser']=function(_0x17f48a){const _0x417284=state['users']['find'](_0x4f4629=>_0x4f4629['id']===_0x17f48a);if(!_0x417284)return;state['deletingUserId']=_0x17f48a;const _0x38aed9=document['getElementById']('delete-modal'),_0x420860=document['getElementById']('delete-user-name');_0x420860['textContent']=_0x417284['name']+'\x20('+_0x417284['username']+')',_0x38aed9['hidden']=![];};function hideDeleteModal(){const _0x57577e=document['getElementById']('delete-modal');_0x57577e['hidden']=!![],state['deletingUserId']=null;const _0x24f57d=document['getElementById']('confirm-delete');_0x24f57d&&(_0x24f57d['disabled']=![],_0x24f57d['textContent']='Delete\x20User');}async function confirmDeleteUser(){if(!state['deletingUserId'])return;const _0x12c1d1=document['getElementById']('confirm-delete'),_0x3bde91=_0x12c1d1['textContent'];_0x12c1d1['disabled']=!![],_0x12c1d1['textContent']='Deleting...';try{await API['deleteUser'](state['deletingUserId']),Utils['showToast']('User\x20deleted\x20successfully','success'),await loadUsers(),hideDeleteModal();}catch(_0x26ed26){console['error']('Failed\x20to\x20delete\x20user',_0x26ed26),Utils['showToast']('Failed\x20to\x20delete\x20user:\x20'+_0x26ed26['message'],'error'),_0x12c1d1['disabled']=![],_0x12c1d1['textContent']=_0x3bde91;}}function handleSkipPasswordChange(_0xbfe1c5){const _0x127232=document['getElementById']('user-password'),_0x547d8a=_0xbfe1c5['target']['checked'];_0x547d8a?(_0x127232['required']=![],_0x127232['disabled']=!![],_0x127232['value']=''):(_0x127232['required']=!![],_0x127232['disabled']=![]);}function showSetupLinkModal(){if(!state['setupLinkData'])return;const _0x158992=document['getElementById']('setup-link-modal'),_0x1b285a=document['getElementById']('setup-link-username'),_0x347778=document['getElementById']('setup-link-url'),_0x3756bf=document['getElementById']('email-setup-link'),_0x5949c6=document['getElementById']('email-button-text');_0x1b285a['textContent']=state['setupLinkData']['username'],_0x347778['textContent']=state['setupLinkData']['url'],_0x3756bf&&_0x5949c6&&(_0x3756bf['disabled']=![],_0x5949c6['textContent']='Email\x20Link',state['emailConfigured']&&!state['setupLinkData']['emailSent']?_0x3756bf['style']['display']='inline-block':_0x3756bf['style']['display']='none'),_0x158992['hidden']=![];}function hideSetupLinkModal(){const _0x588d9a=document['getElementById']('setup-link-modal');_0x588d9a['hidden']=!![],state['setupLinkData']=null;}async function copySetupLink(){if(!state['setupLinkData'])return;try{await navigator['clipboard']['writeText'](state['setupLinkData']['url']),Utils['showToast']('Link\x20copied\x20to\x20clipboard','success');}catch(_0x316a4a){console['error']('Failed\x20to\x20copy\x20link',_0x316a4a),Utils['showToast']('Failed\x20to\x20copy\x20link','error');}}async function emailSetupLink(){if(!state['setupLinkData'])return;const _0x45d5ea=document['getElementById']('email-setup-link'),_0xcbb2d2=document['getElementById']('email-button-text');if(!_0x45d5ea||!_0xcbb2d2)return;const _0x34829f=_0xcbb2d2['textContent'];_0x45d5ea['disabled']=!![],_0xcbb2d2['textContent']='Sending...';try{const _0x1cd071=await API['createPasswordToken'](state['setupLinkData']['userId'],state['setupLinkData']['type'],!![]);if(_0x1cd071['emailSent'])Utils['showToast']('Email\x20sent\x20to\x20'+state['setupLinkData']['email'],'success'),state['setupLinkData']['emailSent']=!![],_0x45d5ea['style']['display']='none';else{const _0x2ced63=_0x1cd071['emailError']||'Failed\x20to\x20send\x20email';Utils['showToast'](_0x2ced63,'error'),_0x45d5ea['disabled']=![],_0xcbb2d2['textContent']=_0x34829f;}}catch(_0x465ba9){console['error']('Failed\x20to\x20email\x20setup\x20link',_0x465ba9),Utils['showToast']('Failed\x20to\x20send\x20email:\x20'+_0x465ba9['message'],'error'),_0x45d5ea['disabled']=![],_0xcbb2d2['textContent']=_0x34829f;}}window['resetPassword']=async function(_0x283030){const _0x578e12=state['users']['find'](_0x4c236=>_0x4c236['id']===_0x283030);if(!_0x578e12)return;const _0x336037=await ConfirmDialog['show']({'title':'Reset\x20Password','message':'Generate\x20a\x20password\x20reset\x20link\x20for\x20'+_0x578e12['name']+'\x20('+_0x578e12['username']+')?\x20This\x20will\x20create\x20a\x20link\x20that\x20they\x20can\x20use\x20to\x20set\x20a\x20new\x20password.','confirmText':'Generate\x20Link'});if(!_0x336037)return;try{const _0x39f962=await API['createPasswordToken'](_0x283030,'reset',![]);state['setupLinkData']={'username':_0x578e12['username'],'email':_0x578e12['email'],'url':_0x39f962['token']['setupUrl'],'userId':_0x578e12['id'],'type':'reset','emailSent':![]},showSetupLinkModal();}catch(_0x3edb85){console['error']('Failed\x20to\x20create\x20password\x20reset\x20link',_0x3edb85),Utils['showToast']('Failed\x20to\x20create\x20password\x20reset\x20link:\x20'+_0x3edb85['message'],'error');}};
|