File size: 3,179 Bytes
2a582da
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
require('dotenv').config();
const express = require('express');
const path = require('path');
const cors = require('cors');
const { createClient } = require('@supabase/supabase-js');
const { google } = require('googleapis');
const multer = require('multer');
const stream = require('stream');

const app = express();
const PORT = process.env.PORT || 7860;
const upload = multer({ storage: multer.memoryStorage() });

app.use(cors());
app.use(express.json());
app.use(express.static(path.join(__dirname, '../public')));

const supabase = createClient(
  process.env.SUPABASE_URL,
  process.env.SUPABASE_SERVICE_KEY
);

const oauth2Client = new google.auth.OAuth2(
  process.env.GOOGLE_CLIENT_ID,
  process.env.GOOGLE_CLIENT_SECRET,
  process.env.GOOGLE_REDIRECT_URI
);

// 1. Connect Drive
app.get('/api/drive/connect', (req, res) => {
  const { user_id } = req.query;
  const url = oauth2Client.generateAuthUrl({
    access_type: 'offline',
    scope: ['https://www.googleapis.com/auth/drive.file'],
    state: user_id, 
    prompt: 'consent'
  });
  res.redirect(url);
});

// 2. Callback
app.get('/api/drive/callback', async (req, res) => {
  const { code, state: user_id } = req.query;
  try {
    const { tokens } = await oauth2Client.getToken(code);
    oauth2Client.setCredentials(tokens);

    const drive = google.drive({ version: 'v3', auth: oauth2Client });
    const folder = await drive.files.create({
      resource: { name: 'AI Generations (App)', mimeType: 'application/vnd.google-apps.folder' },
      fields: 'id'
    });

    await supabase.from('drive_accounts').upsert({
      user_id: user_id,
      folder_id: folder.data.id,
      refresh_token: tokens.refresh_token
    });

    res.redirect('/?drive_success=true');
  } catch (error) {
    console.error(error);
    res.redirect('/?drive_error=true');
  }
});

// 3. Upload
app.post('/api/drive/upload', upload.single('image'), async (req, res) => {
  const token = req.headers.authorization?.split(' ')[1];
  const { data: { user } } = await supabase.auth.getUser(token);
  if (!user) return res.status(401).json({ error: 'Unauthorized' });

  const { data: driveData } = await supabase
    .from('drive_accounts').select('*').eq('user_id', user.id).single();

  if (!driveData) return res.status(400).json({ error: 'Drive not connected' });

  oauth2Client.setCredentials({ refresh_token: driveData.refresh_token });
  const drive = google.drive({ version: 'v3', auth: oauth2Client });
  const bufferStream = new stream.PassThrough();
  bufferStream.end(req.file.buffer);

  const file = await drive.files.create({
    resource: { name: `gen_${Date.now()}.png`, parents: [driveData.folder_id] },
    media: { mimeType: 'image/png', body: bufferStream },
    fields: 'id, webViewLink'
  });

  await supabase.from('generations').insert({
      user_id: user.id,
      prompt: req.body.prompt,
      drive_file_id: file.data.id,
      drive_view_link: file.data.webViewLink
  });

  res.json({ success: true, link: file.data.webViewLink });
});

app.get('*', (req, res) => res.sendFile(path.join(__dirname, '../public/index.html')));
app.listen(PORT, '0.0.0.0', () => console.log(`Running on ${PORT}`));