unipass-js-sdk
Version:
unipass-js-sdk
209 lines (204 loc) • 5.55 kB
text/typescript
// unipass.ts
const { createHash } = require('crypto')
declare interface Window {
unipass: any
unipassIsBindEvent: any
}
declare interface Ret {
code: number
info: string
data: {
email: string
pubkey: string
}
}
declare interface Provider {
email: string
pubkey: string
}
;(function (factory) {
// nodejs
if (typeof exports === 'object' && typeof module !== 'undefined') {
module.exports = factory()
}
// browser
if (typeof window !== 'undefined') {
window.unipass = factory()
}
})(function () {
const Sea = {
// json parse
json(s: string) {
try {
return JSON.parse(s)
} catch (err) {
return s
}
},
// Local storage
localStorage(key: string, val?: any) {
if (val === undefined) {
return this.json(window.localStorage.getItem(key) as string)
} else if (val === '') {
window.localStorage.removeItem(key)
} else {
window.localStorage.setItem(key, JSON.stringify(val))
}
},
params(key: string, value?: string) {
const obj = new window.URL(window.location.href)
if (value) {
obj.searchParams.set(key, value)
} else if (value === '') {
obj.searchParams.delete(key)
} else if (key) {
return obj.searchParams.get(key)
} else {
return obj.searchParams
}
history.replaceState({}, '', obj.href)
},
}
const _callbackRet = function (ret: Ret) {
if (ret && ret.data && ret.code) {
if (Sea.params('unipass_ret')) {
Sea.params('unipass_ret', '')
}
unipass.callback(ret)
if (ret.info === 'login success') {
Sea.localStorage('unipass_provider', ret.data)
unipass.provider = ret.data
}
}
}
const _jump = function (type: string, data = {} as any) {
if (type === 'sign') {
const pubkey = unipass.provider.pubkey
if (pubkey) {
data.pubkey = pubkey
} else {
console.error('Please login first')
return
}
// handle message
if (data.message) {
data.message = encodeURIComponent(data.message)
if (data.type !== 'personal_sign') {
data.message = createHash('SHA256')
.update(data.message)
.digest('hex')
.toString()
}
} else {
console.error('Please enter message')
return
}
}
data.success_url = encodeURIComponent(window.location.href)
const query = Object.keys(data)
.map((key) => `${key}=${data[key]}`)
.join('&')
const url = `${unipass.url}/${type}?${query}`
window.location.href = url
}
const _popup = function (type: string, data = {} as any) {
if (unipass.isBuiltInBrowser()) {
console.error(
'Popup Window is not supported by low compatibility browser',
)
return
}
if (type === 'sign') {
const pubkey = unipass.provider.pubkey
if (pubkey) {
data.pubkey = pubkey
} else {
console.error('Please login first')
return
}
// handle message
if (data.message) {
data.message = encodeURIComponent(data.message)
if (data.type !== 'personal_sign') {
data.message = createHash('SHA256')
.update(data.message)
.digest('hex')
.toString()
}
} else {
console.error('Please enter message')
return
}
}
const page = window.open(
`${unipass.url}/${type}`,
type,
'width=380,height=675,top=40,left=100,toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=yes,',
)
if (page) {
page.onload = () => {
data.success_url = 'open'
page.postMessage(data, '*')
}
}
}
const unipass = {
callback(_ret: Ret) {},
url: 'https://t.unipass.xyz',
provider: {} as Provider,
init(baseUrl: string | null, callback: (ret: Ret) => void) {
if (typeof window === 'undefined' || window.unipassIsBindEvent) {
return
}
this.callback = callback
if (baseUrl) {
this.url = baseUrl
}
window.unipassIsBindEvent = true
const url = new URL(window.location.href)
const ret = Sea.json(url.searchParams.get('unipass_ret') as string)
if (ret) {
_callbackRet(ret)
}
window.addEventListener(
'message',
(event: MessageEvent) => {
const ret = event.data
_callbackRet(ret)
},
false,
)
unipass.provider = Sea.localStorage('unipass_provider') || {}
},
login() {
_jump('login')
},
sign(data = {} as any) {
_jump('sign', data)
},
popupLogin() {
_popup('login')
},
popupSign(data = {} as any) {
_popup('sign', data)
},
exit() {
Sea.localStorage('unipass_provider', '')
window.location.reload()
},
isBuiltInBrowser() {
if (typeof navigator === 'undefined') {
return true
}
const userAgent = navigator.userAgent.toLowerCase()
const list = ['micromessenger', 'qqbrowser', 'weibo', 'alipay']
for (const browser of list) {
if (userAgent.includes(browser)) {
return true
}
}
return false
},
}
return unipass
})