Skip to content

Commit

Permalink
fix: 修复中文名称
Browse files Browse the repository at this point in the history
  • Loading branch information
vcheckzen committed Sep 19, 2024
1 parent 70c3a4c commit cbf10dd
Show file tree
Hide file tree
Showing 5 changed files with 14,549 additions and 405 deletions.
194 changes: 101 additions & 93 deletions back-end-cf/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,21 @@
* EXPOSE_PASSWD: 覆盖 EXPOSE_PATH 目录密码,优先级:本目录密码 > EXPOSE_PASSWD > EXPORSE_PATH 目录密码;填写后访问速度稍快,但不便于更改
*/
const IS_CN = 0;
const EXPOSE_PATH = "";
const ONEDRIVE_REFRESHTOKEN = "";
const PASSWD_FILENAME = ".password";
const EXPOSE_PATH = '';
const ONEDRIVE_REFRESHTOKEN = '';
const PASSWD_FILENAME = '.password';
const PROTECTED_LAYERS = -1;
const EXPOSE_PASSWD = "";
const EXPOSE_PASSWD = '';

addEventListener('scheduled', event => {
addEventListener('scheduled', (event) => {
event.waitUntil(fetchAccessToken(/* event.scheduledTime */));
});

addEventListener("fetch", (event) => {
addEventListener('fetch', (event) => {
try {
return event.respondWith(handleRequest(event.request));
} catch (e) {
return event.respondWith(new Response("Error thrown " + e.message));
return event.respondWith(new Response('Error thrown ' + e.message));
}
});

Expand All @@ -30,87 +30,90 @@ const OAUTH = {
refreshToken: ONEDRIVE_REFRESHTOKEN,
clientId: clientId,
clientSecret: clientSecret,
oauthUrl: loginHost + "/common/oauth2/v2.0/",
apiUrl: apiHost + "/v1.0/me/drive/root",
scope: apiHost + "/Files.ReadWrite.All offline_access",
oauthUrl: loginHost + '/common/oauth2/v2.0/',
apiUrl: apiHost + '/v1.0/me/drive/root',
scope: apiHost + '/Files.ReadWrite.All offline_access',
};

const PATH_AUTH_STATES = Object.freeze({
NO_PW_FILE: Symbol("NO_PW_FILE"),
PW_CORRECT: Symbol("PW_CORRECT"),
PW_ERROR: Symbol("PW_ERROR")
NO_PW_FILE: Symbol('NO_PW_FILE'),
PW_CORRECT: Symbol('PW_CORRECT'),
PW_ERROR: Symbol('PW_ERROR'),
});

async function handleRequest(request) {
let queryString, querySplited, requestPath;
let abnormalWay = false;
const returnHeaders = {
"Access-Control-Allow-Origin": "*",
"Cache-Control": "max-age=3600",
"Content-Type": "application/json; charset=utf-8",
'Access-Control-Allow-Origin': '*',
'Cache-Control': 'max-age=3600',
'Content-Type': 'application/json; charset=utf-8',
};
if (request.url.includes("?")) {
queryString = decodeURIComponent(request.url.split("?")[1]);
} else if (request.url.split("/").pop().includes(".")) {
if (request.url.includes('?')) {
queryString = decodeURIComponent(request.url.split('?')[1]);
} else if (request.url.split('/').pop().includes('.')) {
queryString = decodeURIComponent(
"file=/" + request.url.split("://")[1].split(/\/(.+)/)[1]
'file=/' + request.url.split('://')[1].split(/\/(.+)/)[1]
);
abnormalWay = true;
}
if (queryString) querySplited = queryString.split("=");
if ((querySplited && querySplited[0] === "file") || abnormalWay) {
if (queryString) querySplited = queryString.split('=');
if ((querySplited && querySplited[0] === 'file') || abnormalWay) {
const file = querySplited[1];
const fileName = file.split("/").pop();
const fileName = file.split('/').pop();
if (fileName.toLowerCase() === PASSWD_FILENAME.toLowerCase())
return Response.redirect(
"https://www.baidu.com/s?wd=%E6%80%8E%E6%A0%B7%E7%9B%97%E5%8F%96%E5%AF%86%E7%A0%81",
'https://www.baidu.com/s?wd=%E6%80%8E%E6%A0%B7%E7%9B%97%E5%8F%96%E5%AF%86%E7%A0%81',
301
);
requestPath = file.replace("/" + fileName, "");
requestPath = file.replace('/' + fileName, '');
const url = await fetchFiles(requestPath, fileName);
return Response.redirect(url, 302);
} else if (querySplited && querySplited[0] === "upload") {
} else if (querySplited && querySplited[0] === 'upload') {
requestPath = querySplited[1];
const uploadAllow = await fetchFiles(requestPath, ".upload");
const uploadAllow = await fetchFiles(requestPath, '.upload');
const fileList = await request.json();
const pwAttack = fileList["files"].some(file => file.remotePath.split("/").pop().toLowerCase() === PASSWD_FILENAME.toLowerCase());
const pwAttack = fileList['files'].some(
(file) =>
file.remotePath.split('/').pop().toLowerCase() ===
PASSWD_FILENAME.toLowerCase()
);
if (uploadAllow && !pwAttack) {
const uploadLinks = await uploadFiles(fileList);
return new Response(uploadLinks, {
headers: returnHeaders,
});
}
return new Response(
JSON.stringify({ error: "Access forbidden" }),
{
status: 403,
headers: returnHeaders
}
);
return new Response(JSON.stringify({ error: 'Access forbidden' }), {
status: 403,
headers: returnHeaders,
});
} else {
const { headers } = request;
const contentType = headers.get("content-type");
const contentType = headers.get('content-type');
const body = {};
if (contentType && contentType.includes("form")) {
if (contentType && contentType.includes('form')) {
const formData = await request.formData();
for (const entry of formData.entries()) {
body[entry[0]] = entry[1];
}
}
requestPath = Object.getOwnPropertyNames(body).length ? body["?path"] : "";
const files = await fetchFiles(requestPath, null, body.passwd);
requestPath = Object.getOwnPropertyNames(body).length ? body['?path'] : '';
const files = await fetchFiles(
decodeURIComponent(requestPath),
null,
body.passwd
);
return new Response(files, {
headers: returnHeaders,
});
}
}

async function gatherResponse(response) {
const {
headers
} = response;
const contentType = headers.get("content-type");
if (contentType.includes("application/json")) {
const { headers } = response;
const contentType = headers.get('content-type');
if (contentType.includes('application/json')) {
return await response.json();
}
return await response.text();
Expand All @@ -133,7 +136,7 @@ async function getContent(url) {

async function getContentWithHeaders(url, headers) {
const response = await cacheFetch(url, {
headers: headers
headers: headers,
});
const result = await gatherResponse(response);
return result;
Expand All @@ -147,7 +150,7 @@ async function fetchFormData(url, data) {
}
}
const requestOptions = {
method: "POST",
method: 'POST',
body: formdata,
};
const response = await cacheFetch(url, requestOptions);
Expand All @@ -156,7 +159,7 @@ async function fetchFormData(url, data) {
}

async function fetchAccessToken() {
let refreshToken = OAUTH["refreshToken"];
let refreshToken = OAUTH['refreshToken'];
if (typeof FODI_CACHE !== 'undefined') {
const cache = JSON.parse(await FODI_CACHE.get('token_data'));
if (cache?.refresh_token) {
Expand All @@ -171,12 +174,12 @@ async function fetchAccessToken() {
}
}

const url = OAUTH["oauthUrl"] + "token";
const url = OAUTH['oauthUrl'] + 'token';
const data = {
client_id: OAUTH["clientId"],
client_secret: OAUTH["clientSecret"],
grant_type: "refresh_token",
requested_token_use: "on_behalf_of",
client_id: OAUTH['clientId'],
client_secret: OAUTH['clientSecret'],
grant_type: 'refresh_token',
requested_token_use: 'on_behalf_of',
refresh_token: refreshToken,
};
const result = await fetchFormData(url, data);
Expand All @@ -189,28 +192,31 @@ async function fetchAccessToken() {
}

async function fetchFiles(path, fileName, passwd, viewExposePathPassword) {
const relativePath = path;
if (path === "/") path = "";
if (path || EXPOSE_PATH) path = ":" + EXPOSE_PATH + path;
const parent = path || '/';
if (path === '/') path = '';
if (path || EXPOSE_PATH)
path = ':' + encodeURIComponent(EXPOSE_PATH + path) + ':';

const accessToken = await fetchAccessToken();
const expand = path
? ":/children?select=name,size,parentReference,lastModifiedDateTime,@microsoft.graph.downloadUrl&$top=200"
: "?expand=children(select=name,size,parentReference,lastModifiedDateTime,@microsoft.graph.downloadUrl)";
const uri = OAUTH.apiUrl + encodeURI(path) + expand;
const expand =
'/children?select=name,size,parentReference,lastModifiedDateTime,@microsoft.graph.downloadUrl&$top=200';
const uri = OAUTH.apiUrl + path + expand;

let pageRes = await getContentWithHeaders(uri, {
Authorization: "Bearer " + accessToken,
Authorization: 'Bearer ' + accessToken,
});
let body = { children: pageRes.value ? pageRes.value : pageRes.children };
while (pageRes["@odata.nextLink"]) {
pageRes = await getContentWithHeaders(pageRes["@odata.nextLink"], {
Authorization: "Bearer " + accessToken,
let children = pageRes.value;
while (pageRes['@odata.nextLink']) {
pageRes = await getContentWithHeaders(pageRes['@odata.nextLink'], {
Authorization: 'Bearer ' + accessToken,
});
body.children = body.children.concat(pageRes.value);
children = children.concat(pageRes.value);
}

const pwFile = body.children.filter(file => file.name === PASSWD_FILENAME)[0];
const PASSWD = pwFile ? await getContent(pwFile["@microsoft.graph.downloadUrl"]) : '';
const pwFile = children.find((file) => file.name === PASSWD_FILENAME);
const PASSWD = pwFile
? await getContent(pwFile['@microsoft.graph.downloadUrl'])
: '';
if (viewExposePathPassword) {
return PASSWD;
}
Expand All @@ -224,16 +230,15 @@ async function fetchFiles(path, fileName, passwd, viewExposePathPassword) {
}
}

let parent = body.children.length ?
body.children[0].parentReference.path :
body.parentReference.path;
parent = parent.split(":").pop().replace(EXPOSE_PATH, "") || "/";
parent = decodeURIComponent(parent);

if (authState === PATH_AUTH_STATES.NO_PW_FILE && parent.split("/").length <= PROTECTED_LAYERS) {
const upperPasswd = EXPOSE_PASSWD ? EXPOSE_PASSWD : (
(!relativePath || relativePath === "/") ? "" : await fetchFiles("", null, null, true)
);
if (
authState === PATH_AUTH_STATES.NO_PW_FILE &&
parent.split('/').length <= PROTECTED_LAYERS
) {
const upperPasswd = EXPOSE_PASSWD
? EXPOSE_PASSWD
: parent === '/'
? ''
: await fetchFiles('', null, null, true);
if (upperPasswd !== passwd) {
authState = PATH_AUTH_STATES.PW_ERROR;
}
Expand All @@ -244,47 +249,50 @@ async function fetchFiles(path, fileName, passwd, viewExposePathPassword) {
return JSON.stringify({
parent,
files: [],
encrypted: true
encrypted: true,
});
}

// Download file
if (fileName) {
return body
.children
.filter(file => file.name === decodeURIComponent(fileName))[0]?.["@microsoft.graph.downloadUrl"];
return children.find(
(file) => file.name === decodeURIComponent(fileName)
)?.['@microsoft.graph.downloadUrl'];
}

// List folder
return JSON.stringify({
parent,
files: body.children.map(file => ({
name: file.name,
size: file.size,
time: file.lastModifiedDateTime,
url: file["@microsoft.graph.downloadUrl"],
})).filter(file => file.name !== PASSWD_FILENAME)
files: children
.map((file) => ({
name: file.name,
size: file.size,
time: file.lastModifiedDateTime,
url: file['@microsoft.graph.downloadUrl'],
}))
.filter((file) => file.name !== PASSWD_FILENAME),
});
}

async function uploadFiles(fileJsonList) {
let fileList = fileJsonList["files"];
let fileList = fileJsonList['files'];
const accessToken = await fetchAccessToken();
await Promise.all(
fileList.map(async (file) => {
const uri = `${OAUTH.apiUrl}:${EXPOSE_PATH}${file["remotePath"]}:/createUploadSession`;
const uploadPath = encodeURIComponent(EXPOSE_PATH + file['remotePath']);
const uri = `${OAUTH.apiUrl}:${uploadPath}:/createUploadSession`;
const headers = {
Authorization: "Bearer " + accessToken,
Authorization: 'Bearer ' + accessToken,
};
const uploadUrl = await fetch(uri, {
method: "POST",
const uploadUrl = await cacheFetch(uri, {
method: 'POST',
headers: headers,
})
.then((response) => {
return response.json();
})
.then((data) => {
return data["uploadUrl"];
return data['uploadUrl'];
});
file.uploadUrl = uploadUrl;
})
Expand Down
Loading

0 comments on commit cbf10dd

Please sign in to comment.