e17398d86d
- Ajoute la configuration et les services backend (app, actors, registration, attendees, contacts, catalog, core auth/nodeinfo/proxy/notification). - Corrige le démarrage : désactive resourcesWithContainerPath pour éviter le conflit entre l'URI de l'acteur applicatif (/as/actor/app) et la route /app. - Corrige l'URL du dépôt de shapes : https://shapes.activitypods.org/. - Ajoute backend/Dockerfile et docker-compose.yml racine (frontend + backend). - Met à jour .env.example racine avec les variables SEMAPPS_* et VITE_BACKEND_*. - Gates verts : bunx tsc --noEmit (0 erreur) et bun test (50 pass).
98 lines
2.8 KiB
JavaScript
98 lines
2.8 KiB
JavaScript
const { ACTIVITY_TYPES, OBJECT_TYPES } = require('@semapps/activitypub');
|
|
const { PodActivitiesHandlerMixin } = require('@activitypods/app');
|
|
const { arrayOf } = require('@semapps/ldp');
|
|
|
|
module.exports = {
|
|
name: 'registration',
|
|
mixins: [PodActivitiesHandlerMixin],
|
|
async started() {
|
|
this.logger.info('Registration watcher subscribed');
|
|
},
|
|
activities: {
|
|
join: {
|
|
match: {
|
|
type: ACTIVITY_TYPES.JOIN,
|
|
object: {
|
|
type: OBJECT_TYPES.EVENT
|
|
}
|
|
},
|
|
async onEmit(ctx, activity, actorUri) {
|
|
const event = activity.object;
|
|
const organizerUri = event['dc:creator'];
|
|
if (!organizerUri) return;
|
|
|
|
const { body: actor } = await ctx.call('pod-resources.get', { resourceUri: actorUri, actorUri });
|
|
if (!actor || !actor['apods:contacts']) return;
|
|
|
|
const contactsGroupUri = await ctx.call('pod-wac-groups.getUriFromCollectionUri', {
|
|
collectionUri: actor['apods:contacts']
|
|
});
|
|
|
|
await ctx.call('pod-wac-groups.addMember', {
|
|
groupUri: contactsGroupUri,
|
|
memberUri: organizerUri,
|
|
actorUri
|
|
});
|
|
},
|
|
async onReceive(ctx, activity, actorUri) {
|
|
const event = activity.object;
|
|
const attendeesCollectionUri = event['apods:attendees'];
|
|
|
|
if (!attendeesCollectionUri) {
|
|
this.logger.warn(`No attendees collection on ${event.id}, skipping Join`);
|
|
return;
|
|
}
|
|
|
|
const attendees = await ctx.call('pod-collections.getItems', {
|
|
collectionUri: attendeesCollectionUri,
|
|
actorUri
|
|
});
|
|
|
|
if (arrayOf(attendees).includes(activity.actor)) {
|
|
this.logger.info(`${activity.actor} is already attending ${event.id}`);
|
|
return;
|
|
}
|
|
|
|
await ctx.call('attendees.add', {
|
|
collectionUri: attendeesCollectionUri,
|
|
itemUri: activity.actor,
|
|
actorUri
|
|
});
|
|
}
|
|
},
|
|
leave: {
|
|
match: {
|
|
type: ACTIVITY_TYPES.LEAVE,
|
|
object: {
|
|
type: OBJECT_TYPES.EVENT
|
|
}
|
|
},
|
|
async onReceive(ctx, activity, actorUri) {
|
|
const event = activity.object;
|
|
const attendeesCollectionUri = event['apods:attendees'];
|
|
|
|
if (!attendeesCollectionUri) {
|
|
this.logger.warn(`No attendees collection on ${event.id}, skipping Leave`);
|
|
return;
|
|
}
|
|
|
|
const attendees = await ctx.call('pod-collections.getItems', {
|
|
collectionUri: attendeesCollectionUri,
|
|
actorUri
|
|
});
|
|
|
|
if (!arrayOf(attendees).includes(activity.actor)) {
|
|
this.logger.info(`${activity.actor} is not attending ${event.id}, skipping Leave`);
|
|
return;
|
|
}
|
|
|
|
await ctx.call('attendees.remove', {
|
|
collectionUri: attendeesCollectionUri,
|
|
itemUri: activity.actor,
|
|
actorUri
|
|
});
|
|
}
|
|
}
|
|
}
|
|
};
|