d63ab86e70
- roleMenuItems.js: merged menu builder that unions items from all user roles (student + missionary, student + counselor, etc.) additively - auth store: expose `roles` array in addition to singular `role`; wire in WordPress auth-status cookie sync so the public site can show/hide the account button - router guards: use roles.includes() instead of role === for multi-role access - layouts (Student/Counselor/Missionary): delegate menuItems to buildMergedMenuItems so dual-role users see sections from both roles - StudentSessionDetailsPage: contentKind now returns 'video' (not 'link') when session.videoUrl is set; adds embed iframe branch for online sessions - CertificateItem.vue: fix CSS order/alignment for desktop + mobile layout - StudentCertificatesPage.vue: map backend payload fields to component props with Jalaali date formatting - SessionFormPage: upload progress bar (%) during video uploads; embed_code textarea for online sessions (frontend-only; dormant until batch-2 backend migration is deployed) - wp-sync/auth-status-cookie.js: cookie helper for WordPress login-state sync [batch-1-low-risk]
62 lines
2.5 KiB
JavaScript
62 lines
2.5 KiB
JavaScript
import { ROLE_HOME_ROUTES } from '@/enums'
|
|
|
|
// Read by the WordPress site (madresebanoo.ir) to show/hide its "account"
|
|
// button and link it to the right dashboard, without ever seeing a real
|
|
// auth token. Must stay in sync with whatever the WP/Elementor side expects
|
|
// — see the implementation report for the exact contract.
|
|
const COOKIE_NAME = 'mb_auth_status'
|
|
const ROOT_DOMAIN = 'madresebanoo.ir'
|
|
|
|
const isOnRootDomain = () => {
|
|
const host = window.location.hostname
|
|
return host === ROOT_DOMAIN || host.endsWith(`.${ROOT_DOMAIN}`)
|
|
}
|
|
|
|
const cookieAttributes = () => {
|
|
const attrs = ['Path=/', 'SameSite=Lax']
|
|
// A Domain=.madresebanoo.ir cookie is only accepted by the browser when the
|
|
// current page is actually on that domain (prod). On local dev
|
|
// (127.0.0.1/localhost) we fall back to a host-only cookie so the sync
|
|
// logic is still exercised, instead of silently failing to set anything.
|
|
if (isOnRootDomain()) attrs.push(`Domain=.${ROOT_DOMAIN}`)
|
|
// Secure cookies are dropped by the browser on plain http, which local dev
|
|
// serves over. Only require it where it can actually work (prod, https).
|
|
if (window.location.protocol === 'https:') attrs.push('Secure')
|
|
return attrs
|
|
}
|
|
|
|
const writeCookie = (value, { expire = false } = {}) => {
|
|
const attrs = cookieAttributes()
|
|
attrs.push(expire ? 'Max-Age=0' : '') // no Max-Age on set = session cookie
|
|
// This cookie must be readable by a separate WordPress site with plain JS
|
|
// (no httpOnly), and needs Domain/SameSite attributes the CookieStore API
|
|
// doesn't uniformly support yet — document.cookie is the correct tool here.
|
|
// eslint-disable-next-line unicorn/no-document-cookie
|
|
document.cookie = [`${COOKIE_NAME}=${value}`, ...attrs].filter(Boolean).join('; ')
|
|
}
|
|
|
|
const dashboardPathFor = async (role) => {
|
|
try {
|
|
const { default: router } = await import('@/router')
|
|
const routeName = ROLE_HOME_ROUTES[role] || 'student-dashboard'
|
|
return router.resolve({ name: routeName }).path
|
|
} catch {
|
|
return '/dashboard'
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sets mb_auth_status to a non-sensitive JSON blob describing display state
|
|
* only: `{ loggedIn: true, dashboardPath }`. Never put the access token,
|
|
* password, or any credential in this cookie.
|
|
*/
|
|
export const syncAuthStatusCookie = async (role) => {
|
|
const dashboardPath = await dashboardPathFor(role)
|
|
const value = encodeURIComponent(JSON.stringify({ loggedIn: true, dashboardPath }))
|
|
writeCookie(value)
|
|
}
|
|
|
|
export const clearAuthStatusCookie = () => {
|
|
writeCookie('', { expire: true })
|
|
}
|