@communecter/cocolight-api-client 1.0.78 → 1.0.79
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/cocolight-api-client.browser.js +3 -3
- package/dist/cocolight-api-client.cjs +1 -1
- package/dist/cocolight-api-client.mjs.js +1 -1
- package/dist/cocolight-api-client.vite.mjs.js +1 -1
- package/dist/cocolight-api-client.vite.mjs.js.map +1 -1
- package/package.json +1 -1
- package/src/api/BaseEntity.ts +6 -4
- package/src/api/EndpointApi.ts +17 -1
- package/src/api/EndpointApi.types.ts +14 -0
- package/src/api/User.ts +494 -16
- package/src/api/serverDataType/common.ts +1 -0
- package/src/endpoints.module.ts +1 -1
- package/types/api/BaseEntity.d.ts +2 -0
- package/types/api/EndpointApi.d.ts +11 -1
- package/types/api/EndpointApi.types.d.ts +12 -0
- package/types/api/User.d.ts +226 -3
- package/types/api/serverDataType/common.d.ts +1 -0
- package/types/endpoints.module.d.ts +356 -0
package/package.json
CHANGED
package/src/api/BaseEntity.ts
CHANGED
|
@@ -230,6 +230,8 @@ type LinkFilters = Record<string, FilterValue>;
|
|
|
230
230
|
interface MinimalUserLink {
|
|
231
231
|
toBeValidated?: boolean;
|
|
232
232
|
isInviting?: boolean;
|
|
233
|
+
isAdminInviting?: boolean;
|
|
234
|
+
isAdminPending?: boolean;
|
|
233
235
|
}
|
|
234
236
|
|
|
235
237
|
// Types pour linkEntitiesFromServerData
|
|
@@ -2406,7 +2408,7 @@ export class BaseEntity<TServerData = any> {
|
|
|
2406
2408
|
}
|
|
2407
2409
|
|
|
2408
2410
|
// Invitation reçue → accepte automatiquement
|
|
2409
|
-
if (userLink.isInviting) {
|
|
2411
|
+
if (userLink.isInviting || userLink.isAdminInviting) {
|
|
2410
2412
|
return this._acceptLinkRequest();
|
|
2411
2413
|
}
|
|
2412
2414
|
|
|
@@ -2443,7 +2445,7 @@ export class BaseEntity<TServerData = any> {
|
|
|
2443
2445
|
|
|
2444
2446
|
const userLink = this._getLinkFromConnectedUser();
|
|
2445
2447
|
|
|
2446
|
-
if (userLink && userLink.isInviting) {
|
|
2448
|
+
if (userLink && (userLink.isInviting || userLink.isAdminInviting)) {
|
|
2447
2449
|
const t = this.getEntityType();
|
|
2448
2450
|
|
|
2449
2451
|
// 1) Garde runtime pour exclure les types non pris en charge par LinkValidateData
|
|
@@ -3382,8 +3384,8 @@ export class BaseEntity<TServerData = any> {
|
|
|
3382
3384
|
*/
|
|
3383
3385
|
protected _validateUserLink(userLink: MinimalUserLink | null | undefined): boolean {
|
|
3384
3386
|
if (!userLink) return false;
|
|
3385
|
-
const { toBeValidated, isInviting } = userLink;
|
|
3386
|
-
return !toBeValidated && !isInviting;
|
|
3387
|
+
const { toBeValidated, isInviting, isAdminInviting, isAdminPending } = userLink;
|
|
3388
|
+
return !toBeValidated && !isInviting && !isAdminInviting && !isAdminPending;
|
|
3387
3389
|
}
|
|
3388
3390
|
|
|
3389
3391
|
/**
|
package/src/api/EndpointApi.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { ApiAuthenticationError } from "../error.js";
|
|
3
3
|
|
|
4
4
|
import type ApiClient from "../ApiClient.js";
|
|
5
|
-
import type { PersonRegisterData, AuthenticateUrlData, RefreshTokenUrlData, PasswordRecoveryData, ServerExchangeTokenData, ChangePasswordData, DeleteAccountData, UpdateSettingsData, UpdateBlockDescriptionData, UpdateBlockInfoData, UpdateBlockSocialData, UpdateBlockLocalityData, UpdateBlockSlugData, CheckData, ProfilImageData, ProfilBannerData, GetElementsAboutData, MulticonnectData, GetNewsData, GetNewsByIdData, AddNewsData, AddImageNewsData, AddFileNewsData, DeleteNewsData, UpdateNewsData, ShareNewsData, GetCommentsData, AddCommentsData, DeleteCommentsData, UpdateCommentsData, SearchTagsData, ShowVoteData, GlobalAutocompleteData, CityAutocompleteData, CityAutocompleteByCountryData, SuggestionInputData, GetProjectsNoAdminData, GetProjectsAdminData, GetPoisNoAdminData, GetPoisAdminData, GetOrganizationsNoAdminData, GetOrganizationsAdminData, GetMembersNoAdminData, GetMembersAdminData, GetFriendsAdminData, GetSubscriptionsData, GetSubscriptionsAdminData, GetSubscribersData, GetSubscribersAdminData, GetContributorsNoAdminData, GetContributorsAdminData, GetBadgesData, GetBadgesFiltersData, ConnectData, DisconnectData, GetElementsKeyData, GetFavorisData, DeleteFavorisData, AddFavorisData, AddOrganizationData, AddProjectData, AddPoiData, AddEventData, DeletePoiData, DeleteEventData, DeleteElementData, AddImageElementData, LinkValidateData, SearchMemberAutocompleteData, GetNotificationsData, GetNotificationsCountData, NotificationUpdateData, MarkNotificationAsReadData, ActivitypubSearchData, ActivitypubLinkData, ActivitypubGetCommunityData, GetBadgeData, AddBadgesData, AssignBadgesData, GetEventsData, ShareEventsData, InviteEventData, FollowData, GetCostumJsonData, GlobalAutocompleteCostumData, CostumEventRequestActorsData, CostumEventRequestSubeventsData, CostumEventRequestElementEventData, CostumEventRequestCategoriesData, CostumEventRequestDatesData, CostumEventRequestEventData, CostumEventRequestLinkTlToEventData, CostumEventRequestLoadContextTagData, GetGalleryData, GetAttendeesNoAdminData, GetAttendeesAdminData, CoformAnswersSearchData, CoformAnswersByIdData, AddVoteData, AddReportAbuseData, UpdatePathValueData, DeleteDocumentByContextData } from "./EndpointApi.types.js";
|
|
5
|
+
import type { PersonRegisterData, AuthenticateUrlData, RefreshTokenUrlData, PasswordRecoveryData, ServerExchangeTokenData, ChangePasswordData, DeleteAccountData, UpdateSettingsData, UpdateBlockDescriptionData, UpdateBlockInfoData, UpdateBlockSocialData, UpdateBlockLocalityData, UpdateBlockSlugData, CheckData, ProfilImageData, ProfilBannerData, GetElementsAboutData, MulticonnectData, GetNewsData, GetNewsByIdData, AddNewsData, AddImageNewsData, AddFileNewsData, DeleteNewsData, UpdateNewsData, ShareNewsData, GetCommentsData, AddCommentsData, DeleteCommentsData, UpdateCommentsData, SearchTagsData, ShowVoteData, GlobalAutocompleteData, CityAutocompleteData, CityAutocompleteByCountryData, SuggestionInputData, GetProjectsNoAdminData, GetProjectsAdminData, GetPoisNoAdminData, GetPoisAdminData, GetOrganizationsNoAdminData, GetOrganizationsAdminData, GetMembersNoAdminData, GetMembersAdminData, GetFriendsAdminData, GetSubscriptionsData, GetSubscriptionsAdminData, GetSubscribersData, GetSubscribersAdminData, GetContributorsNoAdminData, GetContributorsAdminData, GetBadgesData, GetBadgesFiltersData, ConnectData, DisconnectData, GetElementsKeyData, GetFavorisData, DeleteFavorisData, AddFavorisData, AddOrganizationData, AddProjectData, AddPoiData, AddEventData, DeletePoiData, DeleteEventData, DeleteElementData, AddImageElementData, LinkValidateData, SearchMemberAutocompleteData, GetNotificationsData, GetNotificationsCountData, NotificationUpdateData, MarkNotificationAsReadData, ActivitypubSearchData, ActivitypubLinkData, ActivitypubGetCommunityData, GetBadgeData, AddBadgesData, AssignBadgesData, GetEventsData, ShareEventsData, InviteEventData, FollowData, GetCostumJsonData, GlobalAutocompleteCostumData, CostumEventRequestActorsData, CostumEventRequestSubeventsData, CostumEventRequestElementEventData, CostumEventRequestCategoriesData, CostumEventRequestDatesData, CostumEventRequestEventData, CostumEventRequestLinkTlToEventData, CostumEventRequestLoadContextTagData, GetGalleryData, GetAttendeesNoAdminData, GetAttendeesAdminData, CoformAnswersSearchData, CoformAnswersByIdData, AddVoteData, AddReportAbuseData, UpdatePathValueData, DeleteDocumentByContextData, DemoteAdminData } from "./EndpointApi.types.js";
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Classe EndpointApi générée automatiquement depuis endpoints-copie.json
|
|
@@ -1704,6 +1704,22 @@ export class EndpointApi {
|
|
|
1704
1704
|
return this.callIsConnected("DELETE_DOCUMENT_BY_CONTEXT", data);
|
|
1705
1705
|
}
|
|
1706
1706
|
|
|
1707
|
+
/**
|
|
1708
|
+
* Rétirer les droits d’administrateur d’un membre : Rétirer les droits d’administrateur d’un membre d’une organisation ou d’un projet
|
|
1709
|
+
* Constant : DEMOTE_ADMIN
|
|
1710
|
+
* @param data - Données envoyées à l'API
|
|
1711
|
+
* @returns Les données de réponse.
|
|
1712
|
+
* @throws {ApiResponseError} - En cas d'erreur détectée dans la réponse.
|
|
1713
|
+
* @throws {ApiAuthenticationError} - En cas d'erreur d'authentification.
|
|
1714
|
+
* @throws {Error} - En cas d'erreur inattendue.
|
|
1715
|
+
*/
|
|
1716
|
+
async demoteAdmin(data: DemoteAdminData): Promise<any> {
|
|
1717
|
+
if (!data || typeof data !== "object") {
|
|
1718
|
+
throw new TypeError("Le paramètre data doit être un objet.");
|
|
1719
|
+
}
|
|
1720
|
+
return this.callIsConnected("DEMOTE_ADMIN", data);
|
|
1721
|
+
}
|
|
1722
|
+
|
|
1707
1723
|
}
|
|
1708
1724
|
|
|
1709
1725
|
export default EndpointApi;
|
|
@@ -4899,3 +4899,17 @@ export interface DeleteDocumentByContextData {
|
|
|
4899
4899
|
};
|
|
4900
4900
|
[k: string]: unknown;
|
|
4901
4901
|
}
|
|
4902
|
+
|
|
4903
|
+
|
|
4904
|
+
export interface DemoteAdminData {
|
|
4905
|
+
parentId: string;
|
|
4906
|
+
/**
|
|
4907
|
+
* Type de contexte de l’entité
|
|
4908
|
+
*/
|
|
4909
|
+
parentType: "organizations" | "projects";
|
|
4910
|
+
childId: string;
|
|
4911
|
+
childType: "citoyens";
|
|
4912
|
+
connect: "members" | "contributors";
|
|
4913
|
+
isAdmin: false;
|
|
4914
|
+
[k: string]: unknown;
|
|
4915
|
+
}
|
package/src/api/User.ts
CHANGED
|
@@ -15,7 +15,8 @@ import type {
|
|
|
15
15
|
GetSubscriptionsData,
|
|
16
16
|
GetOrganizationsNoAdminData,
|
|
17
17
|
GetOrganizationsAdminData,
|
|
18
|
-
GetFriendsAdminData
|
|
18
|
+
GetFriendsAdminData,
|
|
19
|
+
DemoteAdminData
|
|
19
20
|
} from "./EndpointApi.types.js";
|
|
20
21
|
import type { Organization } from "./Organization.js";
|
|
21
22
|
import type { EntityTypes } from "@/types/entities.js";
|
|
@@ -922,16 +923,18 @@ export class User extends BaseEntity<UserItemNormalized> {
|
|
|
922
923
|
}
|
|
923
924
|
}
|
|
924
925
|
|
|
926
|
+
|
|
925
927
|
/**
|
|
926
|
-
* Récupère le lien
|
|
928
|
+
* Récupère le lien parent pour l'utilisateur actuel.
|
|
929
|
+
*
|
|
930
|
+
* @returns Le lien parent de l'utilisateur ou `null` s'il n'existe pas.
|
|
927
931
|
* @private
|
|
928
|
-
* @returns Le lien utilisateur ou null.
|
|
929
932
|
*/
|
|
930
|
-
private
|
|
931
|
-
const {
|
|
932
|
-
const
|
|
933
|
-
if (!
|
|
934
|
-
return this?.serverData?.links?.[
|
|
933
|
+
private _getParentLinkForUser(): any {
|
|
934
|
+
const { connectTypeDisconnect } = this.parent!._getLinkMeta();
|
|
935
|
+
const userId = this!.id;
|
|
936
|
+
if (!userId) return null;
|
|
937
|
+
return this.parent?.serverData?.links?.[connectTypeDisconnect]?.[userId] || null;
|
|
935
938
|
}
|
|
936
939
|
|
|
937
940
|
/**
|
|
@@ -976,8 +979,8 @@ export class User extends BaseEntity<UserItemNormalized> {
|
|
|
976
979
|
*/
|
|
977
980
|
override isAdmin(): boolean {
|
|
978
981
|
this._validateRoleCheckPreconditions("isAdmin", ["organizations", "projects"]);
|
|
979
|
-
const
|
|
980
|
-
return this._validateUserLink(
|
|
982
|
+
const parentLink = this._getParentLinkForUser();
|
|
983
|
+
return this._validateUserLink(parentLink) && parentLink?.isAdmin === true;
|
|
981
984
|
}
|
|
982
985
|
|
|
983
986
|
/**
|
|
@@ -1007,8 +1010,8 @@ export class User extends BaseEntity<UserItemNormalized> {
|
|
|
1007
1010
|
*/
|
|
1008
1011
|
override isMember(): boolean {
|
|
1009
1012
|
this._validateRoleCheckPreconditions("isMember", ["organizations"]);
|
|
1010
|
-
const
|
|
1011
|
-
return this._validateUserLink(
|
|
1013
|
+
const parentLink = this._getParentLinkForUser();
|
|
1014
|
+
return this._validateUserLink(parentLink);
|
|
1012
1015
|
}
|
|
1013
1016
|
|
|
1014
1017
|
/**
|
|
@@ -1038,8 +1041,8 @@ export class User extends BaseEntity<UserItemNormalized> {
|
|
|
1038
1041
|
*/
|
|
1039
1042
|
override isContributor(): boolean {
|
|
1040
1043
|
this._validateRoleCheckPreconditions("isContributor", ["projects"]);
|
|
1041
|
-
const
|
|
1042
|
-
return this._validateUserLink(
|
|
1044
|
+
const parentLink = this._getParentLinkForUser();
|
|
1045
|
+
return this._validateUserLink(parentLink);
|
|
1043
1046
|
}
|
|
1044
1047
|
|
|
1045
1048
|
/**
|
|
@@ -1069,8 +1072,483 @@ export class User extends BaseEntity<UserItemNormalized> {
|
|
|
1069
1072
|
*/
|
|
1070
1073
|
override isAttendee(): boolean {
|
|
1071
1074
|
this._validateRoleCheckPreconditions("isAttendee", ["events"]);
|
|
1072
|
-
const
|
|
1073
|
-
return this._validateUserLink(
|
|
1075
|
+
const parentLink = this._getParentLinkForUser();
|
|
1076
|
+
return this._validateUserLink(parentLink);
|
|
1077
|
+
}
|
|
1078
|
+
|
|
1079
|
+
/**
|
|
1080
|
+
* Vérifie si l'utilisateur a une invitation en attente d'acceptation pour l'entité parente.
|
|
1081
|
+
*
|
|
1082
|
+
* Cette méthode vérifie si l'utilisateur a été invité à rejoindre l'organisation, le projet
|
|
1083
|
+
* ou l'événement parent, mais n'a pas encore accepté l'invitation (`isInviting: true`).
|
|
1084
|
+
*
|
|
1085
|
+
* @returns {boolean} `true` si l'utilisateur a une invitation en attente, `false` sinon
|
|
1086
|
+
* @throws {ApiError} Si l'utilisateur n'est pas connecté, pas admin du parent, ou si le parent n'est pas défini
|
|
1087
|
+
*
|
|
1088
|
+
* @example
|
|
1089
|
+
* ```typescript
|
|
1090
|
+
* const org = await me.organization({ slug: "myOrg" });
|
|
1091
|
+
* const members = await org.getMembers();
|
|
1092
|
+
* const invitedUser = members.results.find(m => m.isInviting());
|
|
1093
|
+
* console.log("Invitation en attente:", invitedUser?.data.name);
|
|
1094
|
+
* ```
|
|
1095
|
+
*/
|
|
1096
|
+
isInviting(): boolean {
|
|
1097
|
+
this._validateRoleCheckPreconditions("isInviting", ["organizations", "projects", "events"]);
|
|
1098
|
+
const parentLink = this._getParentLinkForUser();
|
|
1099
|
+
if (!parentLink) return false;
|
|
1100
|
+
return parentLink?.isInviting === true;
|
|
1101
|
+
}
|
|
1102
|
+
|
|
1103
|
+
/**
|
|
1104
|
+
* Vérifie si l'utilisateur a une invitation en attente avec des droits d'admin.
|
|
1105
|
+
*
|
|
1106
|
+
* Cette méthode vérifie si l'utilisateur a été invité à rejoindre l'organisation ou le projet
|
|
1107
|
+
* parent en tant qu'administrateur, mais n'a pas encore accepté (`isInviting: true` et `isAdmin: true`).
|
|
1108
|
+
*
|
|
1109
|
+
* @returns {boolean} `true` si l'utilisateur a une invitation admin en attente, `false` sinon
|
|
1110
|
+
* @throws {ApiError} Si l'utilisateur n'est pas connecté, pas admin du parent, ou si le parent n'est pas défini
|
|
1111
|
+
*
|
|
1112
|
+
* @example
|
|
1113
|
+
* ```typescript
|
|
1114
|
+
* const org = await me.organization({ slug: "myOrg" });
|
|
1115
|
+
* const members = await org.getMembers();
|
|
1116
|
+
* const invitedAdmin = members.results.find(m => m.isInvitingAdmin());
|
|
1117
|
+
* console.log("Invitation admin en attente:", invitedAdmin?.data.name);
|
|
1118
|
+
* ```
|
|
1119
|
+
*/
|
|
1120
|
+
isInvitingAdmin(): boolean {
|
|
1121
|
+
this._validateRoleCheckPreconditions("isInvitingAdmin", ["organizations", "projects"]);
|
|
1122
|
+
const parentLink = this._getParentLinkForUser();
|
|
1123
|
+
if (!parentLink) return false;
|
|
1124
|
+
return parentLink?.isAdminInviting === true && parentLink?.isAdmin === true;
|
|
1125
|
+
}
|
|
1126
|
+
|
|
1127
|
+
/**
|
|
1128
|
+
* Vérifie si l'utilisateur a une demande de promotion admin en attente de validation.
|
|
1129
|
+
*
|
|
1130
|
+
* Cette méthode vérifie si l'utilisateur a demandé ou a été proposé pour devenir administrateur
|
|
1131
|
+
* de l'organisation ou du projet parent, mais la demande n'a pas encore été validée (`isAdminPending: true`).
|
|
1132
|
+
*
|
|
1133
|
+
* @returns {boolean} `true` si l'utilisateur a une demande admin en attente, `false` sinon
|
|
1134
|
+
* @throws {ApiError} Si l'utilisateur n'est pas connecté, pas admin du parent, ou si le parent n'est pas défini
|
|
1135
|
+
*
|
|
1136
|
+
* @example
|
|
1137
|
+
* ```typescript
|
|
1138
|
+
* const org = await me.organization({ slug: "myOrg" });
|
|
1139
|
+
* const members = await org.getMembers();
|
|
1140
|
+
* const pendingAdmin = members.results.find(m => m.isAdminPending());
|
|
1141
|
+
* if (pendingAdmin) {
|
|
1142
|
+
* await pendingAdmin.validateAdminRequest();
|
|
1143
|
+
* }
|
|
1144
|
+
* ```
|
|
1145
|
+
*/
|
|
1146
|
+
isAdminPending(): boolean {
|
|
1147
|
+
this._validateRoleCheckPreconditions("isAdminPending", ["organizations", "projects"]);
|
|
1148
|
+
const parentLink = this._getParentLinkForUser();
|
|
1149
|
+
return parentLink?.isAdmin === true && parentLink?.isAdminPending === true;
|
|
1150
|
+
}
|
|
1151
|
+
|
|
1152
|
+
/**
|
|
1153
|
+
* Vérifie si l'utilisateur a une demande d'adhésion en attente de validation.
|
|
1154
|
+
*
|
|
1155
|
+
* Cette méthode vérifie si l'utilisateur a demandé à rejoindre l'organisation, le projet
|
|
1156
|
+
* ou l'événement parent, mais la demande n'a pas encore été validée par un administrateur (`toBeValidated: true`).
|
|
1157
|
+
*
|
|
1158
|
+
* @returns {boolean} `true` si l'utilisateur a une demande en attente, `false` sinon
|
|
1159
|
+
* @throws {ApiError} Si l'utilisateur n'est pas connecté, pas admin du parent, ou si le parent n'est pas défini
|
|
1160
|
+
*
|
|
1161
|
+
* @example
|
|
1162
|
+
* ```typescript
|
|
1163
|
+
* const org = await me.organization({ slug: "myOrg" });
|
|
1164
|
+
* const members = await org.getMembers();
|
|
1165
|
+
* const pendingUser = members.results.find(m => m.isToBeValidated());
|
|
1166
|
+
* if (pendingUser) {
|
|
1167
|
+
* await pendingUser.validateMemberRequest();
|
|
1168
|
+
* }
|
|
1169
|
+
* ```
|
|
1170
|
+
*/
|
|
1171
|
+
isToBeValidated(): boolean {
|
|
1172
|
+
this._validateRoleCheckPreconditions("isToBeValidated", ["organizations", "projects", "events"]);
|
|
1173
|
+
const parentLink = this._getParentLinkForUser();
|
|
1174
|
+
return parentLink?.toBeValidated === true;
|
|
1175
|
+
}
|
|
1176
|
+
|
|
1177
|
+
|
|
1178
|
+
// ────────────────────────────────
|
|
1179
|
+
// Actions d'admin sur l'utilisateur par rapport à l'entité parente
|
|
1180
|
+
// ────────────────────────────────
|
|
1181
|
+
|
|
1182
|
+
/**
|
|
1183
|
+
* Envoie une demande pour rejoindre l'entité parente.
|
|
1184
|
+
*
|
|
1185
|
+
* Cette méthode permet à un admin de créer une demande de connexion pour un utilisateur
|
|
1186
|
+
* vers l'organisation ou le projet parent. Si l'utilisateur n'a pas encore de lien,
|
|
1187
|
+
* une demande de connexion est créée.
|
|
1188
|
+
*
|
|
1189
|
+
* @returns {Promise<unknown>} La réponse de l'API après création de la demande
|
|
1190
|
+
* @throws {ApiError} Si l'utilisateur n'est pas connecté, pas admin, ou si le parent n'est pas défini
|
|
1191
|
+
* @throws {ApiError} Si l'utilisateur est déjà en attente de validation
|
|
1192
|
+
* @throws {ApiError} Si l'utilisateur est déjà connecté à l'entité
|
|
1193
|
+
*
|
|
1194
|
+
* @example
|
|
1195
|
+
* ```typescript
|
|
1196
|
+
* // Un admin récupère les membres et envoie une invitation
|
|
1197
|
+
* const org = await me.organization({ slug: "myOrg" });
|
|
1198
|
+
* const users = await org.getMembers();
|
|
1199
|
+
* const user = users.results[0];
|
|
1200
|
+
* await user.sendRequestToJoinParent();
|
|
1201
|
+
* ```
|
|
1202
|
+
*/
|
|
1203
|
+
async sendRequestToJoinParent(): Promise<unknown> {
|
|
1204
|
+
this._validateRoleCheckPreconditions("sendRequestToJoinParent", ["organizations", "projects"]);
|
|
1205
|
+
|
|
1206
|
+
const { connectTypeConnect } = this.parent!._getLinkMeta();
|
|
1207
|
+
|
|
1208
|
+
const parentLink = this._getParentLinkForUser();
|
|
1209
|
+
|
|
1210
|
+
// Cas : aucun lien → on demande à se connecter
|
|
1211
|
+
if (!parentLink) {
|
|
1212
|
+
|
|
1213
|
+
const t = this.parent!.getEntityType();
|
|
1214
|
+
|
|
1215
|
+
// 2) Narrow de type pour TypeScript
|
|
1216
|
+
const parentType = t as ConnectData["parentType"];
|
|
1217
|
+
|
|
1218
|
+
const data: ConnectData = {
|
|
1219
|
+
childId: this.id!,
|
|
1220
|
+
childType: "citoyens",
|
|
1221
|
+
parentType,
|
|
1222
|
+
parentId: this.parent!.id!,
|
|
1223
|
+
connectType: connectTypeConnect
|
|
1224
|
+
};
|
|
1225
|
+
|
|
1226
|
+
const retour = await this.callIsConnected(() => this.endpointApi.connect(data));
|
|
1227
|
+
// Refresh l'utilisateur membre et l'entité parente
|
|
1228
|
+
await this.refresh();
|
|
1229
|
+
if (this.parent) {
|
|
1230
|
+
await this.parent.refresh();
|
|
1231
|
+
}
|
|
1232
|
+
return retour;
|
|
1233
|
+
}
|
|
1234
|
+
|
|
1235
|
+
// Cas : déjà en attente
|
|
1236
|
+
if (parentLink.toBeValidated) {
|
|
1237
|
+
throw new ApiError("Vous êtes déjà en attente de validation.", 400);
|
|
1238
|
+
}
|
|
1239
|
+
|
|
1240
|
+
// Cas par défaut : rien à faire
|
|
1241
|
+
throw new ApiError("Vous êtes déjà connecté à cette entité.", 400);
|
|
1242
|
+
}
|
|
1243
|
+
|
|
1244
|
+
/**
|
|
1245
|
+
* Valide une demande de membre en attente de validation.
|
|
1246
|
+
*
|
|
1247
|
+
* Cette méthode permet à un admin de valider une demande d'adhésion d'un utilisateur
|
|
1248
|
+
* qui est en attente (`toBeValidated: true`). Après validation, l'utilisateur devient
|
|
1249
|
+
* membre actif de l'entité parente.
|
|
1250
|
+
*
|
|
1251
|
+
* @returns {Promise<unknown>} La réponse de l'API après validation
|
|
1252
|
+
* @throws {ApiError} Si l'utilisateur n'est pas connecté, pas admin, ou si le parent n'est pas défini
|
|
1253
|
+
* @throws {ApiError} Si l'utilisateur n'a pas de demande en attente
|
|
1254
|
+
*
|
|
1255
|
+
* @example
|
|
1256
|
+
* ```typescript
|
|
1257
|
+
* // Un admin valide une demande en attente
|
|
1258
|
+
* const org = await me.organization({ slug: "myOrg" });
|
|
1259
|
+
* const members = await org.getMembers();
|
|
1260
|
+
* const pendingUser = members.results.find(u => u.serverData.links?.memberOf?.[org.id]?.toBeValidated);
|
|
1261
|
+
* await pendingUser.validateMemberRequest();
|
|
1262
|
+
* ```
|
|
1263
|
+
*/
|
|
1264
|
+
async validateMemberRequest(): Promise<unknown> {
|
|
1265
|
+
this._validateRoleCheckPreconditions("validateMemberRequest", ["organizations", "projects"]);
|
|
1266
|
+
|
|
1267
|
+
const parentLink = this._getParentLinkForUser();
|
|
1268
|
+
|
|
1269
|
+
if (!parentLink?.toBeValidated) {
|
|
1270
|
+
throw new ApiError("Cet utilisateur n'a pas de demande en attente de validation.", 400);
|
|
1271
|
+
}
|
|
1272
|
+
|
|
1273
|
+
const t = this.parent!.getEntityType();
|
|
1274
|
+
|
|
1275
|
+
const parentType = t as LinkValidateData["parentType"];
|
|
1276
|
+
|
|
1277
|
+
const data: LinkValidateData = {
|
|
1278
|
+
childId: this.id!,
|
|
1279
|
+
childType: "citoyens",
|
|
1280
|
+
parentType,
|
|
1281
|
+
parentId: this.parent!.id!,
|
|
1282
|
+
linkOption: "toBeValidated"
|
|
1283
|
+
};
|
|
1284
|
+
|
|
1285
|
+
const retour = await this.callIsConnected(() => this.endpointApi.linkValidate(data));
|
|
1286
|
+
// Refresh l'utilisateur membre et l'entité parente
|
|
1287
|
+
await this.refresh();
|
|
1288
|
+
if (this.parent) {
|
|
1289
|
+
await this.parent.refresh();
|
|
1290
|
+
}
|
|
1291
|
+
return retour;
|
|
1292
|
+
}
|
|
1293
|
+
|
|
1294
|
+
/**
|
|
1295
|
+
* Valide une invitation en attente d'acceptation.
|
|
1296
|
+
*
|
|
1297
|
+
* Cette méthode permet à un admin de valider une invitation envoyée à un utilisateur
|
|
1298
|
+
* qui est en attente (`isInviting: true`). Après validation, l'utilisateur devient
|
|
1299
|
+
* membre actif de l'entité parente.
|
|
1300
|
+
*
|
|
1301
|
+
* @returns {Promise<unknown>} La réponse de l'API après validation
|
|
1302
|
+
* @throws {ApiError} Si l'utilisateur n'est pas connecté, pas admin, ou si le parent n'est pas défini
|
|
1303
|
+
* @throws {ApiError} Si l'utilisateur n'a pas d'invitation en attente
|
|
1304
|
+
*
|
|
1305
|
+
* @example
|
|
1306
|
+
* ```typescript
|
|
1307
|
+
* // Un admin valide une invitation en attente
|
|
1308
|
+
* const org = await me.organization({ slug: "myOrg" });
|
|
1309
|
+
* const members = await org.getMembers();
|
|
1310
|
+
* const invitedUser = members.results.find(u => u.serverData.links?.memberOf?.[org.id]?.isInviting);
|
|
1311
|
+
* await invitedUser.validateInvitation();
|
|
1312
|
+
* ```
|
|
1313
|
+
*/
|
|
1314
|
+
// async validateInvitation(): Promise<unknown> {
|
|
1315
|
+
// this._validateRoleCheckPreconditions("validateInvitation", ["organizations", "projects"]);
|
|
1316
|
+
|
|
1317
|
+
// const parentLink = this._getParentLinkForUser();
|
|
1318
|
+
|
|
1319
|
+
// if (!parentLink?.isInviting) {
|
|
1320
|
+
// throw new ApiError("Cet utilisateur n'a pas d'invitation en attente.", 400);
|
|
1321
|
+
// }
|
|
1322
|
+
|
|
1323
|
+
// const t = this.parent!.getEntityType();
|
|
1324
|
+
|
|
1325
|
+
// const parentType = t as LinkValidateData["parentType"];
|
|
1326
|
+
|
|
1327
|
+
// const data: LinkValidateData = {
|
|
1328
|
+
// childId: this.id!,
|
|
1329
|
+
// childType: "citoyens",
|
|
1330
|
+
// parentType,
|
|
1331
|
+
// parentId: this.parent!.id!,
|
|
1332
|
+
// linkOption: "isInviting"
|
|
1333
|
+
// };
|
|
1334
|
+
|
|
1335
|
+
// const retour = await this.callIsConnected(() => this.endpointApi.linkValidate(data));
|
|
1336
|
+
// // Refresh l'utilisateur membre et l'entité parente
|
|
1337
|
+
// await this.refresh();
|
|
1338
|
+
// if (this.parent) {
|
|
1339
|
+
// await this.parent.refresh();
|
|
1340
|
+
// }
|
|
1341
|
+
// return retour;
|
|
1342
|
+
// }
|
|
1343
|
+
|
|
1344
|
+
/**
|
|
1345
|
+
* Valide une demande d'admin en attente.
|
|
1346
|
+
*
|
|
1347
|
+
* Cette méthode permet à un admin de valider une demande de promotion au statut d'admin
|
|
1348
|
+
* pour un utilisateur qui est en attente (`isAdminPending: true`). Après validation,
|
|
1349
|
+
* l'utilisateur devient admin de l'entité parente.
|
|
1350
|
+
*
|
|
1351
|
+
* @returns {Promise<unknown>} La réponse de l'API après validation
|
|
1352
|
+
* @throws {ApiError} Si l'utilisateur n'est pas connecté, pas admin, ou si le parent n'est pas défini
|
|
1353
|
+
* @throws {ApiError} Si l'utilisateur n'a pas de demande d'admin en attente
|
|
1354
|
+
*
|
|
1355
|
+
* @example
|
|
1356
|
+
* ```typescript
|
|
1357
|
+
* // Un admin valide une demande de promotion à admin
|
|
1358
|
+
* const org = await me.organization({ slug: "myOrg" });
|
|
1359
|
+
* const members = await org.getMembers();
|
|
1360
|
+
* const pendingAdmin = members.results.find(u => u.serverData.links?.memberOf?.[org.id]?.isAdminPending);
|
|
1361
|
+
* await pendingAdmin.validateAdminRequest();
|
|
1362
|
+
* ```
|
|
1363
|
+
*/
|
|
1364
|
+
async validateAdminRequest(): Promise<unknown> {
|
|
1365
|
+
this._validateRoleCheckPreconditions("validateAdminRequest", ["organizations", "projects"]);
|
|
1366
|
+
|
|
1367
|
+
const parentLink = this._getParentLinkForUser();
|
|
1368
|
+
|
|
1369
|
+
if (!parentLink?.isAdminPending) {
|
|
1370
|
+
throw new ApiError("Cet utilisateur n'a pas de demande d'admin en attente.", 400);
|
|
1371
|
+
}
|
|
1372
|
+
|
|
1373
|
+
const t = this.parent!.getEntityType();
|
|
1374
|
+
|
|
1375
|
+
const parentType = t as LinkValidateData["parentType"];
|
|
1376
|
+
|
|
1377
|
+
const data: LinkValidateData = {
|
|
1378
|
+
childId: this.id!,
|
|
1379
|
+
childType: "citoyens",
|
|
1380
|
+
parentType,
|
|
1381
|
+
parentId: this.parent!.id!,
|
|
1382
|
+
linkOption: "isAdminPending"
|
|
1383
|
+
};
|
|
1384
|
+
|
|
1385
|
+
const retour = await this.callIsConnected(() => this.endpointApi.linkValidate(data));
|
|
1386
|
+
// Refresh l'utilisateur membre et l'entité parente
|
|
1387
|
+
await this.refresh();
|
|
1388
|
+
if (this.parent) {
|
|
1389
|
+
await this.parent.refresh();
|
|
1390
|
+
}
|
|
1391
|
+
return retour;
|
|
1392
|
+
}
|
|
1393
|
+
|
|
1394
|
+
/**
|
|
1395
|
+
* Retire un utilisateur de l'entité parente.
|
|
1396
|
+
*
|
|
1397
|
+
* Cette méthode permet à un admin de déconnecter un membre de l'organisation ou du projet parent.
|
|
1398
|
+
* L'utilisateur perd tous ses liens avec l'entité (membre, admin, etc.).
|
|
1399
|
+
*
|
|
1400
|
+
* @returns {Promise<unknown>} La réponse de l'API après déconnexion
|
|
1401
|
+
* @throws {ApiError} Si l'utilisateur n'est pas connecté, pas admin, ou si le parent n'est pas défini
|
|
1402
|
+
* @throws {ApiError} Si l'utilisateur n'est pas membre de l'entité
|
|
1403
|
+
*
|
|
1404
|
+
* @example
|
|
1405
|
+
* ```typescript
|
|
1406
|
+
* // Un admin retire un membre
|
|
1407
|
+
* const org = await me.organization({ slug: "myOrg" });
|
|
1408
|
+
* const members = await org.getMembers();
|
|
1409
|
+
* const userToRemove = members.results[0];
|
|
1410
|
+
* await userToRemove.removeFromParent();
|
|
1411
|
+
* ```
|
|
1412
|
+
*/
|
|
1413
|
+
async removeFromParent(): Promise<unknown> {
|
|
1414
|
+
this._validateRoleCheckPreconditions("removeFromParent", ["organizations", "projects"]);
|
|
1415
|
+
|
|
1416
|
+
const parentLink = this._getParentLinkForUser();
|
|
1417
|
+
|
|
1418
|
+
if (!parentLink) {
|
|
1419
|
+
throw new ApiError("Cet utilisateur n'est pas connecté à cette entité.", 400);
|
|
1420
|
+
}
|
|
1421
|
+
|
|
1422
|
+
const t = this.parent!.getEntityType();
|
|
1423
|
+
|
|
1424
|
+
const parentType = t as DisconnectData["parentType"];
|
|
1425
|
+
|
|
1426
|
+
const { connectTypeDisconnect } = this.parent!._getLinkMeta();
|
|
1427
|
+
|
|
1428
|
+
const data: DisconnectData = {
|
|
1429
|
+
childId: this.id!,
|
|
1430
|
+
childType: "citoyens",
|
|
1431
|
+
parentType,
|
|
1432
|
+
parentId: this.parent!.id!,
|
|
1433
|
+
connectType: connectTypeDisconnect
|
|
1434
|
+
};
|
|
1435
|
+
|
|
1436
|
+
const retour = await this.callIsConnected(() => this.endpointApi.disconnect(data));
|
|
1437
|
+
// Refresh l'utilisateur membre et l'entité parente
|
|
1438
|
+
await this.refresh();
|
|
1439
|
+
if (this.parent) {
|
|
1440
|
+
await this.parent.refresh();
|
|
1441
|
+
}
|
|
1442
|
+
return retour;
|
|
1443
|
+
}
|
|
1444
|
+
|
|
1445
|
+
/**
|
|
1446
|
+
* Promeut un utilisateur au statut d'admin de l'entité parente.
|
|
1447
|
+
*
|
|
1448
|
+
* Cette méthode permet à un admin de promouvoir un membre ordinaire au statut d'admin
|
|
1449
|
+
* de l'organisation ou du projet parent.
|
|
1450
|
+
*
|
|
1451
|
+
* @returns {Promise<unknown>} La réponse de l'API après promotion
|
|
1452
|
+
* @throws {ApiError} Si l'utilisateur n'est pas connecté, pas admin, ou si le parent n'est pas défini
|
|
1453
|
+
* @throws {ApiError} Si l'utilisateur n'est pas membre de l'entité
|
|
1454
|
+
* @throws {ApiError} Si l'utilisateur est déjà admin
|
|
1455
|
+
*
|
|
1456
|
+
* @example
|
|
1457
|
+
* ```typescript
|
|
1458
|
+
* // Un admin promeut un membre au statut d'admin
|
|
1459
|
+
* const org = await me.organization({ slug: "myOrg" });
|
|
1460
|
+
* const members = await org.getMembers();
|
|
1461
|
+
* const userToPromote = members.results.find(u => !u.isAdmin());
|
|
1462
|
+
* await userToPromote.promoteToAdmin();
|
|
1463
|
+
* ```
|
|
1464
|
+
*/
|
|
1465
|
+
async promoteToAdmin(): Promise<unknown> {
|
|
1466
|
+
this._validateRoleCheckPreconditions("promoteToAdmin", ["organizations", "projects"]);
|
|
1467
|
+
|
|
1468
|
+
const parentLink = this._getParentLinkForUser();
|
|
1469
|
+
|
|
1470
|
+
if (!parentLink) {
|
|
1471
|
+
throw new ApiError("Cet utilisateur n'est pas membre de cette entité.", 400);
|
|
1472
|
+
}
|
|
1473
|
+
|
|
1474
|
+
if (parentLink.isAdmin && !parentLink.isAdminPending) {
|
|
1475
|
+
throw new ApiError("Cet utilisateur est déjà admin.", 400);
|
|
1476
|
+
}
|
|
1477
|
+
|
|
1478
|
+
const t = this.parent!.getEntityType();
|
|
1479
|
+
|
|
1480
|
+
const parentType = t as ConnectData["parentType"];
|
|
1481
|
+
|
|
1482
|
+
const data: ConnectData = {
|
|
1483
|
+
childId: this.id!,
|
|
1484
|
+
childType: "citoyens",
|
|
1485
|
+
parentType,
|
|
1486
|
+
parentId: this.parent!.id!,
|
|
1487
|
+
connectType: "admin"
|
|
1488
|
+
};
|
|
1489
|
+
|
|
1490
|
+
const retour = await this.callIsConnected(() => this.endpointApi.connect(data));
|
|
1491
|
+
// Refresh l'utilisateur membre et l'entité parente
|
|
1492
|
+
await this.refresh();
|
|
1493
|
+
if (this.parent) {
|
|
1494
|
+
await this.parent.refresh();
|
|
1495
|
+
}
|
|
1496
|
+
return retour;
|
|
1497
|
+
}
|
|
1498
|
+
|
|
1499
|
+
/**
|
|
1500
|
+
* Rétrograde un admin au statut de membre ordinaire.
|
|
1501
|
+
*
|
|
1502
|
+
* Cette méthode permet à un admin de rétrograder un autre admin au statut de membre
|
|
1503
|
+
* ordinaire de l'organisation ou du projet parent. L'utilisateur perd ses privilèges d'admin
|
|
1504
|
+
* mais reste membre de l'entité.
|
|
1505
|
+
*
|
|
1506
|
+
* @returns {Promise<unknown>} La réponse de l'API après rétrogradation
|
|
1507
|
+
* @throws {ApiError} Si l'utilisateur n'est pas connecté, pas admin, ou si le parent n'est pas défini
|
|
1508
|
+
* @throws {ApiError} Si l'utilisateur n'est pas admin de l'entité
|
|
1509
|
+
*
|
|
1510
|
+
* @example
|
|
1511
|
+
* ```typescript
|
|
1512
|
+
* // Un admin rétrograde un autre admin
|
|
1513
|
+
* const org = await me.organization({ slug: "myOrg" });
|
|
1514
|
+
* const admins = await org.getMembers({}, { isAdmin: true });
|
|
1515
|
+
* const adminToDemote = admins.results.find(u => u.isAdmin());
|
|
1516
|
+
* await adminToDemote.demoteFromAdmin();
|
|
1517
|
+
* ```
|
|
1518
|
+
*/
|
|
1519
|
+
async demoteFromAdmin(): Promise<unknown> {
|
|
1520
|
+
this._validateRoleCheckPreconditions("demoteFromAdmin", ["organizations", "projects"]);
|
|
1521
|
+
|
|
1522
|
+
const parentLink = this._getParentLinkForUser();
|
|
1523
|
+
|
|
1524
|
+
if (!parentLink?.isAdmin || parentLink.isAdminPending) {
|
|
1525
|
+
throw new ApiError("Cet utilisateur n'est pas admin de cette entité.", 400);
|
|
1526
|
+
}
|
|
1527
|
+
|
|
1528
|
+
const t = this.parent!.getEntityType();
|
|
1529
|
+
|
|
1530
|
+
const { connectTypeDisconnect } = this.parent!._getLinkMeta();
|
|
1531
|
+
|
|
1532
|
+
const parentType = t as DemoteAdminData["parentType"];
|
|
1533
|
+
|
|
1534
|
+
// Pour rétrograder un admin, on déconnecte le lien "admin"
|
|
1535
|
+
// L'utilisateur garde son lien "member"
|
|
1536
|
+
const data: DemoteAdminData = {
|
|
1537
|
+
childId: this.id!,
|
|
1538
|
+
childType: "citoyens",
|
|
1539
|
+
parentType,
|
|
1540
|
+
parentId: this.parent!.id!,
|
|
1541
|
+
connect: connectTypeDisconnect as DemoteAdminData["connect"],
|
|
1542
|
+
isAdmin: false
|
|
1543
|
+
};
|
|
1544
|
+
|
|
1545
|
+
const retour = await this.callIsConnected(() => this.endpointApi.demoteAdmin(data));
|
|
1546
|
+
// Refresh l'utilisateur membre et l'entité parente
|
|
1547
|
+
await this.refresh();
|
|
1548
|
+
if (this.parent) {
|
|
1549
|
+
await this.parent.refresh();
|
|
1550
|
+
}
|
|
1551
|
+
return retour;
|
|
1074
1552
|
}
|
|
1075
1553
|
|
|
1076
1554
|
}
|