Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 87 additions & 6 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,15 @@ const authConfig = {
* 如果在全局认证的基础上,仍需要给某些目录单独进行 .password 文件内的密码验证的话,将此选项设置为 true;
* 【注意】如果开启了 .password 文件密码验证,每次列目录都会额外增加查询目录内 .password 文件是否存在的开销。
*/
"enable_password_file_verify": false
"enable_password_file_verify": false,
/**
* Enable or disable service account usage with go2index. If set to true, `service_account_json` will need to have all the appropriate values
*/
service_account_enabled: false,
/**
* This will hold the contents of the JSON file downloaded from Google Cloud Platform console
*/
service_accounts_json: [],
};

/**
Expand Down Expand Up @@ -97,6 +105,68 @@ const FUNCS = {

};

/**
* Functions that are required to generate the JWT token required for service account authentication
*/
const JWT = {
header: {
alg: 'RS256',
typ: 'JWT'
},
importKey: async function(pemKey) {
var pemDER = this.textUtils.base64ToArrayBuffer(pemKey.split('\n').map(s => s.trim()).filter(l => l.length && !l.startsWith('---')).join(''));
return crypto.subtle.importKey('pkcs8', pemDER, { name: 'RSASSA-PKCS1-v1_5', hash: 'SHA-256' }, false, ['sign']);
},
createSignature: async function(text, key) {
const textBuffer = this.textUtils.stringToArrayBuffer(text);
return crypto.subtle.sign('RSASSA-PKCS1-v1_5', key, textBuffer)
},
generateGCPToken: async function(serviceAccount) {
const iat = parseInt(Date.now()/1000);
var payload = {
"iss": serviceAccount.client_email,
"scope": "https://www.googleapis.com/auth/drive",
"aud": "https://oauth2.googleapis.com/token",
"exp": iat+3600,
"iat": iat
};
const encPayload = btoa(JSON.stringify(payload));
const encHeader = btoa(JSON.stringify(this.header));

var key = await this.importKey(serviceAccount.private_key);
var signed = await this.createSignature(encHeader+"."+encPayload, key);
return encHeader+"."+encPayload+"."+this.textUtils.arrayBufferToBase64(signed).replace(/\//g, '_').replace(/\+/g, '-');
},
textUtils: {
base64ToArrayBuffer: function(base64) {
var binary_string = atob(base64);
var len = binary_string.length;
var bytes = new Uint8Array(len);
for (var i = 0; i < len; i++) {
bytes[i] = binary_string.charCodeAt(i);
}
return bytes.buffer;
},
stringToArrayBuffer: function(str){
var len = str.length;
var bytes = new Uint8Array(len);
for (var i = 0; i < len; i++) {
bytes[i] = str.charCodeAt(i);
}
return bytes.buffer;
},
arrayBufferToBase64: function(buffer) {
let binary = '';
let bytes = new Uint8Array(buffer);
let len = bytes.byteLength;
for (let i = 0; i < len; i++) {
binary += String.fromCharCode(bytes[i]);
}
return btoa(binary);
}
}
};

/**
* global consts
* @type {{folder_mime_type: string, default_file_fields: string, gd_root_type: {share_drive: number, user_drive: number, sub_folder: number}}}
Expand Down Expand Up @@ -787,11 +857,22 @@ class googleDrive {
const headers = {
'Content-Type': 'application/x-www-form-urlencoded'
};
const post_data = {
'client_id': this.authConfig.client_id,
'client_secret': this.authConfig.client_secret,
'refresh_token': this.authConfig.refresh_token,
'grant_type': 'refresh_token'
var post_data;
if(this.authConfig.service_account_enabled && typeof this.authConfig.service_accounts_json != "undefined" && this.authConfig.service_accounts_json.length > 0)
{
const service_account = this.authConfig.service_accounts_json[Math.floor(Math.random() * this.authConfig.service_accounts_json.length)];
const jwttoken = await JWT.generateGCPToken(service_account);
post_data = {
grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
assertion: jwttoken,
};
} else {
post_data = {
client_id: this.authConfig.client_id,
client_secret: this.authConfig.client_secret,
refresh_token: this.authConfig.refresh_token,
grant_type: "refresh_token",
};
}

let requestOption = {
Expand Down