mirror of
https://github.com/docmost/docmost.git
synced 2026-08-23 18:42:13 +10:00
fix(integration): thread requester identity through unfurl for per-user authorization
This commit is contained in:
@@ -66,8 +66,24 @@ export type UnfurlOpts = {
|
|||||||
match: RegExpMatchArray;
|
match: RegExpMatchArray;
|
||||||
patternType: string;
|
patternType: string;
|
||||||
settings?: Record<string, any>;
|
settings?: Record<string, any>;
|
||||||
|
// The requesting Docmost user and integration. Providers backed by a shared
|
||||||
|
// (workspace) connection MUST authorize the requester against the target
|
||||||
|
// resource before returning content: the shared bot token is not itself
|
||||||
|
// proof that the requester may see it.
|
||||||
|
userId: string;
|
||||||
|
integrationId: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Thrown by a provider's unfurl() when the requesting user is not authorized
|
||||||
|
// to view the linked resource. UnfurlService turns it into a null result
|
||||||
|
// (no card) rather than logging it as an error.
|
||||||
|
export class UnfurlForbiddenError extends Error {
|
||||||
|
constructor(message = 'Not authorized to unfurl this link') {
|
||||||
|
super(message);
|
||||||
|
this.name = 'UnfurlForbiddenError';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export type LinkDescription = {
|
export type LinkDescription = {
|
||||||
title: string;
|
title: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { OAuthService } from '../oauth/oauth.service';
|
|||||||
import {
|
import {
|
||||||
UnfurlResult,
|
UnfurlResult,
|
||||||
UnfurlNeedsConnection,
|
UnfurlNeedsConnection,
|
||||||
|
UnfurlForbiddenError,
|
||||||
IntegrationProvider,
|
IntegrationProvider,
|
||||||
} from '../registry/integration-provider.interface';
|
} from '../registry/integration-provider.interface';
|
||||||
import { RedisService } from '@nestjs-labs/nestjs-ioredis';
|
import { RedisService } from '@nestjs-labs/nestjs-ioredis';
|
||||||
@@ -89,6 +90,8 @@ export class UnfurlService {
|
|||||||
match,
|
match,
|
||||||
patternType,
|
patternType,
|
||||||
settings: (integration.settings as Record<string, any>) ?? {},
|
settings: (integration.settings as Record<string, any>) ?? {},
|
||||||
|
userId,
|
||||||
|
integrationId: integration.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
await this.redis.set(
|
await this.redis.set(
|
||||||
@@ -100,6 +103,11 @@ export class UnfurlService {
|
|||||||
|
|
||||||
return unfurlResult;
|
return unfurlResult;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
// Not-authorized is an expected outcome (no card), not an error.
|
||||||
|
if (err instanceof UnfurlForbiddenError) {
|
||||||
|
this.logger.debug(`Unfurl not authorized for ${url}`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
this.logger.error(`Unfurl failed for ${url}: ${(err as Error).message}`);
|
this.logger.error(`Unfurl failed for ${url}: ${(err as Error).message}`);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user