Skip to content

Commit 38831b4

Browse files
committed
feat(support logout and change OAuth API): add logout API and change the way of getting OAuth Code
1 parent e7f1725 commit 38831b4

File tree

5 files changed

+116
-25
lines changed

5 files changed

+116
-25
lines changed

example/basic-dapp/index.html

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@
5050
<button id="connect" disabled="true">Connect
5151
Wallet
5252
</button>
53+
<button id="logout" disabled="true">
54+
Logout
55+
</button>
5356
<footer>
5457
<p>Address: <span id="address">N/A</span></p>
5558
<p>OAuth Code: <span id="oauth_code">N/A</span></p>

example/basic-dapp/index.js

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,7 @@ function isAnyWebInstall() {
475475
async function walletInitialized() {
476476
// connect
477477
const connectButton = getElement('connect')
478+
const logoutButton = getElement('logout')
478479
const sendNativeTokenButton = getElement('send_native_token')
479480
const approveButton = getElement('approve')
480481
const transferFromButton = getElement('transfer_from')
@@ -491,36 +492,37 @@ async function walletInitialized() {
491492

492493
const deployContract = getElement('deploy_contract')
493494

494-
async function authed(address) {
495+
function authed(address, oauthCode = undefined) {
495496
if (!address || address === '') {
496497
return unAuthed()
497498
}
498-
const oauthCode = await provider.request({
499-
method: 'anyweb_oauth',
500-
})
501499
getElement('address').innerHTML = address
502-
getElement('oauth_code').innerHTML = oauthCode
500+
if (oauthCode) {
501+
getElement('oauth_code').innerHTML = oauthCode
502+
}
503503
console.log('authed address: ', address)
504-
console.log('OAuth Code: ', oauthCode)
505504
sendNativeTokenButton.disabled = false
506505
approveButton.disabled = false
507506
transferFromButton.disabled = false
508507
deployContract.disabled = false
509508
getCFXButton.disabled = false
510509
connectButton.disabled = true
510+
logoutButton.disabled = false
511511
importAddressButton.disabled = false
512512
importPrivateKeyButton.disabled = false
513513
}
514514

515515
function unAuthed() {
516516
getElement('address').innerHTML = 'N/A'
517+
getElement('oauth_code').innerHTML = 'N/A'
517518
console.log('unauthed')
518519
sendNativeTokenButton.disabled = true
519520
approveButton.disabled = true
520521
transferFromButton.disabled = true
521522
getCFXButton.disabled = true
522523
deployContract.disabled = true
523524
connectButton.disabled = false
525+
logoutButton.disabled = true
524526
importAddressButton.disabled = true
525527
importPrivateKeyButton.disabled = true
526528
}
@@ -547,18 +549,21 @@ async function walletInitialized() {
547549
getElement('version').innerHTML = version
548550
})
549551

550-
const [chainId, networkId, alreadyAuthedAddresses] = await Promise.all([
552+
const [chainId, networkId, authResult] = await Promise.all([
551553
provider.request({ method: 'cfx_chainId' }),
552554
provider.request({ method: 'cfx_netVersion' }),
553555
provider.request({
554556
method: 'cfx_accounts',
555557
params: [
556558
{
557559
availableNetwork: [1, 1029],
560+
scopes: ['baseinfo', 'phone'],
558561
},
559562
],
560563
}),
561564
])
565+
const { address: alreadyAuthedAddresses, code, scopes } = authResult
566+
console.log('DApp 获取到的授权结果', authResult)
562567

563568
getElement('initialized').innerHTML = 'initialized'
564569
getElement('chainId').innerHTML = chainId
@@ -571,19 +576,32 @@ async function walletInitialized() {
571576
) {
572577
unAuthed()
573578
} else {
574-
authed(alreadyAuthedAddresses[0])
579+
authed(alreadyAuthedAddresses[0], code)
575580
}
576581
} catch (e) {
577582
unAuthed()
578583
console.error('try 到错误了', e)
579584
}
580585

581-
connectButton.onclick = () => {
586+
connectButton.onclick = async () => {
587+
const { address, code } = await provider.request({
588+
method: 'cfx_accounts',
589+
params: [
590+
{
591+
availableNetwork: [1, 1029],
592+
scopes: ['baseinfo', 'phone'],
593+
},
594+
],
595+
})
596+
authed(address, code)
597+
}
598+
599+
logoutButton.onclick = () => {
582600
provider
583601
.request({
584-
method: 'cfx_requestAccounts',
602+
method: 'anyweb_logout',
585603
})
586-
.then(authed)
604+
.then(unAuthed)
587605
.catch(console.error)
588606
}
589607

src/interface/provider.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ export interface IAuthResult {
5656
address: string[]
5757
url: string
5858
oauthToken: string
59+
scopes: string[]
5960
}
6061

6162
export interface IProviderRpcError extends Error {
@@ -77,7 +78,7 @@ export interface IIframeOptions {
7778
appId: string
7879
params: string
7980
chainId: string
80-
scope?: number[]
81+
scopes?: string[]
8182
authType?:
8283
| 'account'
8384
| 'createContract'

src/provider.ts

Lines changed: 54 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,13 @@ import {
1212
IProviderRpcError,
1313
IRequestArguments,
1414
} from './interface/provider'
15-
import { callIframe, readCache, setCache } from './utils/common'
15+
import {
16+
callIframe,
17+
isIncluded,
18+
readCache,
19+
removeCache,
20+
setCache,
21+
} from './utils/common'
1622
import config from '../package.json'
1723
import { AddressType, getAddressType } from './utils/address'
1824
import { ConsoleLike } from './utils/types'
@@ -33,6 +39,9 @@ export class Provider implements IProvider {
3339
networkId = -1
3440
chainId = -1
3541
url = ''
42+
scopes: string[] = []
43+
reAuth = false
44+
3645
events: {
3746
onConnect?: (connectInfo: IProviderConnectInfo) => void
3847
onDisconnect?: (error: IProviderRpcError) => void
@@ -150,27 +159,53 @@ export class Provider implements IProvider {
150159
case 'cfx_requestAccounts':
151160
return this.rawRequest('cfx_accounts')
152161
case 'cfx_accounts':
162+
const scopes: string[] =
163+
(params && 'scopes' in paramsObj ? paramsObj['scopes'] : []) || []
164+
console.log('paramsObj', paramsObj)
165+
console.log('scopes', scopes, this.scopes)
153166
if (this.address.length > 0) {
154-
return this.address
167+
if (isIncluded(this.scopes, scopes)) {
168+
if (scopes.length === 0) {
169+
return this.address
170+
} else {
171+
return {
172+
address: this.address,
173+
code: this.oauthToken,
174+
scopes: scopes,
175+
}
176+
}
177+
} else {
178+
removeCache(this)
179+
}
155180
}
156-
console.log('cfx_accounts参数', paramsObj)
157181
const result = (await callIframe(
158182
'pages/dapp/auth',
159183
{
160184
appId: this.appId,
161185
params: params ? JSON.stringify(paramsObj) : '',
162186
chainId: (await this.request({ method: 'cfx_chainId' })) as string,
163187
authType: 'account',
188+
scopes: scopes,
164189
},
165-
this
190+
this,
191+
this.reAuth
166192
)) as IAuthResult
193+
result.scopes = scopes
194+
this.reAuth = false
167195
setCache(result, this)
168196
this.events.onAccountsChanged &&
169197
this.events.onAccountsChanged(result.address)
170198
this.events.onChainChanged &&
171199
this.events.onChainChanged(String(result.chainId))
172200
this.events.onNetworkChanged &&
173201
this.events.onNetworkChanged(String(result.networkId))
202+
if (scopes.length > 0) {
203+
return {
204+
address: this.address,
205+
code: result.oauthToken,
206+
scopes: scopes,
207+
}
208+
}
174209
return this.address
175210
case 'cfx_sendTransaction':
176211
try {
@@ -218,11 +253,6 @@ export class Provider implements IProvider {
218253
}
219254
case 'anyweb_version':
220255
return config.version
221-
case 'anyweb_oauth':
222-
if (this.oauthToken) {
223-
return this.oauthToken
224-
}
225-
throw new Error('Get oauth token failed: get account address first')
226256
case 'anyweb_home':
227257
return await callIframe(
228258
'pages/index/home',
@@ -234,6 +264,21 @@ export class Provider implements IProvider {
234264
},
235265
this
236266
)
267+
case 'anyweb_logout':
268+
try {
269+
removeCache(this)
270+
this.reAuth = true
271+
// sendMessageToApp({
272+
// type: 'event',
273+
// data: {
274+
// type: 'logout',
275+
// appId: this.appId,
276+
// },
277+
// })
278+
} catch (e) {
279+
return e
280+
}
281+
return 'success'
237282
default:
238283
return 'Unsupported method'
239284
}

src/utils/common.ts

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -232,19 +232,22 @@ export const callIframe = async (
232232
appId,
233233
params,
234234
chainId,
235-
scope = [2],
235+
scopes = [],
236236
authType,
237237
waitResult = true,
238238
}: IIframeOptions,
239-
provider: Provider
239+
provider: Provider,
240+
reAuth = false
240241
) => {
241242
if (waitResult) {
242243
return new Promise<unknown>(async (resolve, reject) => {
243244
let callback: IIframeData | undefined = undefined
244245
const close = await getIframe(
245246
`${path}?appId=${appId}&authType=${authType}&random=${Math.floor(
246247
Math.random() * 1000
247-
)}&chainId=${chainId}&params=${params}&scope=${JSON.stringify(scope)}`,
248+
)}&chainId=${chainId}&params=${params}&scopes=${JSON.stringify(
249+
scopes
250+
)}&reAuth=${reAuth}`,
248251
() => {
249252
if (timer) {
250253
clearTimeout(timer)
@@ -306,7 +309,7 @@ export const callIframe = async (
306309
await getIframe(
307310
`${path}?appId=${appId}&authType=${authType}&random=${Math.floor(
308311
Math.random() * 1000
309-
)}&chainId=${chainId}&params=${params}&scope=${JSON.stringify(scope)}`,
312+
)}&chainId=${chainId}&params=${params}&scopes=${JSON.stringify(scopes)}`,
310313
() => {
311314
return
312315
}
@@ -328,13 +331,15 @@ export const readCache = (provider: Provider) => {
328331
Object.keys(result).includes('chainId') &&
329332
Object.keys(result).includes('expires') &&
330333
Object.keys(result).includes('oauthToken') &&
334+
Object.keys(result).includes('scopes') &&
331335
result.expires > new Date().getTime()
332336
) {
333337
provider.address = result.address
334338
provider.networkId = result.networkId
335339
provider.chainId = result.chainId
336340
provider.url = result.url
337341
provider.oauthToken = result.oauthToken
342+
provider.scopes = result.scopes
338343
}
339344
} catch (e) {
340345
provider.logger.error(e)
@@ -355,5 +360,24 @@ export const setCache = (data: IAuthResult, provider: Provider) => {
355360
provider.chainId = data.chainId || provider.chainId
356361
provider.url = data.url
357362
provider.oauthToken = data.oauthToken || provider.oauthToken
363+
provider.scopes = data.scopes || provider.scopes
358364
return data
359365
}
366+
367+
export const removeCache = (provider: Provider) => {
368+
window.localStorage && window.localStorage.removeItem('anyweb_info')
369+
provider.address = []
370+
provider.networkId = -1
371+
provider.chainId = -1
372+
provider.url = ''
373+
provider.oauthToken = undefined
374+
provider.scopes = []
375+
}
376+
377+
export const isArrEqual = <T>(arr1: T[], arr2: T[]) => {
378+
return arr1.length === arr2.length && arr1.every((ele) => arr2.includes(ele))
379+
}
380+
381+
export const isIncluded = <T>(arr1: T[], arr2: T[]): boolean => {
382+
return arr1.length === new Set([...arr1, ...arr2]).size
383+
}

0 commit comments

Comments
 (0)