fix some other bugs of iam

This commit is contained in:
Montech
2026-10-11 16:01:15 +03:30
parent e4924a28f5
commit 025d223dac
227 changed files with 376 additions and 221 deletions
+3
View File
@@ -359,6 +359,9 @@ export const api = {
`/customer/auth/sso/logout-url?return_url=${encodeURIComponent(iamAppUrl(''))}`,
),
endSharedSession: () =>
request<{ ended: number }>('/customer/auth/logout', { method: 'POST', body: '{}' }),
// The three reads below identify the customer by TOKEN. They replaced
// /customers/:id, /:id/orders and /:id/ledger-entries, which took the id from
// the URL and let anyone read anyone (SEC-08).
+3
View File
@@ -122,6 +122,9 @@ router.beforeEach(async (to) => {
try {
const started = await api.ssoStart();
if (started.enabled && started.authorize_url) {
if (to.fullPath.startsWith('/') && !to.fullPath.startsWith('//')) {
sessionStorage.setItem('gb_iam_return', to.fullPath);
}
window.location.assign(started.authorize_url);
return false;
}
@@ -242,6 +242,11 @@ function goToDetails(id: number) {
async function logOut() {
data.notify = false
try {
await api.endSharedSession()
} catch {
// خروج محلی ادامه پیدا می‌کند
}
let central: string | null = null
try {
central = (await api.ssoLogoutUrl()).logout_url
+10 -4
View File
@@ -7,13 +7,20 @@ import { useSessionStore } from '../../stores/session'
const router = useRouter()
const session = useSessionStore()
function backToCaller() {
sessionStorage.setItem('gb_iam_sso_skip', '1')
const saved = sessionStorage.getItem('gb_iam_return')
sessionStorage.removeItem('gb_iam_return')
const path = saved && saved.startsWith('/') && !saved.startsWith('//') ? saved : '/'
return router.replace(path)
}
onMounted(async () => {
const params = new URLSearchParams(window.location.search)
sessionStorage.removeItem('gb_iam_sso_checked')
if (params.get('error') || !params.get('code') || !params.get('state')) {
sessionStorage.setItem('gb_iam_sso_skip', '1')
await router.replace({ name: 'login' })
await backToCaller()
return
}
@@ -28,8 +35,7 @@ onMounted(async () => {
}
await router.replace({ name: 'home' })
} catch {
sessionStorage.setItem('gb_iam_sso_skip', '1')
await router.replace({ name: 'login' })
await backToCaller()
}
})
</script>
+4 -4
View File
@@ -162,6 +162,10 @@ const sendToken = async (otpCode: string) => {
const verified = await api.verifyOtp(String(formModel.username ?? ''), otpCode)
const { token, customer } = verified
session.login(token, customer.id, customer.mobile)
if (verified.iamBootstrapUrl) {
window.location.assign(verified.iamBootstrapUrl)
return
}
// D21 — ask the server which kind of principal this token is, so the
// expert-only entries appear for a sales expert. Failure is non-fatal:
// the entries simply stay hidden, and the server refuses those routes
@@ -172,10 +176,6 @@ const sendToken = async (otpCode: string) => {
} catch {
session.setSalesExpert(false)
}
if (verified.iamBootstrapUrl) {
window.location.assign(verified.iamBootstrapUrl)
return
}
const redirect = typeof route.query.redirect === 'string' ? route.query.redirect : undefined
await router.push(redirect ?? { name: 'home' })
toast.success('با موفقیت وارد شدید')