useAuth.ts 1.79 KB
import React, { useState, useCallback } from "react";
import ky from "ky";

interface LoginResponse {
  access: string;
  refresh: string;
  exp: number;
  user: {
    int_id: number;
    user_id: string;
    name: string;
    total_size: number;
    current_size: number;
    root_folder: number;
  };
}

interface Token {
  accessToken: string;
  refreshToken: string;
  expiration: Date;
  user: {
    id: number;
    username: string;
    name: string;
    totalSize: number;
    currentSize: number;
    rootFolder: number;
  };
}

export const TokenContext = React.createContext<Token>({} as Token);

export function useAuth() {
  const [token, setToken] = useState<Token | null>(() => {
    const item = localStorage.getItem("token");
    if (item) {
      const token = JSON.parse(item);
      token.expiration = new Date(token.expiration);
      return token;
    }
    return null;
  });

  const login = useCallback(
    async (username: string, password: string, remember: boolean) => {
      const body = new URLSearchParams();
      body.set("user_id", username);
      body.set("password", password);

      const response = await ky
        .post("/users/login/", { body })
        .json<LoginResponse>();

      const token = {
        accessToken: response.access,
        refreshToken: response.refresh,
        expiration: new Date(response.exp * 1000),
        user: {
          id: response.user.int_id,
          username: response.user.user_id,
          name: response.user.name,
          totalSize: response.user.total_size,
          currentSize: response.user.current_size,
          rootFolder: response.user.root_folder,
        },
      };

      setToken(token);

      if (remember) {
        localStorage.setItem("token", JSON.stringify(token));
      }
    },
    []
  );

  return { token, login };
}