feat(ops-web/auth): add remember-me with session/local storage split
Persistent logins land in localStorage, ephemeral ones in sessionStorage, and we recall the last username + remember preference on the login form. Also propagate the indigo brand color through the antd ConfigProvider theme token so the side nav and avatar match the redesigned login.
This commit is contained in:
@@ -5,7 +5,9 @@ import { http } from "@/lib/http";
|
||||
import {
|
||||
type OperatorView,
|
||||
clearStoredSession,
|
||||
readLoginPreference,
|
||||
readStoredSession,
|
||||
writeLoginPreference,
|
||||
writeStoredSession,
|
||||
} from "@/lib/storage";
|
||||
|
||||
@@ -20,25 +22,32 @@ export const useAuthStore = defineStore("ops-auth", () => {
|
||||
const expiresAt = ref<number | null>(null);
|
||||
const operator = ref<OperatorView | null>(null);
|
||||
const initialized = ref(false);
|
||||
const persistent = ref(false);
|
||||
|
||||
function hydrate(): void {
|
||||
const stored = readStoredSession();
|
||||
accessToken.value = stored.accessToken;
|
||||
expiresAt.value = stored.expiresAt;
|
||||
operator.value = stored.operator;
|
||||
accessToken.value = stored.session.accessToken;
|
||||
expiresAt.value = stored.session.expiresAt;
|
||||
operator.value = stored.session.operator;
|
||||
persistent.value = stored.persistent;
|
||||
initialized.value = true;
|
||||
}
|
||||
|
||||
async function login(username: string, password: string): Promise<void> {
|
||||
async function login(username: string, password: string, remember: boolean): Promise<void> {
|
||||
const result = await http.post<LoginResponse>("/auth/login", { username, password });
|
||||
accessToken.value = result.access_token;
|
||||
expiresAt.value = result.expires_at;
|
||||
operator.value = result.operator;
|
||||
writeStoredSession({
|
||||
accessToken: result.access_token,
|
||||
expiresAt: result.expires_at,
|
||||
operator: result.operator,
|
||||
});
|
||||
persistent.value = remember;
|
||||
writeStoredSession(
|
||||
{
|
||||
accessToken: result.access_token,
|
||||
expiresAt: result.expires_at,
|
||||
operator: result.operator,
|
||||
},
|
||||
remember,
|
||||
);
|
||||
writeLoginPreference({ remember, lastUsername: username });
|
||||
}
|
||||
|
||||
async function refreshSelf(): Promise<void> {
|
||||
@@ -53,11 +62,14 @@ export const useAuthStore = defineStore("ops-auth", () => {
|
||||
role: me.role,
|
||||
status: me.status,
|
||||
};
|
||||
writeStoredSession({
|
||||
accessToken: accessToken.value,
|
||||
expiresAt: expiresAt.value,
|
||||
operator: operator.value,
|
||||
});
|
||||
writeStoredSession(
|
||||
{
|
||||
accessToken: accessToken.value,
|
||||
expiresAt: expiresAt.value,
|
||||
operator: operator.value,
|
||||
},
|
||||
persistent.value,
|
||||
);
|
||||
} catch {
|
||||
logout();
|
||||
}
|
||||
@@ -67,6 +79,7 @@ export const useAuthStore = defineStore("ops-auth", () => {
|
||||
accessToken.value = null;
|
||||
expiresAt.value = null;
|
||||
operator.value = null;
|
||||
persistent.value = false;
|
||||
clearStoredSession();
|
||||
}
|
||||
|
||||
@@ -78,9 +91,11 @@ export const useAuthStore = defineStore("ops-auth", () => {
|
||||
operator,
|
||||
initialized,
|
||||
isAuthenticated,
|
||||
persistent,
|
||||
hydrate,
|
||||
login,
|
||||
refreshSelf,
|
||||
logout,
|
||||
readLoginPreference,
|
||||
};
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user