133 lines
4.5 KiB
JavaScript
133 lines
4.5 KiB
JavaScript
const scripts = ['https://apis.google.com/js/api.js', 'https://accounts.google.com/gsi/client'];
|
|
const DISCOVERY_DOC = 'https://www.googleapis.com/discovery/v1/apis/drive/v3/rest';
|
|
const CLIENT_ID = '53206975661-ih3r0ubph3rqejdq97b029difbrk2bqj.apps.googleusercontent.com';
|
|
|
|
// Authorization scopes required by the API; multiple scopes can be included, separated by spaces.
|
|
const SCOPES = 'openid email profile';
|
|
const SCOPES_DRIVE = 'https://www.googleapis.com/auth/drive.appdata';
|
|
|
|
export class GoogleClient {
|
|
async initGApi() {
|
|
return new Promise((resolve, reject) => {
|
|
gapi.load('client', async () => {
|
|
await gapi.client.init({ discoveryDocs: [DISCOVERY_DOC] });
|
|
resolve();
|
|
});
|
|
});
|
|
}
|
|
initTokenClient(scopes, cb) {
|
|
this.tokenClient = google.accounts.oauth2.initTokenClient({
|
|
client_id: CLIENT_ID,
|
|
scope: scopes,
|
|
callback: cb // defined later
|
|
});
|
|
console.log('google client init success');
|
|
}
|
|
async initGoolgeClient() {
|
|
await loadScripts(scripts.map((script) => [script]));
|
|
await this.initGApi();
|
|
this.initTokenClient(SCOPES);
|
|
}
|
|
login(funid) {
|
|
this.tokenClient.callback = async (resp) => {
|
|
if (resp.error !== undefined) {
|
|
throw resp;
|
|
}
|
|
console.log('token: ', gapi.client.getToken());
|
|
this.access_token = gapi.client.getToken().access_token;
|
|
let result = {
|
|
data: gapi.client.getToken().access_token,
|
|
errcode: 0,
|
|
};
|
|
jc.wallet.nativeSvr.handleNativeCallback(funid, JSON.stringify(result));
|
|
};
|
|
|
|
if (gapi.client.getToken() === null) {
|
|
// Prompt the user to select a Google Account and ask for consent to share their data
|
|
// when establishing a new session.
|
|
this.tokenClient.requestAccessToken({ prompt: 'consent' });
|
|
} else {
|
|
// Skip display of account chooser and consent dialog for an existing session.
|
|
this.tokenClient.requestAccessToken({ prompt: '' });
|
|
}
|
|
}
|
|
generateCfgName(key) {
|
|
return `wallet_${key}.json`;
|
|
}
|
|
hasDriveScope() {
|
|
return google.accounts.oauth2.hasGrantedAnyScope(gapi.client.getToken(), SCOPES_DRIVE);
|
|
}
|
|
async requestDriveScope() {
|
|
return new Promise((resolve, reject) => {
|
|
this.initTokenClient(SCOPES + " " + SCOPES_DRIVE, (resp) => {
|
|
if (resp.error !== undefined) {
|
|
throw resp;
|
|
}
|
|
resolve();
|
|
});
|
|
this.tokenClient.requestAccessToken({ prompt: 'consent' });
|
|
});
|
|
}
|
|
async listFiles() {
|
|
return gapi.client.drive.files.list({
|
|
spaces: 'appDataFolder',
|
|
fields: 'files(id, name)',
|
|
});
|
|
}
|
|
async downloadCfg(key) {
|
|
if (!this.hasDriveScope()) {
|
|
await this.requestDriveScope();
|
|
}
|
|
let fileName = this.generateCfgName(key)
|
|
let files = await this.listFiles();
|
|
let file = files.result.files.find((file) => file.name.toLowerCase() === fileName.toLowerCase());
|
|
if (file) {
|
|
let fileId = file.id;
|
|
let info = await gapi.client.drive.files.get({
|
|
fileId: fileId,
|
|
alt: 'media',
|
|
});
|
|
return info.result;
|
|
}
|
|
}
|
|
async uploadOneFile(content, fileName) {
|
|
return new Promise((resolve, reject) => {
|
|
var file = new Blob([JSON.stringify(content)], {type: 'application/json'});
|
|
var metadata = {
|
|
'name': fileName, // Filename at Google Drive
|
|
'mimeType': 'application/json', // mimeType at Google Drive
|
|
'parents': ['appDataFolder'], // Folder ID at Google Drive
|
|
};
|
|
|
|
var accessToken = gapi.auth.getToken().access_token; // Here gapi is used for retrieving the access token.
|
|
var form = new FormData();
|
|
form.append('metadata', new Blob([JSON.stringify(metadata)], {type: 'application/json'}));
|
|
form.append('file', file);
|
|
|
|
var xhr = new XMLHttpRequest();
|
|
xhr.open('post', 'https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart&fields=id');
|
|
xhr.setRequestHeader('Authorization', 'Bearer ' + accessToken);
|
|
xhr.responseType = 'json';
|
|
xhr.onload = () => {
|
|
console.log(xhr.response.id); // Retrieve uploaded file ID.
|
|
resolve && resolve(xhr.response);
|
|
};
|
|
xhr.send(form);
|
|
});
|
|
}
|
|
async uploadCfg(key, pass) {
|
|
if (!this.hasDriveScope()) {
|
|
await this.requestDriveScope();
|
|
}
|
|
let fileName = this.generateCfgName(key);
|
|
let files = await this.listFiles();
|
|
let file = files.result.files.find((file) => file.name.toLowerCase() === fileName.toLowerCase());
|
|
if (!file) {
|
|
let res = await this.uploadOneFile({pass}, fileName);
|
|
return res;
|
|
} else {
|
|
return file;
|
|
}
|
|
}
|
|
}
|