Google auth done
This commit is contained in:
112
src/lib/google.ts
Normal file
112
src/lib/google.ts
Normal file
@@ -0,0 +1,112 @@
|
||||
import { writable } from 'svelte/store';
|
||||
|
||||
const GOOGLE_CLIENT_ID = import.meta.env.VITE_GOOGLE_CLIENT_ID;
|
||||
|
||||
export const isGoogleApiReady = writable(false);
|
||||
export const isSignedIn = writable(false);
|
||||
|
||||
let tokenClient: google.accounts.oauth2.TokenClient;
|
||||
|
||||
const TOKEN_KEY = 'google_oauth_token';
|
||||
export function initGoogleClient(callback: () => void) {
|
||||
const script = document.createElement('script');
|
||||
script.src = 'https://apis.google.com/js/api.js';
|
||||
script.onload = () => {
|
||||
gapi.load('client', async () => {
|
||||
await gapi.client.init({
|
||||
// NOTE: API KEY IS NOT REQUIRED FOR THIS IMPLEMENTATION
|
||||
// apiKey: 'YOUR_API_KEY',
|
||||
discoveryDocs: [
|
||||
'https://www.googleapis.com/discovery/v1/apis/drive/v3/rest',
|
||||
'https://www.googleapis.com/discovery/v1/apis/sheets/v4/rest',
|
||||
],
|
||||
});
|
||||
isGoogleApiReady.set(true);
|
||||
// Restore token from storage if available
|
||||
const saved = localStorage.getItem(TOKEN_KEY);
|
||||
if (saved) {
|
||||
try {
|
||||
const data = JSON.parse(saved);
|
||||
if (data.access_token && data.expires_at && data.expires_at > Date.now()) {
|
||||
gapi.client.setToken({ access_token: data.access_token });
|
||||
isSignedIn.set(true);
|
||||
} else {
|
||||
localStorage.removeItem(TOKEN_KEY);
|
||||
}
|
||||
} catch {
|
||||
localStorage.removeItem(TOKEN_KEY);
|
||||
}
|
||||
}
|
||||
callback();
|
||||
});
|
||||
};
|
||||
document.body.appendChild(script);
|
||||
|
||||
const scriptGsi = document.createElement('script');
|
||||
scriptGsi.src = 'https://accounts.google.com/gsi/client';
|
||||
scriptGsi.onload = () => {
|
||||
tokenClient = google.accounts.oauth2.initTokenClient({
|
||||
client_id: GOOGLE_CLIENT_ID,
|
||||
scope: 'https://www.googleapis.com/auth/drive.readonly https://www.googleapis.com/auth/spreadsheets.readonly',
|
||||
callback: (tokenResponse) => {
|
||||
if (tokenResponse?.access_token) {
|
||||
// Set token in gapi client
|
||||
gapi.client.setToken({ access_token: tokenResponse.access_token });
|
||||
isSignedIn.set(true);
|
||||
// Persist token with expiration
|
||||
const expiresInSeconds = tokenResponse.expires_in
|
||||
? Number(tokenResponse.expires_in)
|
||||
: 0;
|
||||
const expiresInMs = expiresInSeconds * 1000;
|
||||
const record = {
|
||||
access_token: tokenResponse.access_token,
|
||||
expires_at: expiresInMs ? Date.now() + expiresInMs : Date.now() + 3600 * 1000
|
||||
};
|
||||
localStorage.setItem(TOKEN_KEY, JSON.stringify(record));
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
||||
document.body.appendChild(scriptGsi);
|
||||
}
|
||||
|
||||
export function handleSignIn() {
|
||||
if (gapi.client.getToken() === null) {
|
||||
tokenClient.requestAccessToken({ prompt: 'consent' });
|
||||
} else {
|
||||
tokenClient.requestAccessToken({ prompt: '' });
|
||||
}
|
||||
}
|
||||
|
||||
export function handleSignOut() {
|
||||
const token = gapi.client.getToken();
|
||||
if (token !== null) {
|
||||
google.accounts.oauth2.revoke(token.access_token, () => {
|
||||
gapi.client.setToken(null);
|
||||
isSignedIn.set(false);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export async function searchSheets(query: string) {
|
||||
if (!gapi.client.drive) {
|
||||
throw new Error('Google Drive API not loaded');
|
||||
}
|
||||
const response = await gapi.client.drive.files.list({
|
||||
q: `mimeType='application/vnd.google-apps.spreadsheet' and name contains '${query}'`,
|
||||
fields: 'files(id, name, iconLink, webViewLink)',
|
||||
pageSize: 20,
|
||||
});
|
||||
return response.result.files || [];
|
||||
}
|
||||
|
||||
export async function getSheetData(spreadsheetId: string, range: string) {
|
||||
if (!gapi.client.sheets) {
|
||||
throw new Error('Google Sheets API not loaded');
|
||||
}
|
||||
const response = await gapi.client.sheets.spreadsheets.values.get({
|
||||
spreadsheetId,
|
||||
range,
|
||||
});
|
||||
return response.result.values || [];
|
||||
}
|
||||
Reference in New Issue
Block a user