=> {
- // const actor = req.actor;
- // if (!actor?.user) throw new HttpError(401, 'Unauthorized');
-
- // const body = req.body ?? {};
- // let recipients = body.recipients;
- // let shares = body.shares;
- // const dryRun = !!body.dry_run;
-
- // if (!recipients) throw new HttpError(400, 'Missing `recipients`');
- // if (!shares) throw new HttpError(400, 'Missing `shares`');
- // if (!Array.isArray(recipients)) recipients = [recipients];
- // if (!Array.isArray(shares)) shares = [shares];
-
- // // Build the permissions list from share declarations.
- // const permissions = this.#resolvePermissions(shares as unknown[]);
-
- // const recipientResults: unknown[] = [];
-
- // for (const recipient of recipients as unknown[]) {
- // const recipientStr =
- // typeof recipient === 'string' ? recipient.trim() : '';
- // if (!recipientStr) {
- // recipientResults.push({
- // $: 'error',
- // message: 'empty recipient',
- // });
- // continue;
- // }
-
- // try {
- // // Try username first
- // const targetUser =
- // (await this.stores.user.getByUsername(recipientStr)) ??
- // (recipientStr.includes('@')
- // ? await this.stores.user.getByEmail(recipientStr)
- // : null);
-
- // if (targetUser) {
- // // Direct grant — user exists
- // if (!dryRun) {
- // for (const perm of permissions) {
- // try {
- // await this.services.permission.grantUserUserPermission(
- // actor,
- // targetUser.username ?? '',
- // perm.permission,
- // perm.extra ?? {},
- // );
- // } catch (err) {
- // console.warn(
- // '[share] grant to user failed',
- // perm.permission,
- // err,
- // );
- // }
- // }
-
- // // Notify
- // if (this.services.notification) {
- // await this.services.notification.notify(
- // [targetUser.id],
- // {
- // source: 'sharing',
- // title: `${actor.user.username} shared items with you`,
- // template: 'file-shared-with-you',
- // fields: {
- // username: actor.user.username,
- // permissions: permissions.map(
- // (p) => p.permission,
- // ),
- // },
- // },
- // );
- // }
- // }
- // recipientResults.push({
- // $: 'api:status-report',
- // status: 'success',
- // });
- // } else if (recipientStr.includes('@')) {
- // // Email recipient — store pending share
- // if (!dryRun) {
- // const share = await this.stores.share.create({
- // issuerUserId: actor.user.id,
- // recipientEmail: recipientStr.toLowerCase(),
- // data: {
- // permissions,
- // metadata: body.metadata ?? {},
- // },
- // });
-
- // // Sign a share token (14-day expiry)
- // const token = this.services.token.sign(
- // SHARE_TOKEN_TYPE,
- // {
- // type: `token:${SHARE_TOKEN_TYPE}`,
- // uid: share.uid,
- // },
- // { expiresIn: SHARE_TOKEN_EXPIRY },
- // );
-
- // // Email the share link
- // const origin = `https://${this.config.domain ?? 'puter.com'}`;
- // try {
- // await this.clients.email.sendRaw({
- // to: recipientStr,
- // subject: `${actor.user.username} shared something with you on Puter`,
- // html: `${actor.user.username} shared items with you.
Click here to accept
`,
- // });
- // } catch (err) {
- // console.warn('[share] email send failed', err);
- // }
- // }
- // recipientResults.push({
- // $: 'api:status-report',
- // status: 'success',
- // });
- // } else {
- // recipientResults.push({
- // $: 'error',
- // message: 'User not found',
- // });
- // }
- // } catch (err) {
- // recipientResults.push({ $: 'error', message: String(err) });
- // }
- // }
-
- // const allOk = recipientResults.every(
- // (r: unknown) => (r as Record).status === 'success',
- // );
- // const anyOk = recipientResults.some(
- // (r: unknown) => (r as Record).status === 'success',
- // );
-
- // res.json({
- // $: 'api:share',
- // $version: 'v0.0.0',
- // status: allOk ? 'success' : anyOk ? 'mixed' : 'aborted',
- // recipients: recipientResults,
- // ...(dryRun ? { dry_run: true } : {}),
- // });
- // };
-
- // // -- Helpers ------------------------------------------------------
-
- // /**
- // * Convert share declarations into a flat permission list.
- // * Supports `fs-share` ({ path, access }) and `app-share` ({ uid, name }).
- // */
- // #resolvePermissions(
- // shares: unknown[],
- // ): Array<{ permission: string; extra?: Record }> {
- // const perms: Array<{
- // permission: string;
- // extra?: Record;
- // }> = [];
-
- // for (const share of shares) {
- // if (!share || typeof share !== 'object') continue;
- // const s = share as Record;
-
- // if (s.$ === 'fs-share' || s.type === 'fs-share' || s.path) {
- // const path = String(s.path ?? '');
- // const access = String(s.access ?? 'read');
- // if (path) {
- // perms.push({ permission: `fs:${path}:${access}` });
- // }
- // } else if (
- // s.$ === 'app-share' ||
- // s.type === 'app-share' ||
- // s.uid ||
- // s.name
- // ) {
- // const appUid = String(s.uid ?? s.name ?? '');
- // if (appUid) {
- // perms.push({ permission: `app:uid#${appUid}:access` });
- // }
- // }
- // }
-
- // return perms;
- // }
+ void (async () => {
+ try {
+ for (const [label, count] of byRecipient) {
+ const user = label.includes('@')
+ ? await this.stores.user.getByEmail(label)
+ : await this.stores.user.getByUsername(label);
+ if (!user) continue;
+ await this.services.notification.notify([user.id], {
+ source: 'sharing',
+ title: `${actor.user.username} shared ${count === 1 ? 'an item' : `${count} items`} with you`,
+ template: 'file-shared-with-you',
+ fields: { username: actor.user.username, count },
+ });
+ }
+ } catch {
+ // Never fail a completed share over its notification.
+ }
+ })();
+ }
}