diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md
index a67c7e3..303229d 100644
--- a/.github/copilot-instructions.md
+++ b/.github/copilot-instructions.md
@@ -92,6 +92,11 @@ onsubmit|preventDefault={handleSubmit} is depracated, do not use it!
Loading session using page.server.ts is not needed as the session is already available in the locals object.
+IMPORTANT: Always make sure that the client-side module are not importing secrets
+or are running any sensritive code that could expose secrets to the client.
+If any requests are needed to check sensitive infomration, create an api route and
+fetch data from there instead of directly in the client-side module.
+
The database schema in supabase is as follows:
-- WARNING: This schema is for context only and is not meant to be run.
-- Table order and constraints may not be valid for execution.
diff --git a/src/lib/gmail.ts b/src/lib/gmail.ts
deleted file mode 100644
index c46488d..0000000
--- a/src/lib/gmail.ts
+++ /dev/null
@@ -1,80 +0,0 @@
-import { google } from 'googleapis';
-import quotedPrintable from 'quoted-printable';
-import { getAuthenticatedClient } from './google-server.js';
-
-export function createEmailTemplate(text: string): string {
- return `
-
-
-
-
-
-
-
${text}
-

-
-
-
This email has been generated with the help of ScanWave
-
-
-
-`;
-}
-
-export async function sendGmail(
- refreshToken: string,
- { to, subject, text, qr_code }: { to: string; subject: string; text: string; qr_code: string }
-) {
- const oauth = getAuthenticatedClient(refreshToken);
- const gmail = google.gmail({ version: 'v1', auth: oauth });
-
- const message_html = createEmailTemplate(text);
- const boundary = 'BOUNDARY';
- const nl = '\r\n';
-
- // Convert HTML to a Buffer, then to latin1 string for quotedPrintable.encode
- const htmlBuffer = Buffer.from(message_html, 'utf8');
- const htmlLatin1 = htmlBuffer.toString('latin1');
- const htmlQP = quotedPrintable.encode(htmlLatin1);
- const qrLines = qr_code.replace(/.{1,76}/g, '$&' + nl);
-
- const rawParts = [
- 'MIME-Version: 1.0',
- `To: ${to}`,
- `Subject: ${subject}`,
- `Content-Type: multipart/related; boundary="${boundary}"`,
- '',
- `--${boundary}`,
- 'Content-Type: text/html; charset="UTF-8"',
- 'Content-Transfer-Encoding: quoted-printable',
- '',
- htmlQP,
- '',
- `--${boundary}`,
- 'Content-Type: image/png',
- 'Content-Transfer-Encoding: base64',
- 'Content-ID: ',
- 'Content-Disposition: inline; filename="qr.png"',
- '',
- qrLines,
- '',
- `--${boundary}--`,
- ''
- ];
-
- const rawMessage = rawParts.join(nl);
- const raw = Buffer.from(rawMessage).toString('base64url');
-
- await gmail.users.messages.send({
- userId: 'me',
- requestBody: { raw }
- });
-}
diff --git a/src/lib/google-server.ts b/src/lib/google-server.ts
deleted file mode 100644
index 7d98157..0000000
--- a/src/lib/google-server.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-import { google } from 'googleapis';
-import { env } from '$env/dynamic/private';
-
-export const scopes = [
- 'https://www.googleapis.com/auth/gmail.send',
- 'https://www.googleapis.com/auth/userinfo.email',
- 'https://www.googleapis.com/auth/drive.readonly',
- 'https://www.googleapis.com/auth/spreadsheets.readonly'
-];
-
-export function getOAuthClient() {
- return new google.auth.OAuth2(
- env.GOOGLE_CLIENT_ID,
- env.GOOGLE_CLIENT_SECRET,
- env.GOOGLE_REDIRECT_URI
- );
-}
-
-export function createAuthUrl() {
- return getOAuthClient().generateAuthUrl({
- access_type: 'offline',
- prompt: 'consent',
- scope: scopes,
- redirect_uri: env.GOOGLE_REDIRECT_URI
- });
-}
-
-export async function exchangeCodeForTokens(code: string) {
- const { tokens } = await getOAuthClient().getToken(code);
- if (!tokens.refresh_token) throw new Error('No refresh_token returned');
- return tokens.refresh_token;
-}
-
-export function getAuthenticatedClient(refreshToken: string) {
- const oauth = getOAuthClient();
- oauth.setCredentials({ refresh_token: refreshToken });
- return oauth;
-}
diff --git a/src/lib/google.ts b/src/lib/google.ts
deleted file mode 100644
index 4977884..0000000
--- a/src/lib/google.ts
+++ /dev/null
@@ -1,95 +0,0 @@
-import { browser } from '$app/environment';
-
-// Client-side only functions
-export const scopes = [
- 'https://www.googleapis.com/auth/gmail.send',
- 'https://www.googleapis.com/auth/userinfo.email',
- 'https://www.googleapis.com/auth/drive.readonly',
- 'https://www.googleapis.com/auth/spreadsheets.readonly'
-];
-
-// Client-side functions for browser environment
-export async function initGoogleAuth(): Promise {
- if (!browser) return;
- // Google Auth initialization is handled by the OAuth flow
- // No initialization needed for our server-side approach
-}
-
-export function getAuthUrl(): string {
- if (!browser) return '';
- // This should be obtained from the server
- return '/auth/google';
-}
-
-export async function isTokenValid(accessToken: string): Promise {
- if (!browser) return false;
-
- try {
- const response = await fetch(`https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=${accessToken}`);
- const data = await response.json();
-
- if (response.ok && data.expires_in && data.expires_in > 0) {
- return true;
- }
- return false;
- } catch (error) {
- console.error('Error validating token:', error);
- return false;
- }
-}
-
-export async function refreshAccessToken(refreshToken: string): Promise {
- try {
- const response = await fetch('/private/api/google/auth/refresh', {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json'
- },
- body: JSON.stringify({ refreshToken })
- });
-
- if (response.ok) {
- const data = await response.json();
- return data.accessToken;
- }
- return null;
- } catch (error) {
- console.error('Error refreshing token:', error);
- return null;
- }
-}
-
-export async function getUserInfo(accessToken: string): Promise<{ email: string; name: string; picture: string } | null> {
- try {
- const response = await fetch('/private/api/google/auth/userinfo', {
- headers: {
- 'Authorization': `Bearer ${accessToken}`
- }
- });
-
- if (response.ok) {
- return await response.json();
- }
- return null;
- } catch (error) {
- console.error('Error fetching user info:', error);
- return null;
- }
-}
-
-export async function revokeToken(accessToken: string): Promise {
- try {
- const response = await fetch('/private/api/google/auth/revoke', {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json'
- },
- body: JSON.stringify({ accessToken })
- });
-
- return response.ok;
- } catch (error) {
- console.error('Error revoking token:', error);
- return false;
- }
-}
diff --git a/src/lib/google/auth/server.ts b/src/lib/google/auth/server.ts
index 6e937ae..5b4e373 100644
--- a/src/lib/google/auth/server.ts
+++ b/src/lib/google/auth/server.ts
@@ -26,6 +26,7 @@ export function getOAuthClient() {
* @returns Auth URL for Google OAuth
*/
export function createAuthUrl() {
+ console.warn("CREATE AUTH URL");
return getOAuthClient().generateAuthUrl({
access_type: 'offline',
prompt: 'consent',
diff --git a/src/lib/google/client.ts b/src/lib/google/client.ts
index dcce5f2..74da0a6 100644
--- a/src/lib/google/client.ts
+++ b/src/lib/google/client.ts
@@ -1,8 +1,13 @@
/**
- * Client-side Google API integration module
+ * Google API integration module
*
- * This module provides utilities for interacting with Google APIs from the client-side.
+ * This module provides utilities for interacting with Google APIs:
+ * - Authentication (server and client-side)
+ * - Sheets API
*/
-// Re-export auth utilities
-export * from './auth/client.js';
+// Google service modules
+export * as googleAuthClient from './auth/client.ts';
+
+export * as googleSheetsClient from './sheets/client.ts';
+
diff --git a/src/lib/google/client/index.ts b/src/lib/google/client/index.ts
deleted file mode 100644
index 589398b..0000000
--- a/src/lib/google/client/index.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-// Re-export client-side auth utilities
-export * from '../auth/client.js';
-
-// Re-export types
-export * from './types.js';
diff --git a/src/lib/google/client/types.ts b/src/lib/google/client/types.ts
deleted file mode 100644
index d6f5986..0000000
--- a/src/lib/google/client/types.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-/**
- * Client-side type definitions for Google API integration
- */
-
-export interface GoogleSheet {
- id: string;
- name: string;
- modifiedTime: string;
- webViewLink: string;
-}
-
-export interface SheetData {
- values: string[][];
-}
diff --git a/src/lib/google/gmail/index.ts b/src/lib/google/gmail/index.ts
deleted file mode 100644
index d281afc..0000000
--- a/src/lib/google/gmail/index.ts
+++ /dev/null
@@ -1,90 +0,0 @@
-import { google } from 'googleapis';
-import quotedPrintable from 'quoted-printable';
-import { getAuthenticatedClient } from '../auth/server.js';
-
-/**
- * Create an HTML email template
- * @param text - Email body text
- * @returns HTML email template
- */
-export function createEmailTemplate(text: string): string {
- return `
-
-
-
-
-
-
-
${text}
-

-
-
-
This email has been generated with the help of ScanWave
-
-
-
-`;
-}
-
-/**
- * Send an email through Gmail
- * @param refreshToken - Google refresh token
- * @param params - Email parameters (to, subject, text, qr_code)
- */
-export async function sendGmail(
- refreshToken: string,
- { to, subject, text, qr_code }: { to: string; subject: string; text: string; qr_code: string }
-) {
- const oauth = getAuthenticatedClient(refreshToken);
- const gmail = google.gmail({ version: 'v1', auth: oauth });
-
- const message_html = createEmailTemplate(text);
- const boundary = 'BOUNDARY';
- const nl = '\r\n';
-
- // Convert HTML to a Buffer, then to latin1 string for quotedPrintable.encode
- const htmlBuffer = Buffer.from(message_html, 'utf8');
- const htmlLatin1 = htmlBuffer.toString('latin1');
- const htmlQP = quotedPrintable.encode(htmlLatin1);
- const qrLines = qr_code.replace(/.{1,76}/g, '$&' + nl);
-
- const rawParts = [
- 'MIME-Version: 1.0',
- `To: ${to}`,
- `Subject: ${subject}`,
- `Content-Type: multipart/related; boundary="${boundary}"`,
- '',
- `--${boundary}`,
- 'Content-Type: text/html; charset="UTF-8"',
- 'Content-Transfer-Encoding: quoted-printable',
- '',
- htmlQP,
- '',
- `--${boundary}`,
- 'Content-Type: image/png',
- 'Content-Transfer-Encoding: base64',
- 'Content-ID: ',
- 'Content-Disposition: inline; filename="qr.png"',
- '',
- qrLines,
- '',
- `--${boundary}--`,
- ''
- ];
-
- const rawMessage = rawParts.join(nl);
- const raw = Buffer.from(rawMessage).toString('base64url');
-
- await gmail.users.messages.send({
- userId: 'me',
- requestBody: { raw }
- });
-}
diff --git a/src/lib/google/gmail/server.ts b/src/lib/google/gmail/server.ts
new file mode 100644
index 0000000..c6838ca
--- /dev/null
+++ b/src/lib/google/gmail/server.ts
@@ -0,0 +1,88 @@
+import { google } from 'googleapis';
+import quotedPrintable from 'quoted-printable';
+import { getAuthenticatedClient } from '../auth/server.js';
+
+/**
+ * Create an HTML email template
+ * @param text - Email body text
+ * @returns HTML email template
+ */
+export function createEmailTemplate(text: string): string {
+ return `
+
+
+
+
+
+
+
${text}
+

+
+
+`;
+}
+
+/**
+ * Send an email through Gmail
+ * @param refreshToken - Google refresh token
+ * @param params - Email parameters (to, subject, text, qr_code)
+ */
+export async function sendGmail(
+ refreshToken: string,
+ {
+ to,
+ subject,
+ text,
+ qr_code
+ }: {
+ to: string;
+ subject: string;
+ text: string;
+ qr_code: string;
+ }
+) {
+ const oauth = getAuthenticatedClient(refreshToken);
+ const gmail = google.gmail({ version: 'v1', auth: oauth });
+
+ const message_html = createEmailTemplate(text);
+ const boundary = 'BOUNDARY';
+ const nl = '\r\n';
+
+ const htmlBuffer = Buffer.from(message_html, 'utf8');
+ const htmlLatin1 = htmlBuffer.toString('latin1');
+ const htmlQP = quotedPrintable.encode(htmlLatin1);
+ const qrLines = qr_code.replace(/.{1,76}/g, '$&' + nl);
+
+ const rawParts = [
+ 'MIME-Version: 1.0',
+ `To: ${to}`,
+ `Subject: ${subject}`,
+ `Content-Type: multipart/related; boundary="${boundary}"`,
+ '--' + boundary,
+ 'Content-Type: text/html; charset="UTF-8"',
+ 'Content-Transfer-Encoding: quoted-printable',
+ '',
+ htmlQP,
+ '',
+ '--' + boundary,
+ 'Content-Type: image/png',
+ 'Content-Transfer-Encoding: base64',
+ 'Content-ID: ',
+ 'Content-Disposition: inline; filename="qr.png"',
+ '',
+ qrLines,
+ '',
+ '--' + boundary + '--',
+ ''
+ ];
+
+ const rawMessage = rawParts.join(nl);
+ const raw = Buffer.from(rawMessage).toString('base64url');
+
+ await gmail.users.messages.send({
+ userId: 'me',
+ requestBody: { raw }
+ });
+}
diff --git a/src/lib/google/index.ts b/src/lib/google/index.ts
deleted file mode 100644
index eb972b5..0000000
--- a/src/lib/google/index.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-/**
- * Google API integration module
- *
- * This module provides utilities for interacting with Google APIs.
- * NOTE: This is a client-side module. For server-side code, import from '$lib/google/server.js'
- */
-
-// Re-export client-side auth utilities
-export * from './auth/client.js';
diff --git a/src/lib/google/server.ts b/src/lib/google/server.ts
index 2ed029e..55e1b66 100644
--- a/src/lib/google/server.ts
+++ b/src/lib/google/server.ts
@@ -1,14 +1,15 @@
/**
- * Server-side Google API integration module
+ * Google API integration module
*
- * This module provides utilities for interacting with Google APIs from the server-side.
+ * This module provides utilities for interacting with Google APIs:
+ * - Authentication (server and client-side)
+ * - Sheets API
+ * - Gmail API
*/
-// Re-export server-side auth utilities
-export * from './auth/server.js';
+// Google service modules
+export * as googleAuthServer from './auth/server.ts';
-// Re-export sheets utilities
-export * from './sheets/index.js';
+export * as googleSheetsServer from './sheets/server.ts';
-// Re-export Gmail utilities
-export * from './gmail/index.js';
+export * as googleGmailServer from './gmail/server.ts';
diff --git a/src/lib/google/sheets/client.ts b/src/lib/google/sheets/client.ts
new file mode 100644
index 0000000..21c74b5
--- /dev/null
+++ b/src/lib/google/sheets/client.ts
@@ -0,0 +1,23 @@
+// Client-side Sheets functions (use fetch to call protected API endpoints)
+
+/**
+ * Fetch recent spreadsheets via protected endpoint
+ */
+export async function getRecentSpreadsheetsClient(refreshToken: string, limit: number = 10) {
+ const response = await fetch(`/private/api/google/sheets/recent?limit=${limit}`, {
+ headers: { Authorization: `Bearer ${refreshToken}` }
+ });
+ if (!response.ok) throw new Error('Failed to fetch recent sheets');
+ return await response.json();
+}
+
+/**
+ * Fetch spreadsheet data via protected endpoint
+ */
+export async function getSpreadsheetDataClient(refreshToken: string, sheetId: string, range: string = 'A1:Z10') {
+ const response = await fetch(`/private/api/google/sheets/${sheetId}/data?range=${encodeURIComponent(range)}`, {
+ headers: { Authorization: `Bearer ${refreshToken}` }
+ });
+ if (!response.ok) throw new Error('Failed to fetch spreadsheet data');
+ return await response.json();
+}
diff --git a/src/lib/google/sheets/index.ts b/src/lib/google/sheets/index.ts
deleted file mode 100644
index 8eaf173..0000000
--- a/src/lib/google/sheets/index.ts
+++ /dev/null
@@ -1,77 +0,0 @@
-import { google } from 'googleapis';
-import { getAuthenticatedClient } from '../auth/server.js';
-
-export interface GoogleSheet {
- id: string;
- name: string;
- modifiedTime: string;
- webViewLink: string;
-}
-
-export interface SheetData {
- values: string[][];
-}
-
-/**
- * Get a list of recent Google Sheets
- * @param refreshToken - Google refresh token
- * @param limit - Maximum number of sheets to return
- * @returns List of Google Sheets
- */
-export async function getRecentSpreadsheets(refreshToken: string, limit: number = 10): Promise {
- const oauth = getAuthenticatedClient(refreshToken);
- const drive = google.drive({ version: 'v3', auth: oauth });
-
- const response = await drive.files.list({
- q: "mimeType='application/vnd.google-apps.spreadsheet'",
- orderBy: 'modifiedTime desc',
- pageSize: limit,
- fields: 'files(id,name,modifiedTime,webViewLink)'
- });
-
- return response.data.files?.map(file => ({
- id: file.id!,
- name: file.name!,
- modifiedTime: file.modifiedTime!,
- webViewLink: file.webViewLink!
- })) || [];
-}
-
-/**
- * Get data from a Google Sheet
- * @param refreshToken - Google refresh token
- * @param spreadsheetId - ID of the spreadsheet
- * @param range - Cell range to retrieve (default: A1:Z10)
- * @returns Sheet data as a 2D array
- */
-export async function getSpreadsheetData(refreshToken: string, spreadsheetId: string, range: string = 'A1:Z10'): Promise {
- const oauth = getAuthenticatedClient(refreshToken);
- const sheets = google.sheets({ version: 'v4', auth: oauth });
-
- const response = await sheets.spreadsheets.values.get({
- spreadsheetId,
- range
- });
-
- return {
- values: response.data.values || []
- };
-}
-
-/**
- * Get metadata about a Google Sheet
- * @param refreshToken - Google refresh token
- * @param spreadsheetId - ID of the spreadsheet
- * @returns Spreadsheet metadata
- */
-export async function getSpreadsheetInfo(refreshToken: string, spreadsheetId: string) {
- const oauth = getAuthenticatedClient(refreshToken);
- const sheets = google.sheets({ version: 'v4', auth: oauth });
-
- const response = await sheets.spreadsheets.get({
- spreadsheetId,
- fields: 'properties.title,sheets.properties(title,sheetId)'
- });
-
- return response.data;
-}
diff --git a/src/lib/google/sheets/server.ts b/src/lib/google/sheets/server.ts
new file mode 100644
index 0000000..57a7268
--- /dev/null
+++ b/src/lib/google/sheets/server.ts
@@ -0,0 +1,89 @@
+import { google } from 'googleapis';
+import { getAuthenticatedClient } from '../auth/server.js';
+
+export interface GoogleSheet {
+ id: string;
+ name: string;
+ modifiedTime: string;
+ webViewLink: string;
+}
+
+export interface SheetData {
+ values: string[][];
+}
+
+/**
+ * Get a list of recent Google Sheets
+ * @param refreshToken - Google refresh token
+ * @param limit - Maximum number of sheets to return
+ * @returns List of Google Sheets
+ */
+export async function getRecentSpreadsheets(
+ refreshToken: string,
+ limit: number = 10
+): Promise {
+ const oauth = getAuthenticatedClient(refreshToken);
+ const drive = google.drive({ version: 'v3', auth: oauth });
+
+ const response = await drive.files.list({
+ q: "mimeType='application/vnd.google-apps.spreadsheet'",
+ orderBy: 'modifiedTime desc',
+ pageSize: limit,
+ fields: 'files(id,name,modifiedTime,webViewLink)'
+ });
+
+ return (
+ response.data.files?.map(file => ({
+ id: file.id!, // eslint-disable-line @typescript-eslint/no-non-null-assertion
+ name: file.name!,
+ modifiedTime: file.modifiedTime!,
+ webViewLink: file.webViewLink!
+ })) || []
+ );
+}
+
+/**
+ * Get data from a Google Sheet
+ * @param refreshToken - Google refresh token
+ * @param spreadsheetId - ID of the spreadsheet
+ * @param range - Cell range to retrieve (default: A1:Z10)
+ * @returns Sheet data as a 2D array
+ */
+export async function getSpreadsheetData(
+ refreshToken: string,
+ spreadsheetId: string,
+ range: string = 'A1:Z10'
+): Promise {
+ const oauth = getAuthenticatedClient(refreshToken);
+ const sheets = google.sheets({ version: 'v4', auth: oauth });
+
+ const response = await sheets.spreadsheets.values.get({
+ spreadsheetId,
+ range
+ });
+
+ return {
+ values: response.data.values || []
+ };
+}
+
+/**
+ * Get metadata about a Google Sheet
+ * @param refreshToken - Google refresh token
+ * @param spreadsheetId - ID of the spreadsheet
+ * @returns Spreadsheet metadata
+ */
+export async function getSpreadsheetInfo(
+ refreshToken: string,
+ spreadsheetId: string
+) {
+ const oauth = getAuthenticatedClient(refreshToken);
+ const sheets = google.sheets({ version: 'v4', auth: oauth });
+
+ const response = await sheets.spreadsheets.get({
+ spreadsheetId,
+ fields: 'properties.title,sheets.properties(title,sheetId)'
+ });
+
+ return response.data;
+}
diff --git a/src/lib/index.ts b/src/lib/index.ts
deleted file mode 100644
index 856f2b6..0000000
--- a/src/lib/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-// place files you want to import through the `$lib` alias in this folder.
diff --git a/src/lib/sheets.ts b/src/lib/sheets.ts
deleted file mode 100644
index b8dcc4c..0000000
--- a/src/lib/sheets.ts
+++ /dev/null
@@ -1,58 +0,0 @@
-import { google } from 'googleapis';
-import { getAuthenticatedClient } from './google-server.js';
-
-export interface GoogleSheet {
- id: string;
- name: string;
- modifiedTime: string;
- webViewLink: string;
-}
-
-export interface SheetData {
- values: string[][];
-}
-
-export async function getRecentSpreadsheets(refreshToken: string, limit: number = 10): Promise {
- const oauth = getAuthenticatedClient(refreshToken);
- const drive = google.drive({ version: 'v3', auth: oauth });
-
- const response = await drive.files.list({
- q: "mimeType='application/vnd.google-apps.spreadsheet'",
- orderBy: 'modifiedTime desc',
- pageSize: limit,
- fields: 'files(id,name,modifiedTime,webViewLink)'
- });
-
- return response.data.files?.map(file => ({
- id: file.id!,
- name: file.name!,
- modifiedTime: file.modifiedTime!,
- webViewLink: file.webViewLink!
- })) || [];
-}
-
-export async function getSpreadsheetData(refreshToken: string, spreadsheetId: string, range: string = 'A1:Z10'): Promise {
- const oauth = getAuthenticatedClient(refreshToken);
- const sheets = google.sheets({ version: 'v4', auth: oauth });
-
- const response = await sheets.spreadsheets.values.get({
- spreadsheetId,
- range
- });
-
- return {
- values: response.data.values || []
- };
-}
-
-export async function getSpreadsheetInfo(refreshToken: string, spreadsheetId: string) {
- const oauth = getAuthenticatedClient(refreshToken);
- const sheets = google.sheets({ version: 'v4', auth: oauth });
-
- const response = await sheets.spreadsheets.get({
- spreadsheetId,
- fields: 'properties.title,sheets.properties(title,sheetId)'
- });
-
- return response.data;
-}
diff --git a/src/lib/types.ts b/src/lib/types/types.ts
similarity index 100%
rename from src/lib/types.ts
rename to src/lib/types/types.ts
diff --git a/src/routes/api/auth/refresh/+server.ts b/src/routes/api/auth/refresh/+server.ts
index 83eecbb..cfbd733 100644
--- a/src/routes/api/auth/refresh/+server.ts
+++ b/src/routes/api/auth/refresh/+server.ts
@@ -1,6 +1,6 @@
import { json } from '@sveltejs/kit';
import type { RequestHandler } from './$types';
-import { authServer } from '$lib/google/index.js';
+import { getOAuthClient } from '$lib/google/auth/server.js';
export const POST: RequestHandler = async ({ request }) => {
try {
@@ -10,7 +10,7 @@ export const POST: RequestHandler = async ({ request }) => {
return json({ error: 'Refresh token is required' }, { status: 400 });
}
- const oauth = authServer.getOAuthClient();
+ const oauth = getOAuthClient();
oauth.setCredentials({ refresh_token: refreshToken });
const { credentials } = await oauth.refreshAccessToken();
diff --git a/src/routes/api/events/+server.ts b/src/routes/api/events/+server.ts
index a352d1f..e69de29 100644
--- a/src/routes/api/events/+server.ts
+++ b/src/routes/api/events/+server.ts
@@ -1,21 +0,0 @@
-import { json } from '@sveltejs/kit';
-import type { RequestHandler } from './$types';
-
-export const GET: RequestHandler = async ({ locals }) => {
- try {
- const { data: events, error } = await locals.supabase
- .from('events')
- .select('*')
- .order('date', { ascending: false });
-
- if (error) {
- console.error('Error fetching events:', error);
- return json({ error: error.message }, { status: 500 });
- }
-
- return json({ events });
- } catch (err) {
- console.error('Error in events API:', err);
- return json({ error: 'Internal server error' }, { status: 500 });
- }
-};
diff --git a/src/routes/auth/google/+server.ts b/src/routes/auth/google/+server.ts
index 49205f7..71ea732 100644
--- a/src/routes/auth/google/+server.ts
+++ b/src/routes/auth/google/+server.ts
@@ -1,8 +1,8 @@
import { redirect } from '@sveltejs/kit';
import type { RequestHandler } from './$types';
-import { authServer } from '$lib/google/index.js';
+import { createAuthUrl } from '$lib/google/auth/server.js';
export const GET: RequestHandler = () => {
- const authUrl = authServer.createAuthUrl();
+ const authUrl = createAuthUrl();
throw redirect(302, authUrl);
};
diff --git a/src/routes/auth/google/callback/+server.ts b/src/routes/auth/google/callback/+server.ts
index d369a58..584aa48 100644
--- a/src/routes/auth/google/callback/+server.ts
+++ b/src/routes/auth/google/callback/+server.ts
@@ -1,6 +1,6 @@
import { redirect } from '@sveltejs/kit';
import type { RequestHandler } from './$types';
-import { authServer } from '$lib/google/index.js';
+import { googleAuthServer } from '$lib/google/server.ts';
export const GET: RequestHandler = async ({ url }) => {
try {
@@ -17,7 +17,7 @@ export const GET: RequestHandler = async ({ url }) => {
}
// Exchange code for tokens
- const oauth = authServer.getOAuthClient();
+ const oauth = googleAuthServer.getOAuthClient();
const { tokens } = await oauth.getToken(code);
if (!tokens.refresh_token || !tokens.access_token) {
diff --git a/src/routes/private/api/google/auth/refresh/+server.ts b/src/routes/private/api/google/auth/refresh/+server.ts
index 5190a36..ca057c8 100644
--- a/src/routes/private/api/google/auth/refresh/+server.ts
+++ b/src/routes/private/api/google/auth/refresh/+server.ts
@@ -1,6 +1,6 @@
import { json } from '@sveltejs/kit';
import type { RequestHandler } from './$types';
-import { getOAuthClient } from '$lib/google/server.js';
+import { googleAuthServer } from '$lib/google/server.ts';
export const POST: RequestHandler = async ({ request }) => {
try {
@@ -10,7 +10,7 @@ export const POST: RequestHandler = async ({ request }) => {
return json({ error: 'Refresh token is required' }, { status: 400 });
}
- const oauth = getOAuthClient();
+ const oauth = googleAuthServer.getOAuthClient();
oauth.setCredentials({ refresh_token: refreshToken });
const { credentials } = await oauth.refreshAccessToken();
diff --git a/src/routes/private/api/google/auth/userinfo/+server.ts b/src/routes/private/api/google/auth/userinfo/+server.ts
index 3c978d7..2e44e75 100644
--- a/src/routes/private/api/google/auth/userinfo/+server.ts
+++ b/src/routes/private/api/google/auth/userinfo/+server.ts
@@ -1,6 +1,6 @@
import { json } from '@sveltejs/kit';
import type { RequestHandler } from './$types';
-import { getOAuthClient } from '$lib/google/server.js';
+import { googleAuthServer } from '$lib/google/server.ts';
import { google } from 'googleapis';
export const GET: RequestHandler = async ({ request }) => {
@@ -14,7 +14,7 @@ export const GET: RequestHandler = async ({ request }) => {
const accessToken = authHeader.slice(7);
// Create OAuth client with the token
- const oauth = getOAuthClient();
+ const oauth = googleAuthServer.getOAuthClient();
oauth.setCredentials({ access_token: accessToken });
// Call the userinfo endpoint to get user details
diff --git a/src/routes/private/api/google/sheets/[sheetId]/data/+server.ts b/src/routes/private/api/google/sheets/[sheetId]/data/+server.ts
index 3126261..e87c1ff 100644
--- a/src/routes/private/api/google/sheets/[sheetId]/data/+server.ts
+++ b/src/routes/private/api/google/sheets/[sheetId]/data/+server.ts
@@ -1,6 +1,6 @@
import { json } from '@sveltejs/kit';
import type { RequestHandler } from './$types';
-import { getSpreadsheetData } from '$lib/google/server.js';
+import { sheets } from '$lib/google/index.js';
export const GET: RequestHandler = async ({ params, request }) => {
try {
@@ -12,7 +12,7 @@ export const GET: RequestHandler = async ({ params, request }) => {
}
const refreshToken = authHeader.slice(7);
- const sheetData = await getSpreadsheetData(refreshToken, sheetId, 'A1:Z10');
+ const sheetData = await sheets.getSpreadsheetData(refreshToken, sheetId, 'A1:Z10');
return json(sheetData);
} catch (error) {
diff --git a/src/routes/private/api/google/sheets/recent/+server.ts b/src/routes/private/api/google/sheets/recent/+server.ts
index d39f4e8..ed01813 100644
--- a/src/routes/private/api/google/sheets/recent/+server.ts
+++ b/src/routes/private/api/google/sheets/recent/+server.ts
@@ -1,6 +1,6 @@
import { json } from '@sveltejs/kit';
import type { RequestHandler } from './$types';
-import { getRecentSpreadsheets } from '$lib/google/server.js';
+import { sheets } from '$lib/google/index.js';
export const GET: RequestHandler = async ({ request }) => {
try {
@@ -10,7 +10,7 @@ export const GET: RequestHandler = async ({ request }) => {
}
const refreshToken = authHeader.slice(7);
- const spreadsheets = await getRecentSpreadsheets(refreshToken, 20);
+ const spreadsheets = await sheets.getRecentSpreadsheets(refreshToken, 20);
return json(spreadsheets);
} catch (error) {
diff --git a/src/routes/private/events/+page.server.ts b/src/routes/private/events/+page.server.ts
new file mode 100644
index 0000000..e69de29
diff --git a/src/routes/private/events/+page.svelte b/src/routes/private/events/+page.svelte
index ad261e2..1664850 100644
--- a/src/routes/private/events/+page.svelte
+++ b/src/routes/private/events/+page.svelte
@@ -1,85 +1,24 @@
All Events