[598-51][@ant] fix: разрешить пайщику получать собственные кошельки и не терять их при частичном отказе запроса — RolesGuard пропускал self-access только через вложенные data.username/filter.username, из-за чего обычные пайщики (role=user, не председатель и не член совета) получали 401 на getUserWallets; Promise.all в useWalletStore.loadUserWallet из-за этого обнулял program_wallets и agreements целиком, поэтому мини-кошелёк в левом drawer'е не появлялся, а гейт подписи ЦПП зацикливался и требовал подписать уже подписанные документы заново
This commit is contained in:
@@ -11,7 +11,7 @@ export class RolesGuard implements CanActivate {
|
||||
* Работает следующим образом:
|
||||
* 1. Если присутствует заголовок `server-secret`, доступ разрешён.
|
||||
* 2. Если роли не заданы через декоратор `@AuthRoles`, доступ открыт.
|
||||
* 3. Если пользователь обращается к своим ресурсам (поле `username` внутри объекта `data` в запросе совпадает с `user.username`), доступ разрешён.
|
||||
* 3. Если пользователь обращается к своим ресурсам (поле `username` — вложенное в `data`/`filter`, либо плоский аргумент — совпадает с `user.username`), доступ разрешён.
|
||||
* 4. Если пользователь имеет хотя бы одну из разрешённых ролей, доступ разрешён.
|
||||
* 5. В иных случаях доступ запрещён, выбрасывается ошибка с кодом 401.
|
||||
*
|
||||
@@ -50,7 +50,8 @@ export class RolesGuard implements CanActivate {
|
||||
const filter = args.filter;
|
||||
|
||||
if ((data && data.username && user.username === data.username) ||
|
||||
(filter && filter.username && user.username === filter.username)) {
|
||||
(filter && filter.username && user.username === filter.username) ||
|
||||
(args.username && user.username === args.username)) {
|
||||
return true; // Если username совпадает, разрешаем доступ
|
||||
}
|
||||
|
||||
|
||||
@@ -123,9 +123,18 @@ export const useWalletStore = defineStore(namespace, (): IWalletStore => {
|
||||
_patches.value = [];
|
||||
};
|
||||
|
||||
// Запросы независимы (разные срезы кошелька/соглашений) — allSettled, а не
|
||||
// all: падение одного (напр. недостаточно прав на один из резолверов) не
|
||||
// должно обнулять остальные пять уже успешно загруженных.
|
||||
function unwrap<T>(result: PromiseSettledResult<T>, fallback: T): T {
|
||||
if (result.status === 'fulfilled') return result.value ?? fallback;
|
||||
console.error(result.reason);
|
||||
return fallback;
|
||||
}
|
||||
|
||||
const loadUserWallet = async (params: ILoadUserWallet) => {
|
||||
try {
|
||||
const data = await Promise.all([
|
||||
const [depositsRes, withdrawsRes, programWalletsRes, methodsRes, agreementsRes, userWalletsRes] =
|
||||
await Promise.allSettled([
|
||||
api.loadUserDepositsData(params),
|
||||
api.loadUserWithdrawsData(params),
|
||||
api.loadUserProgramWalletsData(params),
|
||||
@@ -134,19 +143,16 @@ export const useWalletStore = defineStore(namespace, (): IWalletStore => {
|
||||
api.loadUserWalletsData(params),
|
||||
]);
|
||||
|
||||
deposits.value = data[0] ?? [];
|
||||
withdraws.value = data[1] ?? [];
|
||||
_program_wallets_base.value = data[2] ?? [];
|
||||
methods.value = data[3] ?? [];
|
||||
agreements.value = data[4] ?? [];
|
||||
user_wallets.value = data[5] ?? [];
|
||||
// Серверная правда выигрывает — все наложенные оптимистичные патчи
|
||||
// сбрасываются. Если расхождение есть, оно будет видно сразу (а не
|
||||
// как «откат через TTL» через несколько секунд).
|
||||
clearOptimisticPatches();
|
||||
} catch (e: any) {
|
||||
console.log(e);
|
||||
}
|
||||
deposits.value = unwrap(depositsRes, []);
|
||||
withdraws.value = unwrap(withdrawsRes, []);
|
||||
_program_wallets_base.value = unwrap(programWalletsRes, []);
|
||||
methods.value = unwrap(methodsRes, []);
|
||||
agreements.value = unwrap(agreementsRes, []);
|
||||
user_wallets.value = unwrap(userWalletsRes, []);
|
||||
// Серверная правда выигрывает — все наложенные оптимистичные патчи
|
||||
// сбрасываются. Если расхождение есть, оно будет видно сразу (а не
|
||||
// как «откат через TTL» через несколько секунд).
|
||||
clearOptimisticPatches();
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user