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 Promise.all([loadSingleScript([scripts[0]]), loadSingleScript([scripts[1]])]); 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; } } }