diff --git a/browser-extensions/chrome/src/App.tsx b/browser-extensions/chrome/src/App.tsx index 7c5963e1b..54bca9503 100644 --- a/browser-extensions/chrome/src/App.tsx +++ b/browser-extensions/chrome/src/App.tsx @@ -23,6 +23,7 @@ const App: React.FC = () => { const [showSettings, setShowSettings] = useState(false); const [isUserMenuOpen, setIsUserMenuOpen] = useState(false); const [isInlineUnlockMode, setIsInlineUnlockMode] = useState(false); + const [clientUrl, setClientUrl] = useState('https://app.aliasvault.net'); const menuRef = useRef(null); const buttonRef = useRef(null); @@ -40,6 +41,7 @@ const App: React.FC = () => { } else { setNeedsUnlock(true); } + updateClientUrl(); }, [authContext.isLoggedIn, dbContext.dbInitialized, dbContext.dbAvailable, authContext.isInitialized]); /** @@ -77,6 +79,20 @@ const App: React.FC = () => { setIsInlineUnlockMode(queryParams.get('mode') === 'inline_unlock'); }, []); + /** + * Retrieve client URL from storage and update the state. + */ + const updateClientUrl = async () : Promise => { + const result = await chrome.storage.local.get(['clientUrl']); + const savedUrl = result.clientUrl; + if (savedUrl && savedUrl !== '') { + setClientUrl(savedUrl); + } + else { + setClientUrl('https://app.aliasvault.net'); + } + }; + /** * Handle logout. */ @@ -123,6 +139,7 @@ const App: React.FC = () => { */ const toggleSettings = () : void => { setShowSettings(!showSettings); + updateClientUrl(); }; /** @@ -132,8 +149,10 @@ const App: React.FC = () => { setIsUserMenuOpen(!isUserMenuOpen); }; - // Add UnlockSuccess component - const UnlockSuccess = () => ( + /** + * Unlock success component. + */ + const UnlockSuccess = (
@@ -171,50 +190,50 @@ const App: React.FC = () => { const userMenu = authContext.isLoggedIn && !needsUnlock ? (
-
- - -
- - Loading...
- -
- - - {isUserMenuOpen && ( -
-
- - {authContext.username} - -
- + +
+ + Loading...
+ +
+ + + {isUserMenuOpen && ( +
+
+ + {authContext.username} + +
+ +
+ )}
- )}
-
) : null; if (isLoading) { @@ -225,6 +244,15 @@ const App: React.FC = () => {
AliasVault

AliasVault

+
@@ -242,7 +270,7 @@ const App: React.FC = () => {
{!authContext.isLoggedIn ? ( <> - + ) : ( userMenu diff --git a/browser-extensions/chrome/src/contentScript.ts b/browser-extensions/chrome/src/contentScript.ts index 05976d164..56b24c82a 100644 --- a/browser-extensions/chrome/src/contentScript.ts +++ b/browser-extensions/chrome/src/contentScript.ts @@ -8,12 +8,16 @@ type CredentialResponse = { const placeholderBase64 = 'UklGRjoEAABXRUJQVlA4IC4EAAAwFwCdASqAAIAAPpFCm0olo6Ihp5IraLASCWUA0eb/0s56RrLtCnYfLPiBshdXWMx8j1Ez65f169iA4xUDBTEV6ylMQeCIj2b7RngGi7gKZ9WjKdSoy9R8JcgOmjCMlDmLG20KhNo/i/Dc/Ah5GAvGfm8kfniV3AkR6fxN6eKwjDc6xrDgSfS48G5uGV6WzQt24YAVlLSK9BMwndzfHnePK1KFchFrL7O3ulB8cGNCeomu4o+l0SrS/JKblJ4WTzj0DAD++lCUEouSfgRKdiV2TiYCD+H+l3tANKSPQFPQuzi7rbvxqGeRmXB9kDwURaoSTTpYjA9REMUi9uA6aV7PWtBNXgUzMLowYMZeos6Xvyhb34GmufswMHA5ZyYpxzjTphOak4ZjNOiz8aScO5ygiTx99SqwX/uL+HSeVOSraHw8IymrMwm+jLxqN8BS8dGcItLlm/ioulqH2j4V8glDgSut+ExkxiD7m8TGPrrjCQNJbRDzpOFsyCyfBZupvp8QjGKW2KGziSZeIWes4aTB9tRmeEBhnUrmTDZQuXcc67Fg82KHrSfaeeOEq6jjuUjQ8wUnzM4Zz3dhrwSyslVz/WvnKqYkr4V/TTXPFF5EjF4rM1bHZ8bK63EfTnK41+n3n4gEFoYP4mXkNH0hntnYcdTqiE7Gn+q0BpRRxnkpBSZlA6Wa70jpW0FGqkw5e591A5/H+OV+60WAo+4Mi+NlsKrvLZ9EiVaPnoEFZlJQx1fA777AJ2MjXJ4KSsrWDWJi1lE8yPs8V6XvcC0chDTYt8456sKXAagCZyY+fzQriFMaddXyKQdG8qBqcdYjAsiIcjzaRFBBoOK9sU+sFY7N6B6+xtrlu3c37rQKkI3O2EoiJOris54EjJ5OFuumA0M6riNUuBf/MEPFBVx1JRcUEs+upEBsCnwYski7FT3TTqHrx7v5AjgFN97xhPTkmVpu6sxRnWBi1fxIRp8eWZeFM6mUcGgVk1WeVb1yhdV9hoMo2TsNEPE0tHo/wvuSJSzbZo7wibeXM9v/rRfKcx7X93rfiXVnyQ9f/5CaAQ4lxedPp/6uzLtOS4FyL0bCNeZ6L5w+AiuyWCTDFIYaUzhwfG+/YTQpWyeZCdQIKzhV+3GeXI2cxoP0ER/DlOKymf1gm+zRU3sqf1lBVQ0y+mK/Awl9bS3uaaQmI0FUyUwHUKP7PKuXnO+LcwDv4OfPT6hph8smc1EtMe5ib/apar/qZ9dyaEaElALJ1KKxnHziuvVl8atk1fINSQh7OtXDyqbPw9o/nGIpTnv5iFmwmWJLis2oyEgPkJqyx0vYI8rjkVEzKc8eQavAJBYSpjMwM193Swt+yJyjvaGYWPnqExxKiNarpB2WSO7soCAZXhS1uEYHryrK47BH6W1dRiruqT0xpLih3MXiwU3VDwAAAA=='; -// Add this function at the top of the file +/** + * Check if the current theme is dark. + */ function isDarkMode(): boolean { return window.matchMedia('(prefers-color-scheme: dark)').matches; } -// Listen for input field focus +/** + * Listen for input field focus + */ document.addEventListener('focusin', (e) => { const target = e.target as HTMLInputElement; if (target.tagName === 'INPUT') { @@ -28,12 +32,8 @@ function showCredentialPopup(input: HTMLInputElement) : void { const forms = detectForms(); if (!forms.length) return; - console.log('showCredentialPopup called'); - // Request credentials from background script chrome.runtime.sendMessage({ type: 'GET_CREDENTIALS_FOR_URL', url: window.location.href }, (response: CredentialResponse) => { - console.log('showCredentialPopup response:', response); - switch (response.status) { case 'OK': if (response.credentials?.length) { diff --git a/browser-extensions/chrome/src/pages/Settings.tsx b/browser-extensions/chrome/src/pages/Settings.tsx index 2adf93757..7052c6eb5 100644 --- a/browser-extensions/chrome/src/pages/Settings.tsx +++ b/browser-extensions/chrome/src/pages/Settings.tsx @@ -7,7 +7,6 @@ type ApiOption = { const DEFAULT_OPTIONS: ApiOption[] = [ { label: 'Aliasvault.net', value: 'https://app.aliasvault.net/api' }, - { label: 'Development', value: 'https://localhost:7223' }, { label: 'Self-hosted', value: 'custom' } ]; @@ -17,17 +16,20 @@ const DEFAULT_OPTIONS: ApiOption[] = [ const Settings: React.FC = () => { const [selectedOption, setSelectedOption] = useState(''); const [customUrl, setCustomUrl] = useState(''); + const [customClientUrl, setCustomClientUrl] = useState(''); useEffect(() => { - // Load saved API URL from storage - chrome.storage.local.get(['apiUrl'], (result) => { + // Load saved URLs from storage + chrome.storage.local.get(['apiUrl', 'clientUrl'], (result) => { const savedUrl = result.apiUrl; + const savedClientUrl = result.clientUrl; const matchingOption = DEFAULT_OPTIONS.find(opt => opt.value === savedUrl); if (matchingOption) { setSelectedOption(matchingOption.value); } else if (savedUrl) { setSelectedOption('custom'); setCustomUrl(savedUrl); + setCustomClientUrl(savedClientUrl || ''); } else { setSelectedOption(DEFAULT_OPTIONS[0].value); } @@ -41,19 +43,30 @@ const Settings: React.FC = () => { const value = e.target.value; setSelectedOption(value); if (value !== 'custom') { - chrome.storage.local.set({ apiUrl: value }); + chrome.storage.local.set({ + apiUrl: '', + clientUrl: '', + }); } }; /** - * Handle custom URL change + * Handle custom API URL change */ const handleCustomUrlChange = (e: React.ChangeEvent) : void => { const value = e.target.value; setCustomUrl(value); - if (selectedOption === 'custom') { - chrome.storage.local.set({ apiUrl: value }); - } + chrome.storage.local.set({ apiUrl: value }); + }; + + /** + * Handle custom client URL change + * @param e + */ + const handleCustomClientUrlChange = (e: React.ChangeEvent) : void => { + const value = e.target.value; + setCustomClientUrl(value); + chrome.storage.local.set({ clientUrl: value }); }; return ( @@ -76,19 +89,34 @@ const Settings: React.FC = () => { {selectedOption === 'custom' && ( -
- - -
+ <> +
+ + +
+
+ + +
+ )} );