🏡 index : ~doyle/chartered.git

author Jordan Doyle <jordan@doyle.la> 2021-10-06 1:23:48.0 +01:00:00
committer Jordan Doyle <jordan@doyle.la> 2021-10-06 1:23:48.0 +01:00:00
commit
d8f6bec3c3123093e1d50de37793325bcbe38d43 [patch]
tree
63836c74cda677d3ae7982dd3beacc69a68805e2
parent
7a3228d3ce274d216cb13532314315a7e8dd1260
download
d8f6bec3c3123093e1d50de37793325bcbe38d43.tar.gz

Remind the user who they are on the frontend



Diff

 chartered-frontend/src/useAuth.tsx              | 48 +++++++++++++++++++++++++++++++++++++-----------
 chartered-frontend/src/pages/Login.tsx          |  4 ----
 chartered-frontend/src/pages/crate/Members.tsx  |  7 +++++--
 chartered-web/src/endpoints/web_api/auth/mod.rs |  3 +++
 4 files changed, 41 insertions(+), 21 deletions(-)

diff --git a/chartered-frontend/src/useAuth.tsx b/chartered-frontend/src/useAuth.tsx
index 2e640d3..b682846 100644
--- a/chartered-frontend/src/useAuth.tsx
+++ a/chartered-frontend/src/useAuth.tsx
@@ -8,12 +8,20 @@
  providers: string[];
}

interface LoginResponse {
  user_uuid: string;
  key: string;
  expires: number;
  error?: string;
}

export interface AuthContext {
  login: (username: string, password: string) => Promise<void>;
  oauthLogin: (provider: string) => Promise<void>;
  logout: () => Promise<void>;
  getAuthKey: () => Promise<string | null>;
  setAuth: ([string, string]) => any;
  getUserUuid: () => Promise<string>;
  handleLoginResponse: (json: LoginResponse) => any;
}

const authContext = createContext<AuthContext | null>(null);
@@ -32,12 +40,8 @@
    try {
      let result = await fetch(unauthenticatedEndpoint(`login/oauth/complete${location.search}`));
      let json = await result.json();

      if (json.error) {
        throw new Error(json.error);
      }

      auth.setAuth([json.key, new Date(json.expires)]);
      auth.handleLoginResponse(json);
    } catch (err) {
      setResult(
        <Redirect to={{
@@ -58,15 +62,23 @@
function useProvideAuth(): AuthContext {
  const [auth, setAuth] = useState(() => {
    let authStorage = getAuthStorage();
    return [authStorage.authKey, authStorage.expires];
    return [authStorage.userUuid, authStorage.authKey, authStorage.expires];
  });

  useEffect(() => {
    localStorage.setItem(
      "charteredAuthentication",
      JSON.stringify({ authKey: auth?.[0], expires: auth?.[1] })
      JSON.stringify({ userUuid: auth?.[0], authKey: auth?.[1], expires: auth?.[2] })
    );
  }, [auth]);

  const handleLoginResponse = (response: LoginResponse) => {
    if (response.error) {
      throw new Error(response.error);
    }

    setAuth([response.user_uuid, response.key, new Date(response.expires)]);
  }

  const login = async (username: string, password: string) => {
    let res = await fetch(unauthenticatedEndpoint("login/password"), {
@@ -79,11 +91,7 @@
    });
    let json = await res.json();

    if (json.error) {
      throw new Error(json.error);
    }

    setAuth([json.key, new Date(json.expires)]);
    handleLoginResponse(json);
  };

  const oauthLogin = async (provider: string) => {
@@ -109,7 +117,15 @@
  };

  const getAuthKey = () => {
    if (auth?.[1] > new Date()) {
    if (auth?.[2] > new Date()) {
      return auth[1];
    } else if (auth) {
      return null;
    }
  };

  const getUserUuid = () => {
    if (auth?.[2] > new Date()) {
      return auth[0];
    } else if (auth) {
      return null;
@@ -120,8 +136,9 @@
    login,
    logout,
    getAuthKey,
    getUserUuid,
    oauthLogin,
    setAuth,
    handleLoginResponse,
  };
}

@@ -129,6 +146,7 @@
  const saved = localStorage.getItem("charteredAuthentication");
  const initial = JSON.parse(saved);
  return {
    userUuid: initial?.userUuid || null,
    authKey: initial?.authKey || null,
    expires: initial?.expires ? new Date(initial.expires) : null,
  };
diff --git a/chartered-frontend/src/pages/Login.tsx b/chartered-frontend/src/pages/Login.tsx
index 41ab0c1..6436fb9 100644
--- a/chartered-frontend/src/pages/Login.tsx
+++ a/chartered-frontend/src/pages/Login.tsx
@@ -55,10 +55,6 @@
      await auth.oauthLogin(provider);
    } catch (e) {
      setError(e.message);
    } finally {
      if (isMountedRef.current) {
        setLoading(null);
      }
    }
  }

diff --git a/chartered-frontend/src/pages/crate/Members.tsx b/chartered-frontend/src/pages/crate/Members.tsx
index ceb1502..c697b37 100644
--- a/chartered-frontend/src/pages/crate/Members.tsx
+++ a/chartered-frontend/src/pages/crate/Members.tsx
@@ -121,6 +121,7 @@
  const [selectedPermissions, setSelectedPermissions] = useState(
    member.permissions
  );
  const auth = useAuth();
  const [deleting, setDeleting] = useState(false);
  const [saving, setSaving] = useState(false);
  const [error, setError] = useState(null);
@@ -218,8 +219,10 @@

        <td className="align-middle">
          <strong>{member.username}</strong>
          {/*<br />
          <em>(that's you!)</em>*/}
          {auth.getUserUuid() === member.uuid ? <>
            <br />
            <em>(that's you!)</em>
          </> : <></>}
        </td>

        {possiblePermissions && member.permissions ? (
diff --git a/chartered-web/src/endpoints/web_api/auth/mod.rs b/chartered-web/src/endpoints/web_api/auth/mod.rs
index e0b309d..bfc7e1a 100644
--- a/chartered-web/src/endpoints/web_api/auth/mod.rs
+++ a/chartered-web/src/endpoints/web_api/auth/mod.rs
@@ -8,6 +8,7 @@
use chartered_db::{
    users::{User, UserSession},
    ConnectionPool,
    uuid::Uuid,
};
use futures::future::Future;
use serde::Serialize;
@@ -34,6 +35,7 @@

#[derive(Serialize)]
pub struct LoginResponse {
    user_uuid: Uuid,
    key: String,
    expires: chrono::DateTime<chrono::Utc>,
}
@@ -62,6 +64,7 @@
    .await?;

    Ok(LoginResponse {
        user_uuid: user.uuid.0,
        key: key.session_key,
        expires,
    })