@proveanything/smartlinks-auth-ui
Version:
Lightweight React authentication UI components with bearer token support and Smartlinks SDK integration
114 lines (113 loc) • 3.88 kB
JavaScript
import { jsx as _jsx } from "react/jsx-runtime";
import React, { createContext, useContext, useState, useEffect, useCallback } from 'react';
import { tokenStorage } from '../utils/tokenStorage';
import { createSmartlinksClient } from '../smartlinks';
const AuthContext = createContext(undefined);
export const AuthProvider = ({ children, apiEndpoint, clientId }) => {
const [user, setUser] = useState(null);
const [token, setToken] = useState(null);
const [accountData, setAccountData] = useState(null);
const [isLoading, setIsLoading] = useState(true);
const [smartlinks, setSmartlinks] = useState(null);
// Initialize Smartlinks SDK
useEffect(() => {
const client = createSmartlinksClient({
apiEndpoint,
clientId,
});
setSmartlinks(client);
}, [apiEndpoint, clientId]);
// Initialize auth state from localStorage
useEffect(() => {
const storedToken = tokenStorage.getToken();
const storedUser = tokenStorage.getUser();
const storedAccountData = tokenStorage.getAccountData();
if (storedToken && storedUser) {
setToken(storedToken.token);
setUser(storedUser);
setAccountData(storedAccountData);
// Set token in Smartlinks SDK
if (smartlinks) {
smartlinks.setToken(storedToken.token);
}
}
setIsLoading(false);
}, [smartlinks]);
const login = useCallback((authToken, authUser, authAccountData) => {
// Store token, user, and account data
tokenStorage.saveToken(authToken);
tokenStorage.saveUser(authUser);
if (authAccountData) {
tokenStorage.saveAccountData(authAccountData);
}
setToken(authToken);
setUser(authUser);
setAccountData(authAccountData || null);
// Set token in Smartlinks SDK
if (smartlinks) {
smartlinks.setToken(authToken);
}
}, [smartlinks]);
const logout = useCallback(async () => {
// Logout via Smartlinks SDK if available
if (smartlinks) {
try {
await smartlinks.logout();
}
catch (error) {
console.error('Smartlinks logout error:', error);
}
}
// Clear local storage
tokenStorage.clearAll();
setToken(null);
setUser(null);
setAccountData(null);
// Clear token from Smartlinks SDK
if (smartlinks) {
smartlinks.clearToken();
}
}, [smartlinks]);
const getToken = useCallback(() => {
const storedToken = tokenStorage.getToken();
return storedToken ? storedToken.token : null;
}, []);
const refreshToken = useCallback(async () => {
if (!smartlinks) {
throw new Error('Smartlinks SDK not initialized');
}
try {
const newToken = await smartlinks.refreshToken();
// Update stored token
tokenStorage.saveToken(newToken);
setToken(newToken);
return newToken;
}
catch (error) {
console.error('Token refresh failed:', error);
// If refresh fails, logout user
await logout();
throw error;
}
}, [smartlinks, logout]);
const value = {
user,
token,
accountData,
isAuthenticated: !!token && !!user,
isLoading,
smartlinks,
login,
logout,
getToken,
refreshToken,
};
return _jsx(AuthContext.Provider, { value: value, children: children });
};
export const useAuth = () => {
const context = useContext(AuthContext);
if (context === undefined) {
throw new Error('useAuth must be used within an AuthProvider');
}
return context;
};