@driveflux/auth 4.0.88 → 4.0.90
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AuthProvider.d.ts.map +1 -1
- package/dist/AuthProvider.js +60 -79
- package/dist/authorization/define.js +28 -57
- package/dist/authorization/fields/index.js +7 -4
- package/dist/authorization/helpers.js +8 -10
- package/dist/authorization/index.js +6 -6
- package/dist/authorization/permissions-list.js +7 -5
- package/dist/authorization/quick.js +1 -1
- package/dist/authorization/roles/admin/business-development-executive.js +7 -20
- package/dist/authorization/roles/admin/ceo.js +2 -4
- package/dist/authorization/roles/admin/common.d.ts.map +1 -1
- package/dist/authorization/roles/admin/common.js +3 -5
- package/dist/authorization/roles/admin/concierge.js +10 -35
- package/dist/authorization/roles/admin/customer-success-executive.js +10 -40
- package/dist/authorization/roles/admin/data-analyst.js +4 -7
- package/dist/authorization/roles/admin/designer.js +4 -7
- package/dist/authorization/roles/admin/engineer.js +4 -7
- package/dist/authorization/roles/admin/finance-executive.js +4 -11
- package/dist/authorization/roles/admin/head-of-business-development.js +4 -14
- package/dist/authorization/roles/admin/head-of-data-analytics.js +4 -14
- package/dist/authorization/roles/admin/head-of-engineering.js +6 -17
- package/dist/authorization/roles/admin/head-of-finance.js +3 -8
- package/dist/authorization/roles/admin/head-of-human-resources.js +5 -13
- package/dist/authorization/roles/admin/head-of-marketing.js +5 -17
- package/dist/authorization/roles/admin/head-of-operations.js +3 -8
- package/dist/authorization/roles/admin/head-of-product.js +6 -17
- package/dist/authorization/roles/admin/head-of-sales.js +5 -17
- package/dist/authorization/roles/admin/human-resources-executive.js +5 -12
- package/dist/authorization/roles/admin/marketing-executive.js +4 -7
- package/dist/authorization/roles/admin/product-manager.js +4 -7
- package/dist/authorization/roles/admin/sales-executive.js +8 -24
- package/dist/authorization/roles/consumer/business-admin.js +6 -19
- package/dist/authorization/roles/consumer/business-user.js +6 -18
- package/dist/authorization/roles/consumer/member.js +6 -16
- package/dist/authorization/types.js +1 -1
- package/dist/authorization/update-user-permissions.js +15 -22
- package/dist/authorization/utils.js +11 -26
- package/dist/server/authenticate-user.js +7 -11
- package/dist/server/cors.js +12 -23
- package/dist/server/credentials-provider.js +2 -2
- package/dist/server/next-auth.d.ts +12 -1
- package/dist/server/next-auth.d.ts.map +1 -1
- package/dist/server/next-auth.js +109 -104
- package/dist/server/prisma-adapter.js +52 -88
- package/dist/server/verfiy-token.js +24 -39
- package/package.json +16 -16
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthProvider.d.ts","sourceRoot":"","sources":["../src/AuthProvider.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"AuthProvider.d.ts","sourceRoot":"","sources":["../src/AuthProvider.tsx"],"names":[],"mappings":"AAWA,OAAO,EACN,KAAK,EAAE,EACP,KAAK,iBAAiB,EAMtB,MAAM,OAAO,CAAA;AAed,QAAA,MAAM,YAAY,EAAE,EAAE,CAAC,iBAAiB,CAyKvC,CAAA;AAED,eAAe,YAAY,CAAA"}
|
package/dist/AuthProvider.js
CHANGED
|
@@ -5,37 +5,38 @@ import { enhancedFetch } from '@driveflux/fetch';
|
|
|
5
5
|
import { useToastResult } from '@driveflux/ui/toast';
|
|
6
6
|
import { useTrackEvent } from '@driveflux/web-analytics/track';
|
|
7
7
|
import Cookies from 'js-cookie';
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
import Router, { useRouter } from 'next/dist/client/router.js';
|
|
11
|
-
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
8
|
+
import Router, { useRouter } from 'next/router';
|
|
9
|
+
import { useCallback, useEffect, useMemo, useRef, useState, } from 'react';
|
|
12
10
|
import useSWR from 'swr';
|
|
13
11
|
import { AuthContext } from './context.js';
|
|
14
12
|
import { translations } from './translations.js';
|
|
15
|
-
const AuthProvider = ({ children })=>{
|
|
13
|
+
const AuthProvider = ({ children }) => {
|
|
16
14
|
const { data: session, status, update } = useAuthSession();
|
|
17
15
|
const { setUserData } = useTrackEvent();
|
|
18
16
|
const [token, setToken] = useState(null);
|
|
19
17
|
/**
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
18
|
+
* A reference to a promise that fetches a new access token from the server.
|
|
19
|
+
* This is used to prevent multiple token requests from being sent simultaneously.
|
|
20
|
+
*/
|
|
21
|
+
const newTokenPromise = useRef(null);
|
|
23
22
|
const localeLogicRan = useRef(false);
|
|
24
23
|
const router = useRouter();
|
|
25
24
|
const { pathname, asPath, query, locale } = router;
|
|
26
25
|
const { toastResult } = useToastResult();
|
|
27
|
-
const { data: user, isValidating, mutate, error } = useSWR(session ? `${config.apiUrl}/user` : null, {
|
|
28
|
-
fallbackData: session
|
|
26
|
+
const { data: user, isValidating, mutate, error, } = useSWR(session ? `${config.apiUrl}/user` : null, {
|
|
27
|
+
fallbackData: session
|
|
28
|
+
?.user,
|
|
29
29
|
});
|
|
30
30
|
const isLoadingUser = status !== 'unauthenticated' && isValidating && !user;
|
|
31
31
|
/**
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
32
|
+
* Retrieves an access token for the current user. If a token is already available and has not expired, it will be returned immediately.
|
|
33
|
+
* Otherwise, the function will attempt to retrieve the token from cookies, and if that fails, it will fetch a new token from the server.
|
|
34
|
+
* If a new token is fetched, it will be stored in cookies and returned.
|
|
35
|
+
* If the user is not authenticated, the function will return null and display an error message.
|
|
36
|
+
* @returns {Promise<string | null>} A promise that resolves to the access token string, or null if the user is not authenticated.
|
|
37
|
+
*/
|
|
38
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies: <explanation>
|
|
39
|
+
const getAccessToken = useCallback(async () => {
|
|
39
40
|
// Check the state first, if we have a token, return it
|
|
40
41
|
if (token && token.expiresAt > new Date()) {
|
|
41
42
|
return token.accessToken;
|
|
@@ -48,17 +49,19 @@ const AuthProvider = ({ children })=>{
|
|
|
48
49
|
if (expiresAt > new Date()) {
|
|
49
50
|
setToken({
|
|
50
51
|
accessToken: tokenFromCookies.accessToken,
|
|
51
|
-
expiresAt
|
|
52
|
+
expiresAt,
|
|
52
53
|
});
|
|
53
54
|
}
|
|
54
55
|
return tokenFromCookies.accessToken;
|
|
55
56
|
}
|
|
56
|
-
} catch (_e) {
|
|
57
|
-
// TODO
|
|
58
|
-
// Nothing to do here
|
|
59
57
|
}
|
|
60
|
-
|
|
61
|
-
|
|
58
|
+
catch (_e) {
|
|
59
|
+
// TODO
|
|
60
|
+
// Nothing to do here
|
|
61
|
+
}
|
|
62
|
+
const tokenPromise = newTokenPromise.current ||
|
|
63
|
+
// biome-ignore lint/suspicious/noAssignInExpressions: <explanation>
|
|
64
|
+
(newTokenPromise.current = enhancedFetch(`${config.apiUrl}/user/token`));
|
|
62
65
|
// As a last resort, fetch a new token
|
|
63
66
|
const newToken = await tokenPromise;
|
|
64
67
|
// Resets the newTokenPromise reference to null after the new token has been fetched.
|
|
@@ -67,50 +70,42 @@ const AuthProvider = ({ children })=>{
|
|
|
67
70
|
toastResult(newToken, {
|
|
68
71
|
error: {
|
|
69
72
|
title: translations.unauthenticated,
|
|
70
|
-
description: translations.unauthenticatedDescription
|
|
71
|
-
}
|
|
73
|
+
description: translations.unauthenticatedDescription,
|
|
74
|
+
},
|
|
72
75
|
});
|
|
73
76
|
return null;
|
|
74
77
|
}
|
|
75
78
|
const newTokenDetils = {
|
|
76
79
|
accessToken: newToken.val.id,
|
|
77
|
-
expiresAt: new Date(newToken.val.expiresAt)
|
|
80
|
+
expiresAt: new Date(newToken.val.expiresAt),
|
|
78
81
|
};
|
|
79
82
|
Cookies.set('accessTokenDetails', JSON.stringify(newTokenDetils));
|
|
80
83
|
setToken(newTokenDetils);
|
|
81
84
|
return newToken.val.id;
|
|
82
|
-
}, [
|
|
83
|
-
|
|
84
|
-
]);
|
|
85
|
-
const refresh = useCallback(async ()=>{
|
|
85
|
+
}, [token]);
|
|
86
|
+
const refresh = useCallback(async () => {
|
|
86
87
|
await update();
|
|
87
88
|
return await mutate();
|
|
88
|
-
}, [
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
]);
|
|
92
|
-
const logout = useCallback(async ()=>{
|
|
93
|
-
await signOut({
|
|
94
|
-
redirect: false
|
|
95
|
-
});
|
|
89
|
+
}, [mutate, update]);
|
|
90
|
+
const logout = useCallback(async () => {
|
|
91
|
+
await signOut({ redirect: false });
|
|
96
92
|
await refresh();
|
|
97
|
-
}, [
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
}), [
|
|
93
|
+
}, [refresh]);
|
|
94
|
+
const context = useMemo(() => ({
|
|
95
|
+
user,
|
|
96
|
+
isLoadingUser,
|
|
97
|
+
refresh,
|
|
98
|
+
error,
|
|
99
|
+
getAccessToken,
|
|
100
|
+
// TODO
|
|
101
|
+
/**
|
|
102
|
+
* @deprecated do not use this property, use getAccessToken instead
|
|
103
|
+
*/
|
|
104
|
+
accessToken: token?.accessToken,
|
|
105
|
+
signIn,
|
|
106
|
+
logout,
|
|
107
|
+
status,
|
|
108
|
+
}), [
|
|
114
109
|
user,
|
|
115
110
|
isLoadingUser,
|
|
116
111
|
refresh,
|
|
@@ -118,11 +113,11 @@ const AuthProvider = ({ children })=>{
|
|
|
118
113
|
getAccessToken,
|
|
119
114
|
logout,
|
|
120
115
|
token,
|
|
121
|
-
status
|
|
116
|
+
status,
|
|
122
117
|
]);
|
|
123
118
|
// Add preferredLocal if any
|
|
124
119
|
// biome-ignore lint/correctness/useExhaustiveDependencies: <explanation>
|
|
125
|
-
useEffect(()=>{
|
|
120
|
+
useEffect(() => {
|
|
126
121
|
if (localeLogicRan.current || !user) {
|
|
127
122
|
return;
|
|
128
123
|
}
|
|
@@ -130,37 +125,23 @@ const AuthProvider = ({ children })=>{
|
|
|
130
125
|
const langFromCookies = Cookies.get('NEXT_LOCALE');
|
|
131
126
|
if (user?.preferredLocale && langFromCookies !== user?.preferredLocale) {
|
|
132
127
|
Cookies.set('NEXT_LOCALE', user.preferredLocale);
|
|
133
|
-
Router.push({
|
|
134
|
-
pathname,
|
|
135
|
-
query
|
|
136
|
-
}, asPath, {
|
|
137
|
-
locale: user.preferredLocale
|
|
138
|
-
});
|
|
128
|
+
Router.push({ pathname, query }, asPath, { locale: user.preferredLocale });
|
|
139
129
|
}
|
|
140
|
-
}, [
|
|
141
|
-
user?.preferredLocale,
|
|
142
|
-
pathname,
|
|
143
|
-
query,
|
|
144
|
-
asPath
|
|
145
|
-
]);
|
|
130
|
+
}, [user?.preferredLocale, pathname, query, asPath]);
|
|
146
131
|
// Add user to the tracking
|
|
147
132
|
// biome-ignore lint/correctness/useExhaustiveDependencies: <explanation>
|
|
148
|
-
useEffect(()=>{
|
|
149
|
-
if (!user)
|
|
133
|
+
useEffect(() => {
|
|
134
|
+
if (!user)
|
|
135
|
+
return;
|
|
150
136
|
setUserData({
|
|
151
137
|
id: user.id,
|
|
152
138
|
email: user.email,
|
|
153
139
|
phoneNumber: user.phoneNumber,
|
|
154
140
|
firstName: user.firstName,
|
|
155
141
|
lastName: user.lastName,
|
|
156
|
-
addresses: user.addresses
|
|
142
|
+
addresses: user.addresses,
|
|
157
143
|
});
|
|
158
|
-
}, [
|
|
159
|
-
|
|
160
|
-
]);
|
|
161
|
-
return /*#__PURE__*/ _jsx(AuthContext.Provider, {
|
|
162
|
-
value: context,
|
|
163
|
-
children: children
|
|
164
|
-
});
|
|
144
|
+
}, [user]);
|
|
145
|
+
return _jsx(AuthContext.Provider, { value: context, children: children });
|
|
165
146
|
};
|
|
166
147
|
export default AuthProvider;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AbilityBuilder } from '@casl/ability';
|
|
2
2
|
import { createPrismaAbility } from '@casl/prisma';
|
|
3
|
-
import { ALL_ADMIN_ROLES, CONSUMER_ROLES, GENERAL_ROLES, HIGHER_ADMIN_ROLES, OWNER_ROLES } from './constants.js';
|
|
3
|
+
import { ALL_ADMIN_ROLES, CONSUMER_ROLES, GENERAL_ROLES, HIGHER_ADMIN_ROLES, OWNER_ROLES, } from './constants.js';
|
|
4
4
|
import { defineRoleAbilitiesBusinessDevelopmentExecutive } from './roles/admin/business-development-executive.js';
|
|
5
5
|
import { defineRoleAbilitiesCeo } from './roles/admin/ceo.js';
|
|
6
6
|
import { defineRoleAbilitiesCommonAdmin } from './roles/admin/common.js';
|
|
@@ -26,64 +26,45 @@ import { defineRoleAbilitiesSalesExecutive } from './roles/admin/sales-executive
|
|
|
26
26
|
import { defineRoleAbilitiesBusinessAdmin } from './roles/consumer/business-admin.js';
|
|
27
27
|
import { defineRoleAbilitiesBusinessUser } from './roles/consumer/business-user.js';
|
|
28
28
|
import { defineRoleAbilitiesMember } from './roles/consumer/member.js';
|
|
29
|
-
export const defineAbilityFor = async (user)=>{
|
|
29
|
+
export const defineAbilityFor = async (user) => {
|
|
30
30
|
const { can, cannot, build } = new AbilityBuilder(createPrismaAbility);
|
|
31
31
|
if (!user) {
|
|
32
32
|
return build();
|
|
33
33
|
}
|
|
34
|
-
const groups = Array.isArray(user.groups)
|
|
35
|
-
user.groups
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
for (const role of sortedGroups){
|
|
34
|
+
const groups = Array.isArray(user.groups)
|
|
35
|
+
? user.groups.map((r) => `${r}`)
|
|
36
|
+
: typeof user.groups === 'string'
|
|
37
|
+
? [user.groups]
|
|
38
|
+
: [];
|
|
39
|
+
const consumerGroups = groups.filter((g) => CONSUMER_ROLES.includes(g));
|
|
40
|
+
const adminGroups = groups.filter((g) => !consumerGroups.includes(g));
|
|
41
|
+
const sortedGroups = [...consumerGroups, ...adminGroups];
|
|
42
|
+
for (const role of sortedGroups) {
|
|
44
43
|
await defineSpecificRoleAbilities(role, can, cannot, user);
|
|
45
44
|
}
|
|
46
45
|
// Common admin abilities
|
|
47
|
-
if (user.groups.some((g)=>adminGroups.includes(g))) {
|
|
46
|
+
if (user.groups.some((g) => adminGroups.includes(g))) {
|
|
48
47
|
await defineRoleAbilitiesCommonAdmin(can);
|
|
49
48
|
}
|
|
50
49
|
// General abilities
|
|
51
|
-
can([
|
|
52
|
-
|
|
53
|
-
'update'
|
|
54
|
-
], 'User', {
|
|
55
|
-
id: user.id
|
|
56
|
-
});
|
|
57
|
-
can([
|
|
58
|
-
'read'
|
|
59
|
-
], 'Invoice', {
|
|
60
|
-
payerId: user.id
|
|
61
|
-
});
|
|
50
|
+
can(['read', 'update'], 'User', { id: user.id });
|
|
51
|
+
can(['read'], 'Invoice', { payerId: user.id });
|
|
62
52
|
if (user.businessId) {
|
|
63
|
-
can([
|
|
64
|
-
'read'
|
|
65
|
-
], 'Invoice', {
|
|
66
|
-
payerId: user.businessId
|
|
67
|
-
});
|
|
53
|
+
can(['read'], 'Invoice', { payerId: user.businessId });
|
|
68
54
|
}
|
|
69
|
-
can('reserveVehicle', 'User', {
|
|
70
|
-
banned: false,
|
|
71
|
-
consented: true
|
|
72
|
-
});
|
|
55
|
+
can('reserveVehicle', 'User', { banned: false, consented: true });
|
|
73
56
|
// Prevent updating the groups for all users
|
|
74
|
-
cannot('update', 'User', [
|
|
75
|
-
'groups'
|
|
76
|
-
]);
|
|
57
|
+
cannot('update', 'User', ['groups']);
|
|
77
58
|
return build();
|
|
78
59
|
};
|
|
79
|
-
const defineSpecificRoleAbilities = async (r, can, cannot, rawUser)=>{
|
|
60
|
+
const defineSpecificRoleAbilities = async (r, can, cannot, rawUser) => {
|
|
80
61
|
if (!~GENERAL_ROLES.indexOf(r)) {
|
|
81
62
|
return;
|
|
82
63
|
}
|
|
83
64
|
// Type issue
|
|
84
65
|
const user = rawUser;
|
|
85
66
|
const role = r;
|
|
86
|
-
switch(role){
|
|
67
|
+
switch (role) {
|
|
87
68
|
// Owners
|
|
88
69
|
case 'ceo':
|
|
89
70
|
defineRoleAbilitiesCeo(can);
|
|
@@ -161,30 +142,20 @@ const defineSpecificRoleAbilities = async (r, can, cannot, rawUser)=>{
|
|
|
161
142
|
case 'businessAdmin':
|
|
162
143
|
defineRoleAbilitiesBusinessAdmin(can, user);
|
|
163
144
|
break;
|
|
164
|
-
default:
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
}
|
|
145
|
+
default: {
|
|
146
|
+
const _exhaustiveCheck = role;
|
|
147
|
+
break;
|
|
148
|
+
}
|
|
169
149
|
}
|
|
170
|
-
if (![
|
|
171
|
-
...OWNER_ROLES,
|
|
172
|
-
...HIGHER_ADMIN_ROLES
|
|
173
|
-
].includes(role)) {
|
|
150
|
+
if (![...OWNER_ROLES, ...HIGHER_ADMIN_ROLES].includes(role)) {
|
|
174
151
|
cannot('manageAdmin', 'User');
|
|
175
|
-
cannot([
|
|
176
|
-
'create',
|
|
177
|
-
'update',
|
|
178
|
-
'delete'
|
|
179
|
-
], 'User', undefined, {
|
|
152
|
+
cannot(['create', 'update', 'delete'], 'User', undefined, {
|
|
180
153
|
groups: {
|
|
181
|
-
hasSome: [
|
|
182
|
-
|
|
183
|
-
]
|
|
184
|
-
}
|
|
154
|
+
hasSome: [...ALL_ADMIN_ROLES],
|
|
155
|
+
},
|
|
185
156
|
}).because('You are not allowed to update admin users');
|
|
186
157
|
can('update', 'User', undefined, {
|
|
187
|
-
id: user.id
|
|
158
|
+
id: user.id,
|
|
188
159
|
});
|
|
189
160
|
}
|
|
190
161
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Prisma, prisma } from '@driveflux/db';
|
|
2
|
-
export const MODEL_FIELDS = Object.keys(Prisma.ModelName)
|
|
2
|
+
export const MODEL_FIELDS = Object.keys(Prisma.ModelName)
|
|
3
|
+
.map((k) => {
|
|
3
4
|
if (!(k in Prisma.ModelName)) {
|
|
4
5
|
return null;
|
|
5
6
|
}
|
|
@@ -7,15 +8,17 @@ export const MODEL_FIELDS = Object.keys(Prisma.ModelName).map((k)=>{
|
|
|
7
8
|
return {
|
|
8
9
|
// TODO
|
|
9
10
|
// @ts-expect-error
|
|
10
|
-
[key]: prisma._runtimeDataModel.models[key].fields.map((f)=>f.name)
|
|
11
|
+
[key]: prisma._runtimeDataModel.models[key].fields.map((f) => f.name),
|
|
11
12
|
};
|
|
12
|
-
})
|
|
13
|
+
})
|
|
14
|
+
.filter((m) => m)
|
|
15
|
+
.reduce((carry, current) => {
|
|
13
16
|
if (current) {
|
|
14
17
|
Object.assign(carry, current);
|
|
15
18
|
}
|
|
16
19
|
return carry;
|
|
17
20
|
}, {});
|
|
18
|
-
export const getModelFields = (model)=>{
|
|
21
|
+
export const getModelFields = (model) => {
|
|
19
22
|
const fields = MODEL_FIELDS[model];
|
|
20
23
|
return fields;
|
|
21
24
|
};
|
|
@@ -1,18 +1,16 @@
|
|
|
1
1
|
import { ALL_ADMIN_ROLES, CONSUMER_ROLES, OWNER_ROLES } from './constants';
|
|
2
|
-
export const extractAdminRoles = (userGroups)=>{
|
|
3
|
-
return userGroups?.filter((group)=>isAdmin(group));
|
|
2
|
+
export const extractAdminRoles = (userGroups) => {
|
|
3
|
+
return userGroups?.filter((group) => isAdmin(group));
|
|
4
4
|
};
|
|
5
|
-
export const extractNonAdminRoles = (userGroups)=>{
|
|
6
|
-
return userGroups?.filter((group)
|
|
5
|
+
export const extractNonAdminRoles = (userGroups) => {
|
|
6
|
+
return userGroups?.filter((group) => !isAdmin(group));
|
|
7
7
|
};
|
|
8
|
-
export const isConsumer = (group)=>{
|
|
8
|
+
export const isConsumer = (group) => {
|
|
9
9
|
return CONSUMER_ROLES.includes(group);
|
|
10
10
|
};
|
|
11
|
-
export const isOwner = (group)=>{
|
|
12
|
-
return [
|
|
13
|
-
...OWNER_ROLES
|
|
14
|
-
]?.map((r)=>group === r)?.[0];
|
|
11
|
+
export const isOwner = (group) => {
|
|
12
|
+
return [...OWNER_ROLES]?.map((r) => group === r)?.[0];
|
|
15
13
|
};
|
|
16
|
-
export const isAdmin = (group)=>{
|
|
14
|
+
export const isAdmin = (group) => {
|
|
17
15
|
return ALL_ADMIN_ROLES.includes(group);
|
|
18
16
|
};
|
|
@@ -4,15 +4,15 @@ import { ErrorWithResult } from '@driveflux/result';
|
|
|
4
4
|
import { GUEST_PERMISSIONS } from './constants.js';
|
|
5
5
|
import buildAbilityFromJson from './quick.js';
|
|
6
6
|
import { updateUserPermissions } from './update-user-permissions.js';
|
|
7
|
-
export const buildOrDefineAbility = async (user, refresh)=>{
|
|
7
|
+
export const buildOrDefineAbility = async (user, refresh) => {
|
|
8
8
|
if (!user) {
|
|
9
|
-
return createPrismaAbility([
|
|
10
|
-
|
|
11
|
-
], {
|
|
12
|
-
detectSubjectType: detectSubjectType
|
|
9
|
+
return createPrismaAbility([...GUEST_PERMISSIONS], {
|
|
10
|
+
detectSubjectType: detectSubjectType,
|
|
13
11
|
});
|
|
14
12
|
}
|
|
15
|
-
if (!Array.isArray(user.permissions) ||
|
|
13
|
+
if (!Array.isArray(user.permissions) ||
|
|
14
|
+
!user.permissions?.length ||
|
|
15
|
+
refresh) {
|
|
16
16
|
const result = await updateUserPermissions(user);
|
|
17
17
|
if (result.err) {
|
|
18
18
|
throw new ErrorWithResult(result);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { s } from './utils.js';
|
|
2
|
-
export const getPermissionsFromAbility = (ability)=>{
|
|
2
|
+
export const getPermissionsFromAbility = (ability) => {
|
|
3
3
|
return {
|
|
4
4
|
// Lists
|
|
5
5
|
viewContractsList: ability.can('read', 'SubscriptionContract'),
|
|
@@ -53,7 +53,7 @@ export const getPermissionsFromAbility = (ability)=>{
|
|
|
53
53
|
updateVehicleServiceCenters: ability.can('update', 'Vehicle', 'allowedServiceCenterIds'),
|
|
54
54
|
readPricingInput: ability.can('readPricingInput', 'Vehicle'),
|
|
55
55
|
updatePricingInput: ability.can('update', 'Vehicle', 'pricing'),
|
|
56
|
-
testPricingInput: ability.can('testPricingInput', 'Vehicle'),
|
|
56
|
+
testPricingInput: ability.can('testPricingInput', 'Vehicle'), // Special Permission to allow users edit pricing but without the ability to update
|
|
57
57
|
// Users ( Members )
|
|
58
58
|
createMember: ability.can('create', 'User'),
|
|
59
59
|
updateMember: ability.can('update', s('User')),
|
|
@@ -84,7 +84,8 @@ export const getPermissionsFromAbility = (ability)=>{
|
|
|
84
84
|
updateInvoice: ability.can('update', s('Invoice', 'payerId')),
|
|
85
85
|
cancelInvoice: ability.can('cancelInvoice', 'Invoice'),
|
|
86
86
|
markInvoiceAsPaid: ability.can('markInvoice', 'Invoice', 'paid'),
|
|
87
|
-
markInvoiceAsRefunded: ability.can('markInvoice', 'Invoice', 'totalRefunded') &&
|
|
87
|
+
markInvoiceAsRefunded: ability.can('markInvoice', 'Invoice', 'totalRefunded') &&
|
|
88
|
+
ability.can('create', 'Refund'),
|
|
88
89
|
readPaymentMethodsUser: ability.can('read', s('User'), 'paymentMethods'),
|
|
89
90
|
readPaymentMethodsBusiness: ability.can('read', s('Business'), 'paymentMethods'),
|
|
90
91
|
addPaymentMethodUser: ability.can('update', s('User'), 'paymentMethods'),
|
|
@@ -132,7 +133,8 @@ export const getPermissionsFromAbility = (ability)=>{
|
|
|
132
133
|
// TODO add logs permision or remove the comments
|
|
133
134
|
// Logs
|
|
134
135
|
// Website Settings
|
|
135
|
-
uploadBanners: ability.can('update', 'PlatformConfig') &&
|
|
136
|
+
uploadBanners: ability.can('update', 'PlatformConfig') &&
|
|
137
|
+
ability.can('create', 'PlatformConfig'),
|
|
136
138
|
deleteBanners: ability.can('update', 'PlatformConfig'),
|
|
137
139
|
// Quotations
|
|
138
140
|
createQuotation: ability.can('create', 'Quotation'),
|
|
@@ -141,6 +143,6 @@ export const getPermissionsFromAbility = (ability)=>{
|
|
|
141
143
|
createVacancy: ability.can('create', 'Vacancy'),
|
|
142
144
|
updateVacancy: ability.can('update', 'Vacancy'),
|
|
143
145
|
readApplicant: ability.can('read', 'Applicant'),
|
|
144
|
-
readVacancy: ability.can('read', 'Vacancy')
|
|
146
|
+
readVacancy: ability.can('read', 'Vacancy'),
|
|
145
147
|
};
|
|
146
148
|
};
|
|
@@ -2,7 +2,7 @@ import { createPrismaAbility } from '@casl/prisma';
|
|
|
2
2
|
import { detectSubjectType } from './utils.js';
|
|
3
3
|
export function buildAbilityFromJson(user) {
|
|
4
4
|
return createPrismaAbility(user.permissions, {
|
|
5
|
-
detectSubjectType
|
|
5
|
+
detectSubjectType,
|
|
6
6
|
});
|
|
7
7
|
}
|
|
8
8
|
export default buildAbilityFromJson;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getDocumentsFields } from '../../utils.js';
|
|
2
|
-
export const defineRoleAbilitiesBusinessDevelopmentExecutive = async (can, cannot)=>{
|
|
2
|
+
export const defineRoleAbilitiesBusinessDevelopmentExecutive = async (can, cannot) => {
|
|
3
3
|
can('read', [
|
|
4
4
|
'Subscription',
|
|
5
5
|
'Vehicle',
|
|
@@ -13,35 +13,22 @@ export const defineRoleAbilitiesBusinessDevelopmentExecutive = async (can, canno
|
|
|
13
13
|
'PaymentLink',
|
|
14
14
|
'Invoice',
|
|
15
15
|
'Transaction',
|
|
16
|
-
'Refund'
|
|
16
|
+
'Refund',
|
|
17
17
|
]);
|
|
18
18
|
cannot('update', 'Invoice');
|
|
19
|
-
can('manage', [
|
|
20
|
-
'Vehicle',
|
|
21
|
-
'ServiceCenter',
|
|
22
|
-
'Host',
|
|
23
|
-
'Inquiry',
|
|
24
|
-
'Token'
|
|
25
|
-
]);
|
|
19
|
+
can('manage', ['Vehicle', 'ServiceCenter', 'Host', 'Inquiry', 'Token']);
|
|
26
20
|
can('readPricingInput', 'Vehicle');
|
|
27
21
|
can('connectHostToStripe', 'Host');
|
|
28
|
-
can('update', 'Subscription', [
|
|
29
|
-
'vehicleId'
|
|
30
|
-
]);
|
|
22
|
+
can('update', 'Subscription', ['vehicleId']);
|
|
31
23
|
cannot('read', 'User', 'status');
|
|
32
24
|
cannot('read', 'User', [
|
|
33
25
|
...getDocumentsFields('identification'),
|
|
34
26
|
...getDocumentsFields('drivingHistory'),
|
|
35
27
|
...getDocumentsFields('financial'),
|
|
36
|
-
...getDocumentsFields('offerLetter')
|
|
37
|
-
]);
|
|
38
|
-
can([
|
|
39
|
-
'viewSubscriptionApproval'
|
|
40
|
-
], 'Subscription');
|
|
41
|
-
cannot('read', [
|
|
42
|
-
'Vacancy',
|
|
43
|
-
'Applicant'
|
|
28
|
+
...getDocumentsFields('offerLetter'),
|
|
44
29
|
]);
|
|
30
|
+
can(['viewSubscriptionApproval'], 'Subscription');
|
|
31
|
+
cannot('read', ['Vacancy', 'Applicant']);
|
|
45
32
|
can('read', 'Activity');
|
|
46
33
|
can('read', 'ActivityTask');
|
|
47
34
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../../../src/authorization/roles/admin/common.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAEhD,eAAO,MAAM,8BAA8B,GAC1C,KAAK,cAAc,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,
|
|
1
|
+
{"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../../../src/authorization/roles/admin/common.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAEhD,eAAO,MAAM,8BAA8B,GAC1C,KAAK,cAAc,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,kBAYtC,CAAA"}
|
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
export const defineRoleAbilitiesCommonAdmin = async (can)=>{
|
|
2
|
-
can([
|
|
3
|
-
'read'
|
|
4
|
-
], [
|
|
1
|
+
export const defineRoleAbilitiesCommonAdmin = async (can) => {
|
|
2
|
+
can(['read'], [
|
|
5
3
|
'Log',
|
|
6
4
|
'Issue',
|
|
7
5
|
'SubscriptionContract',
|
|
8
6
|
'HostContribution',
|
|
9
|
-
'SubscriptionEvent'
|
|
7
|
+
'SubscriptionEvent',
|
|
10
8
|
]);
|
|
11
9
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getDocumentsFields } from '../../utils.js';
|
|
2
|
-
export const defineRoleAbilitiesConcierge = async (can, cannot)=>{
|
|
2
|
+
export const defineRoleAbilitiesConcierge = async (can, cannot) => {
|
|
3
3
|
can('read', [
|
|
4
4
|
'Subscription',
|
|
5
5
|
'Cycle',
|
|
@@ -12,14 +12,11 @@ export const defineRoleAbilitiesConcierge = async (can, cannot)=>{
|
|
|
12
12
|
'Inquiry',
|
|
13
13
|
'Discount',
|
|
14
14
|
'PlatformConfig',
|
|
15
|
-
'PaymentLink'
|
|
15
|
+
'PaymentLink',
|
|
16
16
|
]);
|
|
17
17
|
cannot('create', 'Business');
|
|
18
18
|
can('manage', 'ServiceCenter');
|
|
19
|
-
can('update', 'Vehicle', [
|
|
20
|
-
'images',
|
|
21
|
-
'allowedServiceCenterIds'
|
|
22
|
-
]);
|
|
19
|
+
can('update', 'Vehicle', ['images', 'allowedServiceCenterIds']);
|
|
23
20
|
can('readPricingInput', 'Vehicle');
|
|
24
21
|
can('update', 'Host', 'serviceCenterIds');
|
|
25
22
|
can('manage', 'Subscription');
|
|
@@ -33,38 +30,16 @@ export const defineRoleAbilitiesConcierge = async (can, cannot)=>{
|
|
|
33
30
|
'payerType',
|
|
34
31
|
'driversIds',
|
|
35
32
|
'drivers',
|
|
36
|
-
'vehicleId'
|
|
37
|
-
]);
|
|
38
|
-
can([
|
|
39
|
-
'read'
|
|
40
|
-
], [
|
|
41
|
-
'Invoice',
|
|
42
|
-
'Transaction',
|
|
43
|
-
'Refund'
|
|
33
|
+
'vehicleId',
|
|
44
34
|
]);
|
|
35
|
+
can(['read'], ['Invoice', 'Transaction', 'Refund']);
|
|
45
36
|
cannot('read', 'User', [
|
|
46
37
|
...getDocumentsFields('drivingHistory'),
|
|
47
38
|
...getDocumentsFields('financial'),
|
|
48
|
-
...getDocumentsFields('offerLetter')
|
|
49
|
-
]);
|
|
50
|
-
can([
|
|
51
|
-
'manage'
|
|
52
|
-
], [
|
|
53
|
-
'Activity',
|
|
54
|
-
'ActivityTask'
|
|
55
|
-
]);
|
|
56
|
-
cannot([
|
|
57
|
-
'create',
|
|
58
|
-
'delete'
|
|
59
|
-
], [
|
|
60
|
-
'Activity',
|
|
61
|
-
'ActivityTask'
|
|
62
|
-
]);
|
|
63
|
-
can([
|
|
64
|
-
'viewSubscriptionApproval'
|
|
65
|
-
], 'Subscription');
|
|
66
|
-
cannot('read', [
|
|
67
|
-
'Vacancy',
|
|
68
|
-
'Applicant'
|
|
39
|
+
...getDocumentsFields('offerLetter'),
|
|
69
40
|
]);
|
|
41
|
+
can(['manage'], ['Activity', 'ActivityTask']);
|
|
42
|
+
cannot(['create', 'delete'], ['Activity', 'ActivityTask']);
|
|
43
|
+
can(['viewSubscriptionApproval'], 'Subscription');
|
|
44
|
+
cannot('read', ['Vacancy', 'Applicant']);
|
|
70
45
|
};
|