优化
This commit is contained in:
@@ -100,6 +100,30 @@ describe('admin auth session', () => {
|
|||||||
expect(auth.refreshToken).toBe('refresh-domestic')
|
expect(auth.refreshToken).toBe('refresh-domestic')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('accepts serialized long lifetimes from the real authentication response', async () => {
|
||||||
|
mocks.post.mockResolvedValue({
|
||||||
|
code: '200',
|
||||||
|
message: 'success',
|
||||||
|
data: {
|
||||||
|
tokenType: 'Bearer',
|
||||||
|
accessToken: token(),
|
||||||
|
expiresIn: '7200',
|
||||||
|
refreshToken: 'refresh-serialized',
|
||||||
|
refreshExpiresIn: '604800',
|
||||||
|
overseasAccessToken: null,
|
||||||
|
overseasExpiresIn: '0',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
mocks.listCurrentPlatformPermissionCodes.mockResolvedValue(['platform:warehouse:list'])
|
||||||
|
const auth = useAuthStore()
|
||||||
|
|
||||||
|
await auth.login('platform_admin', 'password')
|
||||||
|
|
||||||
|
expect(auth.isAuthenticated).toBe(true)
|
||||||
|
expect(auth.refreshToken).toBe('refresh-serialized')
|
||||||
|
expect([...auth.permissionCodes]).toEqual(['platform:warehouse:list'])
|
||||||
|
})
|
||||||
|
|
||||||
it('loads permissions from the current authorization endpoint when the JWT only contains identity', async () => {
|
it('loads permissions from the current authorization endpoint when the JWT only contains identity', async () => {
|
||||||
mocks.post.mockResolvedValue(loginResponse())
|
mocks.post.mockResolvedValue(loginResponse())
|
||||||
mocks.listCurrentPlatformPermissionCodes.mockResolvedValue(['platform:warehouse:list'])
|
mocks.listCurrentPlatformPermissionCodes.mockResolvedValue(['platform:warehouse:list'])
|
||||||
|
|||||||
+14
-4
@@ -21,16 +21,26 @@ const REFRESH_LOCK_NAME = 'cc-admin-auth-refresh'
|
|||||||
interface LoginResponse {
|
interface LoginResponse {
|
||||||
tokenType: string
|
tokenType: string
|
||||||
accessToken: string
|
accessToken: string
|
||||||
expiresIn: number
|
expiresIn: number | string
|
||||||
refreshToken: string
|
refreshToken: string
|
||||||
refreshExpiresIn: number
|
refreshExpiresIn: number | string
|
||||||
overseasAccessToken?: string | null
|
overseasAccessToken?: string | null
|
||||||
overseasExpiresIn?: number
|
overseasExpiresIn?: number | string
|
||||||
}
|
}
|
||||||
|
|
||||||
class ExpiredAccessTokenError extends Error {}
|
class ExpiredAccessTokenError extends Error {}
|
||||||
class SupersededSessionError extends Error {}
|
class SupersededSessionError extends Error {}
|
||||||
|
|
||||||
|
function parseLifetimeSeconds(value: number | string, field: string) {
|
||||||
|
const normalized = typeof value === 'number'
|
||||||
|
? value
|
||||||
|
: /^\d+$/.test(value.trim()) ? Number(value) : Number.NaN
|
||||||
|
if (!Number.isSafeInteger(normalized) || normalized < 0) {
|
||||||
|
throw new Error(`登录响应中的 ${field} 格式无效`)
|
||||||
|
}
|
||||||
|
return normalized
|
||||||
|
}
|
||||||
|
|
||||||
function sessionFromToken(token: string) {
|
function sessionFromToken(token: string) {
|
||||||
const claims = decodeJwtClaims(token)
|
const claims = decodeJwtClaims(token)
|
||||||
if (claims.app_code !== 'PLATFORM') throw new Error('账号不属于当前应用端')
|
if (claims.app_code !== 'PLATFORM') throw new Error('账号不属于当前应用端')
|
||||||
@@ -92,7 +102,7 @@ export const useAuthStore = defineStore('admin-auth', () => {
|
|||||||
ensureCurrentGeneration(expectedGeneration)
|
ensureCurrentGeneration(expectedGeneration)
|
||||||
replaceOverseasAccessToken(
|
replaceOverseasAccessToken(
|
||||||
result.overseasAccessToken ?? null,
|
result.overseasAccessToken ?? null,
|
||||||
result.overseasExpiresIn ?? 0,
|
parseLifetimeSeconds(result.overseasExpiresIn ?? 0, 'overseasExpiresIn'),
|
||||||
)
|
)
|
||||||
token.value = result.accessToken
|
token.value = result.accessToken
|
||||||
refreshToken.value = result.refreshToken
|
refreshToken.value = result.refreshToken
|
||||||
|
|||||||
Reference in New Issue
Block a user