You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
OneAuth/oaer/lib/logic.ts

171 lines
3.8 KiB
TypeScript

/*
* logic.ts
* Copyright (C) 2024 veypi <i@veypi.com>
* 2024-10-24 16:36
* Distributed under terms of the GPL license.
*/
import bus from './bus'
import proxy from './components/proxy'
import api, { apitoken } from './api'
class Token {
iat?: string
iss?: string
jti?: string
exp?: number
aid?: string
icon?: string
name?: string
uid?: string
access?: any
private _raw: string
private _typ: 'refresh' | 'oa' | 'app'
constructor(typ: 'refresh' | 'oa' | 'app') {
this._typ = typ
this._raw = localStorage.getItem(typ) || ''
if (this._raw) {
this.set(this._raw)
}
}
isVaild() {
if (this.exp) {
const now = Math.floor(Date.now() / 1000);
return now < this.exp
}
return false
}
set(t: string) {
try {
const parts = t.split('.');
// header = JSON.parse(atob(parts[0]));
let body = JSON.parse(atob(parts[1]));
// sign = parts[2]
this._raw = t
Object.assign(this, body)
localStorage.setItem(this._typ, t)
} catch (error) {
console.warn('Error parsing JWT:', error);
}
}
clear() {
localStorage.removeItem(this._typ)
this.exp = undefined
}
raw() {
return this._raw
}
update() {
return new Promise<Token>((resolve, reject) => {
if (!logic.token.refresh.isVaild() || this._typ === 'refresh') {
reject()
}
let aid = logic.oa_id
if (this._typ === 'app') {
aid = logic.app_id
}
api.token.Post({ refresh: logic.token.refresh.raw(), user_id: logic.token.refresh.uid!, app_id: aid }).then(e => {
if (this._typ === 'oa' && logic.app_id == logic.oa_id) {
logic.token.app.set(e)
}
this.set(e)
resolve(this)
}).catch(e => {
console.warn(`get oa token failed: ${e} `)
reject()
})
})
}
}
// interface Token {
// aid: string
// exp: number
// iat: string
// icon: string
// iss: string
// jti: string
// name: string
// uid: string
// isVaild: () => boolean
// row: () => string
// }
const logic = proxy.Watch({
oa_id: '',
app_id: '',
token: {
refresh: new Token('refresh'),
oa: new Token('oa'),
app: new Token('app'),
},
user: {
username: 'asd',
nickname: '',
email: '',
phone: '',
id: 1,
icon: 'https://public.veypi.com/img/avatar/0001.jpg'
},
myapps: [
{ name: 'a' },
{ name: 'b' },
],
ready: false,
init: () => {
return new Promise<Token>((resolve, reject) => {
api.info().then(e => {
logic.oa_id = e.id
if (logic.token.refresh.isVaild()) {
logic.app_id = logic.token.refresh.aid!
logic.token.oa.update().then((e) => {
apitoken.set_updator(logic.token.oa.update)
if (logic.app_id !== logic.oa_id) {
logic.token.app.update().then((e) => {
logic.ready = true
resolve(e);
}).catch(() => reject())
} else {
logic.ready = true
resolve(e);
}
}).catch(() => {
reject()
})
} else {
reject()
}
}).catch(e => {
console.warn(`can not get info from ${logic.host}: ${e} `)
reject();
})
})
},
host: '',
Host() {
return this.host || (window.location.protocol + window.location.host)
},
goto(url: string) {
if (url.startsWith('http')) {
window.location.href = url
return
}
if (!url.startsWith('/')) {
url = '/' + url
}
window.location.href = this.host + url
},
})
bus.on('login', () => {
logic.goto('/login')
})
bus.on('logout', () => {
logic.ready = false
logic.token.refresh.clear()
logic.token.oa.clear()
logic.token.app.clear()
})
export default logic