hoangthiencm commited on
Commit
a835a2e
·
verified ·
1 Parent(s): fdb7ab1

Update server.js

Browse files
Files changed (1) hide show
  1. server.js +28 -25
server.js CHANGED
@@ -8,7 +8,6 @@ const cors = require('cors');
8
  const app = express();
9
  const upload = multer({ dest: 'uploads/' });
10
 
11
- // Cho phép CORS
12
  app.use(cors({ origin: '*', credentials: true, allowedHeaders: ['Content-Type', 'Authorization', 'x-refresh-token'] }));
13
  app.use(express.json());
14
 
@@ -16,19 +15,15 @@ const GOOGLE_CLIENT_ID = process.env.GOOGLE_CLIENT_ID;
16
  const GOOGLE_CLIENT_SECRET = process.env.GOOGLE_CLIENT_SECRET;
17
  const REDIRECT_URI = process.env.REDIRECT_URI;
18
 
19
- // Biến lưu token tạm thời (sẽ mất khi server restart)
20
  let adminRefreshToken = null;
21
 
22
  const oauth2Client = new google.auth.OAuth2(GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, REDIRECT_URI);
23
 
24
- // Hàm lấy Access Token (Tự động khôi phục từ Header nếu biến local bị mất)
25
  async function getAccessToken(req) {
26
- // 1. Nếu biến server null, thử lấy từ Header của request
27
  if (!adminRefreshToken && req && req.headers['x-refresh-token']) {
28
- console.log('Server restart detected. Restoring session from client header...');
29
  adminRefreshToken = req.headers['x-refresh-token'];
30
  }
31
-
32
  if (!adminRefreshToken) throw new Error('Chưa đăng nhập Admin (Session expired)');
33
 
34
  oauth2Client.setCredentials({ refresh_token: adminRefreshToken });
@@ -36,50 +31,59 @@ async function getAccessToken(req) {
36
  return credentials.access_token;
37
  }
38
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
  // 1. Login
40
  app.post('/api/oauth/token', async (req, res) => {
41
  try {
42
  const { code, redirect_uri } = req.body;
43
  const client = new google.auth.OAuth2(GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, redirect_uri || REDIRECT_URI);
44
  const { tokens } = await client.getToken(code);
45
- if (tokens.refresh_token) {
46
- adminRefreshToken = tokens.refresh_token;
47
- }
48
  res.json(tokens);
49
  } catch (error) {
50
  res.status(500).json({ error: error.message });
51
  }
52
  });
53
 
54
- // 2. Upload
55
  app.post('/api/upload', upload.array('files'), async (req, res) => {
56
  try {
57
- // Truyền req vào để hàm getAccessToken tự tìm token trong header
58
- await getAccessToken(req);
59
-
60
  const drive = google.drive({ version: 'v3', auth: oauth2Client });
61
- const { docName } = req.body;
62
 
63
- // Tạo Folder
64
- const fileMetadata = {
65
- name: `${docName} - ${Date.now()}`,
66
- mimeType: 'application/vnd.google-apps.folder'
67
- };
68
- const folder = await drive.files.create({ resource: fileMetadata, fields: 'id' });
69
- const folderId = folder.data.id;
70
 
71
  const uploadedFiles = [];
72
  for (const file of req.files) {
73
  const media = { mimeType: file.mimetype, body: fs.createReadStream(file.path) };
74
  const driveFile = await drive.files.create({
75
- resource: { name: file.originalname, parents: [folderId] },
76
  media: media,
77
  fields: 'id, name, webViewLink, webContentLink'
78
  });
79
  uploadedFiles.push(driveFile.data);
80
  fs.unlinkSync(file.path);
81
  }
82
- res.json({ folderId, files: uploadedFiles });
83
  } catch (error) {
84
  console.error(error);
85
  res.status(500).json({ error: error.message });
@@ -89,8 +93,7 @@ app.post('/api/upload', upload.array('files'), async (req, res) => {
89
  // 3. Delete
90
  app.delete('/api/delete/:fileId', async (req, res) => {
91
  try {
92
- await getAccessToken(req); // Truyền req để khôi phục token
93
-
94
  const drive = google.drive({ version: 'v3', auth: oauth2Client });
95
  await drive.files.delete({ fileId: req.params.fileId });
96
  res.json({ success: true });
 
8
  const app = express();
9
  const upload = multer({ dest: 'uploads/' });
10
 
 
11
  app.use(cors({ origin: '*', credentials: true, allowedHeaders: ['Content-Type', 'Authorization', 'x-refresh-token'] }));
12
  app.use(express.json());
13
 
 
15
  const GOOGLE_CLIENT_SECRET = process.env.GOOGLE_CLIENT_SECRET;
16
  const REDIRECT_URI = process.env.REDIRECT_URI;
17
 
 
18
  let adminRefreshToken = null;
19
 
20
  const oauth2Client = new google.auth.OAuth2(GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, REDIRECT_URI);
21
 
 
22
  async function getAccessToken(req) {
 
23
  if (!adminRefreshToken && req && req.headers['x-refresh-token']) {
24
+ console.log('Restoring session from client header...');
25
  adminRefreshToken = req.headers['x-refresh-token'];
26
  }
 
27
  if (!adminRefreshToken) throw new Error('Chưa đăng nhập Admin (Session expired)');
28
 
29
  oauth2Client.setCredentials({ refresh_token: adminRefreshToken });
 
31
  return credentials.access_token;
32
  }
33
 
34
+ // Hàm Tìm hoặc Tạo Folder (Đã khôi phục)
35
+ async function findOrCreateFolder(drive, name, parentId = 'root') {
36
+ const q = `mimeType='application/vnd.google-apps.folder' and name='${name}' and '${parentId}' in parents and trashed=false`;
37
+ const res = await drive.files.list({ q, fields: 'files(id, name)' });
38
+
39
+ if (res.data.files.length > 0) return res.data.files[0];
40
+
41
+ const folder = await drive.files.create({
42
+ resource: { name, mimeType: 'application/vnd.google-apps.folder', parents: [parentId] },
43
+ fields: 'id, name'
44
+ });
45
+ return folder.data;
46
+ }
47
+
48
  // 1. Login
49
  app.post('/api/oauth/token', async (req, res) => {
50
  try {
51
  const { code, redirect_uri } = req.body;
52
  const client = new google.auth.OAuth2(GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, redirect_uri || REDIRECT_URI);
53
  const { tokens } = await client.getToken(code);
54
+ if (tokens.refresh_token) adminRefreshToken = tokens.refresh_token;
 
 
55
  res.json(tokens);
56
  } catch (error) {
57
  res.status(500).json({ error: error.message });
58
  }
59
  });
60
 
61
+ // 2. Upload (Đã sửa logic tạo thư mục lồng nhau)
62
  app.post('/api/upload', upload.array('files'), async (req, res) => {
63
  try {
64
+ await getAccessToken(req); // Khôi phục session
 
 
65
  const drive = google.drive({ version: 'v3', auth: oauth2Client });
 
66
 
67
+ const { docName, type, month } = req.body;
68
+
69
+ // Tạo cấu trúc thư mục
70
+ const rootFolder = await findOrCreateFolder(drive, 'QLVB-DATA');
71
+ const typeFolder = await findOrCreateFolder(drive, type === 'incoming' ? 'VanBanDen' : 'VanBanDi', rootFolder.id);
72
+ const monthFolder = await findOrCreateFolder(drive, month || 'Khac', typeFolder.id);
73
+ const docFolder = await findOrCreateFolder(drive, `${docName} - ${Date.now()}`, monthFolder.id);
74
 
75
  const uploadedFiles = [];
76
  for (const file of req.files) {
77
  const media = { mimeType: file.mimetype, body: fs.createReadStream(file.path) };
78
  const driveFile = await drive.files.create({
79
+ resource: { name: file.originalname, parents: [docFolder.id] },
80
  media: media,
81
  fields: 'id, name, webViewLink, webContentLink'
82
  });
83
  uploadedFiles.push(driveFile.data);
84
  fs.unlinkSync(file.path);
85
  }
86
+ res.json({ folderId: docFolder.id, files: uploadedFiles });
87
  } catch (error) {
88
  console.error(error);
89
  res.status(500).json({ error: error.message });
 
93
  // 3. Delete
94
  app.delete('/api/delete/:fileId', async (req, res) => {
95
  try {
96
+ await getAccessToken(req);
 
97
  const drive = google.drive({ version: 'v3', auth: oauth2Client });
98
  await drive.files.delete({ fileId: req.params.fileId });
99
  res.json({ success: true });