Azure AD returns mixed-case usernames (VadymSamoilenko) but
superadmin was created with lowercase. Use LOWER() for matching.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- deploy.sh copies static/ to /var/www/html/solventum-image-metadata/
- Apache Alias serves CSS/JS directly from disk
- ProxyPass exclusion prevents static requests going to Docker
- Updated apache config with full working example
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Microsoft CDN URL was unreachable. Using jsdelivr with
@azure/msal-browser@3.27.0 instead.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Define initMsal() first, then load CDN script with onload="initMsal()".
Prevents 'msal is not defined' race condition.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
MSAL.js 2.x requires await initialize() before loginPopup().
Also added openid/profile/email scopes and loading state guard.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Frontend MSAL.js handles Azure AD popup login
- Backend validates access token via Graph API
- Removed server-side MSAL redirect flow (get_auth_url, acquire_token)
- MicrosoftSSO class simplified: only needs Graph API validation
- No AZURE_CLIENT_SECRET required
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Support both ConfidentialClientApplication (with secret) and
PublicClientApplication (without secret). SSO now only requires
AZURE_CLIENT_ID and AZURE_TENANT_ID.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
git pull runs as current user (needs SSH key), docker commands
use sudo automatically if the user doesn't have docker socket access.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>