fix: read pda authorization outside jwt
This commit is contained in:
+32
-12
@@ -8,7 +8,10 @@ const SESSION_KEY = 'overseas-pda-auth-session'
|
||||
export const PDA_ROLE = 'OVERSEAS_WAREHOUSE_PDA_OPERATOR'
|
||||
export const PDA_AUTHORITY = 'lastleg:pda:operate'
|
||||
|
||||
export const session = reactive({ currentUser: null, token: '', domesticToken: '', refreshToken: '', tenantId: '', apiBase: OVERSEAS_API_ROOT })
|
||||
export const session = reactive({
|
||||
currentUser: null, token: '', domesticToken: '', refreshToken: '', tenantId: '', apiBase: OVERSEAS_API_ROOT,
|
||||
authorization: { roles: [], authorities: [] }
|
||||
})
|
||||
|
||||
function decodeBase64Url(value) {
|
||||
const normalized = value.replace(/-/g, '+').replace(/_/g, '/')
|
||||
@@ -53,7 +56,18 @@ function requireActiveClaims(claims, label) {
|
||||
}
|
||||
}
|
||||
|
||||
export function validatePdaTokenPair(accessToken, overseasAccessToken) {
|
||||
function requireAuthorizationSnapshot(authorization) {
|
||||
if (!Array.isArray(authorization?.roles) || !Array.isArray(authorization?.authorities)) {
|
||||
throw new Error('登录响应缺少完整权限快照')
|
||||
}
|
||||
const roles = authorization.roles.map(String)
|
||||
const authorities = authorization.authorities.map(String)
|
||||
if (!includesClaim(roles, PDA_ROLE)) throw new Error('当前账号不是海外仓 PDA 作业员')
|
||||
if (!includesClaim(authorities, PDA_AUTHORITY)) throw new Error(`当前账号缺少${PDA_AUTHORITY}权限`)
|
||||
return { roles, authorities }
|
||||
}
|
||||
|
||||
export function validatePdaTokenPair(accessToken, overseasAccessToken, authorization) {
|
||||
const domestic = decodeAccessToken(accessToken)
|
||||
const overseas = decodeAccessToken(overseasAccessToken)
|
||||
requireActiveClaims(domestic, '登录状态')
|
||||
@@ -63,9 +77,7 @@ export function validatePdaTokenPair(accessToken, overseasAccessToken) {
|
||||
}
|
||||
const warehouseId = claimId(overseas, 'overseas_warehouse_id')
|
||||
if (!/^\d+$/.test(warehouseId) || warehouseId === '0') throw new Error('海外PDA账号未绑定有效作业仓库')
|
||||
if (!includesClaim(overseas.roles, PDA_ROLE)) throw new Error('当前账号不是海外仓 PDA 作业员')
|
||||
if (!includesClaim(overseas.authorities, PDA_AUTHORITY)) throw new Error(`当前账号缺少${PDA_AUTHORITY}权限`)
|
||||
return { domestic, overseas, warehouseId }
|
||||
return { domestic, overseas, warehouseId, authorization: requireAuthorizationSnapshot(authorization) }
|
||||
}
|
||||
|
||||
function userFromClaims(pair, saved = {}) {
|
||||
@@ -75,7 +87,7 @@ function userFromClaims(pair, saved = {}) {
|
||||
id: claimId(pair.domestic, 'user_id'),
|
||||
name: pair.domestic.username || '仓库作业员',
|
||||
role: PDA_ROLE,
|
||||
roles: [...pair.overseas.roles],
|
||||
roles: [...pair.authorization.roles],
|
||||
warehouse: sameWarehouse && saved.warehouseName ? saved.warehouseName : '',
|
||||
warehouseId: pair.warehouseId,
|
||||
warehouseCode: sameWarehouse ? (saved.warehouseCode || '') : '',
|
||||
@@ -95,7 +107,8 @@ function persistSession() {
|
||||
domesticToken: session.domesticToken,
|
||||
refreshToken: session.refreshToken,
|
||||
tenantId: session.tenantId,
|
||||
apiBase: session.apiBase
|
||||
apiBase: session.apiBase,
|
||||
authorization: session.authorization
|
||||
})
|
||||
}
|
||||
|
||||
@@ -107,6 +120,10 @@ export function signIn(account, warehouse, options = {}) {
|
||||
session.refreshToken = options.refreshToken || account.refreshToken || ''
|
||||
session.tenantId = options.tenantId || account.tenantId || ''
|
||||
session.apiBase = options.apiBase || account.apiBase || OVERSEAS_API_ROOT
|
||||
session.authorization = {
|
||||
roles: [...(options.authorization?.roles || [])],
|
||||
authorities: [...(options.authorization?.authorities || [])]
|
||||
}
|
||||
persistSession()
|
||||
return session.currentUser
|
||||
}
|
||||
@@ -114,19 +131,20 @@ export function signIn(account, warehouse, options = {}) {
|
||||
export function signInWithTokens(tokens) {
|
||||
if (!tokens?.accessToken) throw new Error('登录响应缺少 accessToken')
|
||||
if (!tokens?.overseasAccessToken) throw new Error('登录响应缺少 overseasAccessToken')
|
||||
const pair = validatePdaTokenPair(tokens.accessToken, tokens.overseasAccessToken)
|
||||
const pair = validatePdaTokenPair(tokens.accessToken, tokens.overseasAccessToken, tokens)
|
||||
const user = userFromClaims(pair)
|
||||
return signIn(user, user.warehouse, {
|
||||
token: tokens.overseasAccessToken,
|
||||
domesticToken: tokens.accessToken,
|
||||
refreshToken: tokens.refreshToken || '',
|
||||
tenantId: claimId(pair.domestic, 'tenant_id')
|
||||
tenantId: claimId(pair.domestic, 'tenant_id'),
|
||||
authorization: pair.authorization
|
||||
})
|
||||
}
|
||||
|
||||
export function replaceTokens(tokens) {
|
||||
if (!tokens?.accessToken || !tokens?.overseasAccessToken) throw new Error('刷新响应缺少双区域访问令牌')
|
||||
const pair = validatePdaTokenPair(tokens.accessToken, tokens.overseasAccessToken)
|
||||
const pair = validatePdaTokenPair(tokens.accessToken, tokens.overseasAccessToken, tokens)
|
||||
const user = userFromClaims(pair, session.currentUser)
|
||||
const nextRefreshToken = tokens.refreshToken || session.refreshToken
|
||||
// Validate the complete replacement before mutating reactive or persisted session state.
|
||||
@@ -135,6 +153,7 @@ export function replaceTokens(tokens) {
|
||||
session.refreshToken = nextRefreshToken
|
||||
session.tenantId = claimId(pair.domestic, 'tenant_id')
|
||||
session.currentUser = user
|
||||
session.authorization = pair.authorization
|
||||
persistSession()
|
||||
}
|
||||
|
||||
@@ -160,10 +179,10 @@ export function restoreSession() {
|
||||
return false
|
||||
}
|
||||
try {
|
||||
const pair = validatePdaTokenPair(saved.domesticToken, saved.token)
|
||||
const pair = validatePdaTokenPair(saved.domesticToken, saved.token, saved.authorization)
|
||||
Object.assign(session, saved, {
|
||||
currentUser: userFromClaims(pair, saved.currentUser), tenantId: claimId(pair.domestic, 'tenant_id'),
|
||||
apiBase: OVERSEAS_API_ROOT
|
||||
apiBase: OVERSEAS_API_ROOT, authorization: pair.authorization
|
||||
})
|
||||
return true
|
||||
} catch (_) {
|
||||
@@ -179,6 +198,7 @@ export function signOut() {
|
||||
session.refreshToken = ''
|
||||
session.tenantId = ''
|
||||
session.apiBase = OVERSEAS_API_ROOT
|
||||
session.authorization = { roles: [], authorities: [] }
|
||||
if (typeof uni !== 'undefined' && typeof uni.removeStorageSync === 'function') uni.removeStorageSync(SESSION_KEY)
|
||||
resetReceivingSession()
|
||||
resetFulfillmentSession()
|
||||
|
||||
Reference in New Issue
Block a user