feat: Security
This commit is contained in:
@@ -30,6 +30,8 @@ import {
|
||||
type PluginClientApiMethodPath
|
||||
} from '../../domain/logic/plugin-client-api-surface.rules';
|
||||
import { PluginCapabilityError, PluginCapabilityService } from './plugin-capability.service';
|
||||
import { MessageRevisionService } from '../../../chat/application/services/message-revision.service';
|
||||
import { MessageSigningService } from '../../../authentication/application/services/message-signing.service';
|
||||
import { PluginClientApiService } from './plugin-client-api.service';
|
||||
import { PluginDesktopStateService } from './plugin-desktop-state.service';
|
||||
import { PluginLoggerService } from './plugin-logger.service';
|
||||
@@ -106,17 +108,31 @@ describe('PluginClientApiService', () => {
|
||||
}));
|
||||
});
|
||||
|
||||
it('sends plugin messages and broadcasts them to peers', () => {
|
||||
it('sends plugin messages and broadcasts them to peers', async () => {
|
||||
const api = context.service.createApi(TEST_MANIFEST);
|
||||
const message = api.messages.send('hello plugin');
|
||||
|
||||
expect(message.content).toBe('hello plugin');
|
||||
expect(message.roomId).toBe('room-1');
|
||||
expect(context.store.dispatch).toHaveBeenCalledWith(MessagesActions.sendMessageSuccess({ message }));
|
||||
|
||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||
|
||||
expect(context.store.dispatch).toHaveBeenCalledWith(
|
||||
MessagesActions.sendMessageSuccess({
|
||||
message: expect.objectContaining({
|
||||
content: 'hello plugin',
|
||||
roomId: 'room-1'
|
||||
})
|
||||
})
|
||||
);
|
||||
expect(context.voice.broadcastMessage).toHaveBeenCalledWith(expect.objectContaining({
|
||||
type: 'chat-message',
|
||||
message
|
||||
message: expect.objectContaining({
|
||||
content: 'hello plugin',
|
||||
roomId: 'room-1'
|
||||
})
|
||||
}));
|
||||
expect(context.messageRevisions.broadcastRevision).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('publishes typing state through the realtime facade', () => {
|
||||
@@ -264,6 +280,11 @@ interface ServiceTestContext {
|
||||
setLocalStream: ReturnType<typeof vi.fn>;
|
||||
setOutputVolume: ReturnType<typeof vi.fn>;
|
||||
};
|
||||
messageRevisions: {
|
||||
broadcastRevision: ReturnType<typeof vi.fn>;
|
||||
createSignedRevision: ReturnType<typeof vi.fn>;
|
||||
persistRevision: ReturnType<typeof vi.fn>;
|
||||
};
|
||||
}
|
||||
|
||||
function createServiceTestContext(): ServiceTestContext {
|
||||
@@ -305,6 +326,28 @@ function createServiceTestContext(): ServiceTestContext {
|
||||
setLocalStream: vi.fn(async () => undefined),
|
||||
setOutputVolume: vi.fn()
|
||||
};
|
||||
const messageRevisions = {
|
||||
createSignedRevision: vi.fn(async (input: Parameters<MessageRevisionService['createSignedRevision']>[0]) => ({
|
||||
messageId: input.message.id,
|
||||
revision: input.type === 'create' ? 0 : (input.message.revision ?? 0) + 1,
|
||||
prevRevisionHash: input.type === 'create' ? '' : (input.message.headHash ?? ''),
|
||||
headHash: 'test-head-hash',
|
||||
type: input.type,
|
||||
actorId: input.actorId,
|
||||
senderId: input.message.senderId,
|
||||
roomId: input.message.roomId,
|
||||
channelId: input.message.channelId,
|
||||
senderName: input.message.senderName,
|
||||
content: input.content ?? input.message.content,
|
||||
editedAt: input.editedAt,
|
||||
isDeleted: input.isDeleted ?? false,
|
||||
replyToId: input.message.replyToId,
|
||||
pluginId: input.pluginId,
|
||||
signature: input.sign === false ? undefined : 'test-signature'
|
||||
})),
|
||||
persistRevision: vi.fn(async () => undefined),
|
||||
broadcastRevision: vi.fn()
|
||||
};
|
||||
const realtime = {
|
||||
onSignalingMessage: new Subject<unknown>(),
|
||||
sendRawMessage: vi.fn()
|
||||
@@ -357,11 +400,24 @@ function createServiceTestContext(): ServiceTestContext {
|
||||
{
|
||||
provide: DatabaseService,
|
||||
useValue: {
|
||||
getMessageById: vi.fn(async () => null),
|
||||
saveMessage: vi.fn(async () => undefined),
|
||||
updateMessage: vi.fn(async () => undefined),
|
||||
updateRoom: vi.fn(async () => undefined)
|
||||
}
|
||||
},
|
||||
{
|
||||
provide: MessageRevisionService,
|
||||
useValue: messageRevisions
|
||||
},
|
||||
{
|
||||
provide: MessageSigningService,
|
||||
useValue: {
|
||||
signRevision: vi.fn(async () => 'test-signature'),
|
||||
fetchSigningPublicKey: vi.fn(async () => null),
|
||||
verifyRevisionSignature: vi.fn(async () => true)
|
||||
}
|
||||
},
|
||||
{
|
||||
provide: PluginDesktopStateService,
|
||||
useValue: {
|
||||
@@ -426,7 +482,8 @@ function createServiceTestContext(): ServiceTestContext {
|
||||
storage,
|
||||
store,
|
||||
uiRegistry,
|
||||
voice
|
||||
voice,
|
||||
messageRevisions
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user