Skip to content

Commit 13fb61b

Browse files
committed
Fix saving to Google Drive on Edge + issues with naming / adding to folder
1 parent 6b91785 commit 13fb61b

File tree

3 files changed

+116
-50
lines changed

3 files changed

+116
-50
lines changed

src/manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"name": "__MSG_extName__",
44
"description": "__MSG_extDesc__",
55
"default_locale": "en",
6-
"version": "4.0.4",
6+
"version": "4.0.5",
77
"background": {
88
"service_worker": "background.bundle.js"
99
},

src/pages/Background/drive/handleSaveToDrive.js

Lines changed: 42 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -53,21 +53,19 @@ const getAuthTokenFromStorage = async () => {
5353
try {
5454
payload = JSON.parse(atob(token.split(".")[1]));
5555
} catch {
56-
chrome.identity.getAuthToken({ interactive: true }, (newToken) => {
57-
if (chrome.runtime.lastError)
58-
reject(new Error(chrome.runtime.lastError));
59-
else resolve(newToken);
60-
});
56+
// Token is invalid, sign in again
57+
const newToken = await signIn();
58+
if (!newToken) reject(new Error("Sign-in failed"));
59+
else resolve(newToken);
6160
return;
6261
}
6362

6463
const exp = payload.exp * 1000;
6564
if (Date.now() >= exp) {
66-
chrome.identity.getAuthToken({ interactive: true }, (newToken) => {
67-
if (chrome.runtime.lastError)
68-
reject(new Error(chrome.runtime.lastError));
69-
else resolve(newToken);
70-
});
65+
// Token is expired, sign in again
66+
const newToken = await signIn();
67+
if (!newToken) reject(new Error("Sign-in failed"));
68+
else resolve(newToken);
7169
} else {
7270
resolve(token);
7371
}
@@ -80,46 +78,53 @@ const saveToDrive = async (videoBlob, fileName) => {
8078
const token = await getAuthTokenFromStorage();
8179
if (!token) throw new Error("Sign-in failed");
8280

83-
// Upload the raw media
81+
const folderId = await findOrCreateScreenityFolder(token);
82+
83+
const metadata = {
84+
name: fileName,
85+
parents: [folderId],
86+
};
87+
88+
const boundary = "-------314159265358979323846";
89+
const delimiter = `\r\n--${boundary}\r\n`;
90+
const close_delim = `\r\n--${boundary}--`;
91+
92+
const reader = new FileReader();
93+
94+
const base64Data = await new Promise((resolve) => {
95+
reader.onload = (e) => resolve(e.target.result.split(",")[1]);
96+
reader.readAsDataURL(videoBlob);
97+
});
98+
99+
const multipartBody =
100+
delimiter +
101+
`Content-Type: application/json; charset=UTF-8\r\n\r\n` +
102+
JSON.stringify(metadata) +
103+
delimiter +
104+
`Content-Type: ${videoBlob.type}\r\n` +
105+
`Content-Transfer-Encoding: base64\r\n\r\n` +
106+
base64Data +
107+
close_delim;
108+
84109
const uploadResponse = await fetch(
85-
"https://www.googleapis.com/upload/drive/v3/files?uploadType=media",
110+
"https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart",
86111
{
87112
method: "POST",
88113
headers: {
89114
Authorization: `Bearer ${token}`,
90-
"Content-Type": videoBlob.type,
115+
"Content-Type": `multipart/related; boundary=${boundary}`,
91116
},
92-
body: videoBlob,
117+
body: multipartBody,
93118
}
94119
);
95120

96-
if (!uploadResponse.ok)
121+
if (!uploadResponse.ok) {
97122
throw new Error(`Upload failed: ${uploadResponse.status}`);
123+
}
98124

99125
const { id: fileId } = await uploadResponse.json();
100-
if (!fileId) throw new Error("File ID is undefined");
101-
102-
// Add metadata and move to folder
103-
const folderId = await findOrCreateScreenityFolder(token);
104-
const metadataResponse = await fetch(
105-
`https://www.googleapis.com/drive/v3/files/${fileId}`,
106-
{
107-
method: "PATCH",
108-
headers: {
109-
Authorization: `Bearer ${token}`,
110-
"Content-Type": "application/json; charset=UTF-8",
111-
},
112-
body: JSON.stringify({
113-
name: fileName,
114-
parents: [folderId],
115-
}),
116-
}
117-
);
118-
119-
if (!metadataResponse.ok)
120-
throw new Error(`Metadata update failed: ${metadataResponse.status}`);
126+
if (!fileId) throw new Error("File ID missing after upload");
121127

122-
// Open the file in Drive
123128
chrome.tabs.create({
124129
url: `https://drive.google.com/file/d/${fileId}/view`,
125130
});

src/pages/Background/modules/signIn.js

Lines changed: 73 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,84 @@
1-
const signIn = async () => {
2-
try {
3-
const token = await chrome.identity.getAuthToken({ interactive: true });
1+
const isEdge = navigator.userAgent.includes("Edg");
42

5-
if (!token) {
6-
throw new Error("User cancelled sign-in or failed to get token");
7-
}
3+
const EDGE_CLIENT_ID =
4+
"560517327251-856rbcshgori6mft9slnsaq34p21td3n.apps.googleusercontent.com";
5+
const REDIRECT_URI = isEdge ? chrome.identity.getRedirectURL() : "";
6+
7+
const signInEdge = async () => {
8+
const authUrl = new URL("https://accounts.google.com/o/oauth2/v2/auth");
9+
authUrl.searchParams.set("client_id", EDGE_CLIENT_ID);
10+
authUrl.searchParams.set("response_type", "token");
11+
authUrl.searchParams.set("redirect_uri", REDIRECT_URI);
12+
authUrl.searchParams.set(
13+
"scope",
14+
"https://www.googleapis.com/auth/drive.file"
15+
);
16+
17+
return new Promise((resolve, reject) => {
18+
chrome.identity.launchWebAuthFlow(
19+
{
20+
url: authUrl.href,
21+
interactive: true,
22+
},
23+
async (redirectUrl) => {
24+
if (chrome.runtime.lastError) {
25+
reject(new Error(chrome.runtime.lastError.message));
26+
return;
27+
}
828

9-
// Save token to storage
10-
await new Promise((resolve) =>
11-
chrome.storage.local.set({ token: token.token }, () => resolve())
29+
if (!redirectUrl) {
30+
reject(new Error("User cancelled sign-in or failed to get token"));
31+
return;
32+
}
33+
34+
// Extract token from redirect URL
35+
const url = new URL(redirectUrl);
36+
const params = new URLSearchParams(url.hash.substring(1));
37+
const token = params.get("access_token");
38+
39+
if (!token) {
40+
reject(new Error("Failed to extract token from redirect"));
41+
return;
42+
}
43+
44+
// Save token to storage
45+
await new Promise((res) =>
46+
chrome.storage.local.set({ token }, () => res())
47+
);
48+
49+
resolve(token);
50+
}
1251
);
52+
});
53+
};
1354

14-
const userInfo = await chrome.identity.getProfileUserInfo();
55+
const signInChrome = async () => {
56+
const token = await chrome.identity.getAuthToken({ interactive: true });
1557

16-
return token.token; // Return the token if sign-in is successful
58+
if (!token) {
59+
throw new Error("User cancelled sign-in or failed to get token");
60+
}
61+
62+
// Save token to storage
63+
await new Promise((resolve) =>
64+
chrome.storage.local.set({ token: token.token }, () => resolve())
65+
);
66+
67+
//const userInfo = await chrome.identity.getProfileUserInfo();
68+
69+
return token.token;
70+
};
71+
72+
const signIn = async () => {
73+
try {
74+
if (isEdge) {
75+
return await signInEdge();
76+
} else {
77+
return await signInChrome();
78+
}
1779
} catch (error) {
1880
console.error("Error signing in:", error.message);
1981
return null;
20-
throw error; // Reject the Promise if sign-in fails
2182
}
2283
};
2384

0 commit comments

Comments
 (0)