adds the ability to login to stoat desktop with your session token
Signed-off-by: AvaLilac <257690424+AvaLilac@users.noreply.github.com>
This commit is contained in:
parent
7d07e3fcc8
commit
b22130645a
1 changed files with 139 additions and 0 deletions
139
avia_core/LoginWithToken.js
Normal file
139
avia_core/LoginWithToken.js
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
(function () {
|
||||
if (window.__LOGIN_WITH_TOKEN__) return;
|
||||
window.__LOGIN_WITH_TOKEN__ = true;
|
||||
|
||||
async function loginWithToken(token) {
|
||||
const res = await fetch('https://stoat.chat/api/users/@me', {
|
||||
headers: { 'x-session-token': token }
|
||||
});
|
||||
if (!res.ok) throw new Error('Invalid token');
|
||||
const user = await res.json();
|
||||
|
||||
const db = await new Promise((resolve, reject) => {
|
||||
const r = indexedDB.open('localforage');
|
||||
r.onsuccess = () => resolve(r.result);
|
||||
r.onerror = () => reject(r.error);
|
||||
});
|
||||
|
||||
const tx = db.transaction('keyvaluepairs', 'readwrite');
|
||||
await new Promise((resolve, reject) => {
|
||||
const r = tx.objectStore('keyvaluepairs').put({
|
||||
session: {
|
||||
_id: user._id,
|
||||
token: token,
|
||||
userId: user._id,
|
||||
valid: true
|
||||
}
|
||||
}, 'auth');
|
||||
r.onsuccess = () => resolve();
|
||||
r.onerror = () => reject(r.error);
|
||||
});
|
||||
|
||||
location.reload();
|
||||
}
|
||||
|
||||
function openTokenDialog() {
|
||||
const backdrop = document.createElement('div');
|
||||
backdrop.className = 'top_0 left_0 right_0 bottom_0 pos_fixed z_100 max-h_100% d_grid us_none place-items_center pointer-events_all anim-n_scrimFadeIn anim-dur_0.1s anim-fm_forwards trs_var(--transitions-medium)_all p_80px ov-y_auto';
|
||||
backdrop.style.cssText = '--background: rgba(0, 0, 0, 0.6);';
|
||||
|
||||
backdrop.innerHTML = `
|
||||
<div style="opacity: 1; --motion-translateY: 0px; transform: translateY(var(--motion-translateY));">
|
||||
<div class="p_24px min-w_280px max-w_560px bdr_28px d_flex flex-d_column c_var(--md-sys-color-on-surface) bg_var(--md-sys-color-surface-container-high)">
|
||||
<span class="lh_2rem fs_1.5rem ls_0 fw_400 mbe_16px">Login With Token</span>
|
||||
<div class="c_var(--md-sys-color-on-surface-variant) lh_1.25rem fs_0.875rem ls_0.015625rem fw_400">
|
||||
<div class="d_flex flex-d_column flex-g_initial m_0 ai_initial jc_initial gap_var(--gap-md)">
|
||||
<mdui-text-field id="lwt-token-input" variant="filled" type="password" name="token" required label="Session Token"></mdui-text-field>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gap_8px d_flex jc_end mbs_24px">
|
||||
<button id="lwt-close-btn" type="button" class="lh_1.25rem fs_0.875rem ls_0.015625rem fw_400 pos_relative px_16px flex-sh_0 d_flex ai_center jc_center ff_inherit cursor_pointer bd_none trs_var(--transitions-medium)_all c_var(--color) fill_var(--color) h_40px bdr_var(--borderRadius-full) --color_var(--md-sys-color-primary)">
|
||||
<md-ripple aria-hidden="true"></md-ripple>Close
|
||||
</button>
|
||||
<button id="lwt-login-btn" type="button" class="lh_1.25rem fs_0.875rem ls_0.015625rem fw_400 pos_relative px_16px flex-sh_0 d_flex ai_center jc_center ff_inherit cursor_pointer bd_none trs_var(--transitions-medium)_all c_var(--color) fill_var(--color) h_40px bdr_var(--borderRadius-full) --color_var(--md-sys-color-on-primary) bg_var(--md-sys-color-primary)">
|
||||
<md-ripple aria-hidden="true"></md-ripple>Login
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
document.body.appendChild(backdrop);
|
||||
|
||||
const closeBtn = backdrop.querySelector('#lwt-close-btn');
|
||||
const loginBtn = backdrop.querySelector('#lwt-login-btn');
|
||||
const tokenInput = backdrop.querySelector('#lwt-token-input');
|
||||
|
||||
function close() { backdrop.remove(); }
|
||||
|
||||
function setLoading(loading) {
|
||||
loginBtn.disabled = loading;
|
||||
loginBtn.style.cursor = loading ? 'not-allowed' : 'pointer';
|
||||
const ripple = loginBtn.querySelector('md-ripple');
|
||||
loginBtn.textContent = loading ? 'Logging in…' : 'Login';
|
||||
if (ripple) loginBtn.prepend(ripple);
|
||||
}
|
||||
|
||||
function setError(msg) {
|
||||
loginBtn.disabled = false;
|
||||
loginBtn.style.cursor = 'pointer';
|
||||
const ripple = loginBtn.querySelector('md-ripple');
|
||||
loginBtn.textContent = msg;
|
||||
if (ripple) loginBtn.prepend(ripple);
|
||||
setTimeout(() => {
|
||||
loginBtn.textContent = 'Login';
|
||||
if (ripple) loginBtn.prepend(ripple);
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
backdrop.addEventListener('click', (e) => { if (e.target === backdrop) close(); });
|
||||
closeBtn.addEventListener('click', close);
|
||||
|
||||
loginBtn.addEventListener('click', async () => {
|
||||
const token = tokenInput.value?.trim();
|
||||
if (!token) {
|
||||
setError('Enter a token!');
|
||||
return;
|
||||
}
|
||||
setLoading(true);
|
||||
try {
|
||||
await loginWithToken(token);
|
||||
} catch (err) {
|
||||
setError('Invalid token!');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function injectLoginButton() {
|
||||
const signUpBtn = [...document.querySelectorAll('button')]
|
||||
.find(b => b.textContent.trim() === 'Sign Up');
|
||||
if (!signUpBtn) return;
|
||||
|
||||
const parent = signUpBtn.parentElement;
|
||||
if (parent.querySelector('[data-lwt-btn]')) return;
|
||||
|
||||
const clone = signUpBtn.cloneNode(false);
|
||||
clone.dataset.lwtBtn = 'true';
|
||||
clone.textContent = 'Login With Token';
|
||||
|
||||
const ripple = document.createElement('md-ripple');
|
||||
ripple.setAttribute('aria-hidden', 'true');
|
||||
clone.prepend(ripple);
|
||||
|
||||
clone.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
openTokenDialog();
|
||||
});
|
||||
|
||||
signUpBtn.insertAdjacentElement('afterend', clone);
|
||||
}
|
||||
|
||||
let debounceTimer = null;
|
||||
new MutationObserver(() => {
|
||||
clearTimeout(debounceTimer);
|
||||
debounceTimer = setTimeout(injectLoginButton, 150);
|
||||
}).observe(document.body, { childList: true, subtree: true });
|
||||
|
||||
injectLoginButton();
|
||||
})();
|
||||
Loading…
Add table
Reference in a new issue