diff --git a/plugins/calendar-assets/lang/cs.json b/plugins/calendar-assets/lang/cs.json index 4bc8c8ab26..56247a9f2f 100644 --- a/plugins/calendar-assets/lang/cs.json +++ b/plugins/calendar-assets/lang/cs.json @@ -100,10 +100,11 @@ "MeetingDuration": "Trvání schůzky", "MeetingInterval": "Pauza mezi schůzkami", "CalDavAccess": "Přístup CalDAV", - "CalDavAccessPrompt": "Protokol CalDAV umožňuje synchronizaci vašeho osobního kalendáře Huly s externími aplikacemi kalendáře. Vyberte účet a použijte navrhované heslo pro registraci serveru Huly CalDAV v klientské aplikaci kalendáře.", + "CalDavAccessPrompt": "Protokol CalDAV umožňuje synchronizaci vašeho osobního kalendáře Huly s externími kalendářovými aplikacemi. Použijte tento účet a navrhované heslo pro registraci serveru Huly CalDAV v aplikaci kalendářového klienta.", "CalDavAccessEnable": "Povolte přístup CalDAV k osobnímu kalendáři v pracovním prostoru {ws}", "CalDavAccessServer": "Server CalDAV", "CalDavAccessAccount": "Účet Huly", - "CalDavAccessPassword": "Heslo (automaticky vygenerované)" + "CalDavAccessPassword": "Heslo", + "CalDavAccessPasswordWarning": "Tohle heslo už nebudete moci znovu vidět. Uložte si ho na bezpečné místo." } } \ No newline at end of file diff --git a/plugins/calendar-assets/lang/de.json b/plugins/calendar-assets/lang/de.json index b0402dd889..7842d121d6 100644 --- a/plugins/calendar-assets/lang/de.json +++ b/plugins/calendar-assets/lang/de.json @@ -100,10 +100,11 @@ "MeetingDuration": "Meetingdauer", "MeetingInterval": "Pause zwischen Meetings", "CalDavAccess": "CalDAV-Zugriff", - "CalDavAccessPrompt": "Das CalDAV-Protokoll ermöglicht die Synchronisierung Ihres persönlichen Huly-Kalenders mit externen Kalenderanwendungen. Wählen Sie ein Konto aus und verwenden Sie das vorgeschlagene Passwort für die Registrierung des Huly-CalDAV-Servers in einer Kalender-Client-Anwendung.", + "CalDavAccessPrompt": "Das CalDAV-Protokoll ermöglicht die Synchronisierung Ihres persönlichen Huly-Kalenders mit externen Kalenderanwendungen. Verwenden Sie dieses Konto und das vorgeschlagene Passwort, um den Huly CalDAV-Server in einer Kalender-Client-Anwendung zu registrieren.", "CalDavAccessEnable": "CalDAV-Zugriff auf den persönlichen Kalender im Arbeitsbereich {ws} aktivieren", "CalDavAccessServer": "CalDAV-Server", "CalDavAccessAccount": "Huly-Konto", - "CalDavAccessPassword": "Passwort (automatisch generiert)" + "CalDavAccessPassword": "Passwort", + "CalDavAccessPasswordWarning": "Sie können dieses Passwort nicht erneut anzeigen. Bitte speichern Sie es an einem sicheren Ort." } } \ No newline at end of file diff --git a/plugins/calendar-assets/lang/en.json b/plugins/calendar-assets/lang/en.json index 37e4c9ae70..b4d154402f 100644 --- a/plugins/calendar-assets/lang/en.json +++ b/plugins/calendar-assets/lang/en.json @@ -100,10 +100,11 @@ "MeetingDuration": "Meeting duration", "MeetingInterval": "Pause between meetings", "CalDavAccess": "CalDAV access", - "CalDavAccessPrompt": "CalDAV protocol allows for syncing your personal Huly calendar with external calendar applications. Select an account and use the suggested password for registering the Huly CalDAV server in a calendar client application.", + "CalDavAccessPrompt": "CalDAV protocol allows for syncing your personal Huly calendar with external calendar applications. Use this account and the suggested password for registering the Huly CalDAV server in a calendar client application.", "CalDavAccessEnable": "Enable CalDAV access to the personal calendar in workspace {ws}", "CalDavAccessServer": "CalDAV server", "CalDavAccessAccount": "Huly account", - "CalDavAccessPassword": "Password (auto-generated)" + "CalDavAccessPassword": "Password", + "CalDavAccessPasswordWarning": "You will not be able to see this password again. Please save it in a secure place." } } diff --git a/plugins/calendar-assets/lang/es.json b/plugins/calendar-assets/lang/es.json index 66235ca31a..c1bc944a59 100644 --- a/plugins/calendar-assets/lang/es.json +++ b/plugins/calendar-assets/lang/es.json @@ -100,10 +100,11 @@ "MeetingDuration": "Duración de la reunión", "MeetingInterval": "Pausa entre reuniones", "CalDavAccess": "Acceso a CalDAV", - "CalDavAccessPrompt": "El protocolo CalDAV permite sincronizar su calendario personal de Huly con aplicaciones de calendario externas. Seleccione una cuenta y use la contraseña sugerida para registrar el servidor CalDAV de Huly en una aplicación cliente de calendario.", + "CalDavAccessPrompt": "El protocolo CalDAV permite sincronizar su calendario personal de Huly con aplicaciones de calendario externas. Utilice esta cuenta y la contraseña sugerida para registrar el servidor CalDAV de Huly en una aplicación cliente de calendario.", "CalDavAccessEnable": "Habilite el acceso CalDAV al calendario personal en el espacio de trabajo {ws}", "CalDavAccessServer": "Servidor CalDAV", "CalDavAccessAccount": "Cuenta de Huly", - "CalDavAccessPassword": "Contraseña (autogenerada)" + "CalDavAccessPassword": "Contraseña", + "CalDavAccessPasswordWarning": "No podrá ver esta contraseña nuevamente. Guárdela en un lugar seguro." } } \ No newline at end of file diff --git a/plugins/calendar-assets/lang/fr.json b/plugins/calendar-assets/lang/fr.json index baed206550..979b5ce701 100644 --- a/plugins/calendar-assets/lang/fr.json +++ b/plugins/calendar-assets/lang/fr.json @@ -100,10 +100,11 @@ "MeetingDuration": "Durée de la réunion", "MeetingInterval": "Pause entre les réunions", "CalDavAccess": "Accès CalDAV", - "CalDavAccessPrompt": "Le protocole CalDAV permet de synchroniser votre calendrier personnel Huly avec des applications de calendrier externes. Sélectionnez un compte et utilisez le mot de passe suggéré pour enregistrer le serveur CalDAV Huly dans une application cliente de calendrier.", + "CalDavAccessPrompt": "Le protocole CalDAV permet de synchroniser votre calendrier personnel Huly avec des applications de calendrier externes. Utilisez ce compte et le mot de passe suggéré pour enregistrer le serveur CalDAV Huly dans une application cliente de calendrier.", "CalDavAccessEnable": "Activer l'accès CalDAV au calendrier personnel dans l'espace de travail {ws}", "CalDavAccessServer": "Serveur CalDAV", "CalDavAccessAccount": "Compte Huly", - "CalDavAccessPassword": "Mot de passe (généré automatiquement)" + "CalDavAccessPassword": "Mot de passe", + "CalDavAccessPasswordWarning": "Vous ne pourrez plus voir ce mot de passe. Veuillez le conserver dans un endroit sûr." } } \ No newline at end of file diff --git a/plugins/calendar-assets/lang/it.json b/plugins/calendar-assets/lang/it.json index 8c8698f238..abf5dc4ccb 100644 --- a/plugins/calendar-assets/lang/it.json +++ b/plugins/calendar-assets/lang/it.json @@ -100,10 +100,11 @@ "MeetingDuration": "Durata riunione", "MeetingInterval": "Pausa tra riunioni", "CalDavAccess": "Accesso CalDAV", - "CalDavAccessPrompt": "Il protocollo CalDAV consente la sincronizzazione del calendario personale Huly con applicazioni di calendario esterne. Seleziona un account e utilizza la password suggerita per registrare il server CalDAV Huly in un'applicazione client di calendario.", + "CalDavAccessPrompt": "Il protocollo CalDAV consente la sincronizzazione del calendario personale Huly con applicazioni di calendario esterne. Utilizza questo account e la password suggerita per registrare il server CalDAV Huly in un'applicazione client di calendario.", "CalDavAccessEnable": "Abilita l'accesso CalDAV al calendario personale nell'area di lavoro {ws}", "CalDavAccessServer": "Server CalDAV", "CalDavAccessAccount": "Account Huly", - "CalDavAccessPassword": "Password (generata automaticamente)" + "CalDavAccessPassword": "Password", + "CalDavAccessPasswordWarning": "Non potrai vedere di nuovo questa password. Conservala in un luogo sicuro." } } diff --git a/plugins/calendar-assets/lang/pt.json b/plugins/calendar-assets/lang/pt.json index a2303f4bcd..55f6394284 100644 --- a/plugins/calendar-assets/lang/pt.json +++ b/plugins/calendar-assets/lang/pt.json @@ -100,10 +100,11 @@ "MeetingDuration": "Duração da reunião", "MeetingInterval": "Pausa entre reuniões", "CalDavAccess": "CalDAV Access", - "CalDavAccessPrompt": "O protocolo CalDAV permite sincronizar o seu calendário pessoal Huly com aplicações de calendário externas. Selecione uma conta e utilize a palavra-passe sugerida para registar o servidor Huly CalDAV numa aplicação cliente de calendário.", + "CalDavAccessPrompt": "O protocolo CalDAV permite sincronizar o seu calendário pessoal Huly com aplicações de calendário externas. Utilize esta conta e a palavra-passe sugerida para registar o servidor Huly CalDAV numa aplicação cliente de calendário.", "CalDavAccessEnable": "Ativar o acesso CalDAV ao calendário pessoal no espaço de trabalho {ws}", "CalDavAccessServer": "Servidor CalDAV", "CalDavAccessAccount": "Conta Huly", - "CalDavAccessPassword": "Password (gerada automaticamente)" + "CalDavAccessPassword": "Password", + "CalDavAccessPasswordWarning": "Não será possível ver esta palavra-passe novamente. Guarde-a num local seguro." } } \ No newline at end of file diff --git a/plugins/calendar-assets/lang/ru.json b/plugins/calendar-assets/lang/ru.json index 6a2d40b6e0..6fbf5f7b74 100644 --- a/plugins/calendar-assets/lang/ru.json +++ b/plugins/calendar-assets/lang/ru.json @@ -100,10 +100,11 @@ "MeetingDuration": "Длительность встречи", "MeetingInterval": "Перерыв между встречами", "CalDavAccess": "Доступ через CalDAV", - "CalDavAccessPrompt": "Протокол CalDAV позволяет синхронизировать ваш личный календарь в Huly со сторонними приложениями. Выберите учетную запись и используйте предложенный пароль для регистрации сервера Huly CalDAV в календарном приложении.", + "CalDavAccessPrompt": "Протокол CalDAV позволяет синхронизировать ваш личный календарь Huly с внешними приложениями календаря. Используйте эту учетную запись и предложенный пароль для регистрации сервера Huly CalDAV в клиентском приложении календаря.", "CalDavAccessEnable": "Разрешить доступ к личному календарю в пространстве {ws} через CalDAV", "CalDavAccessServer": "Сервер CalDAV", "CalDavAccessAccount": "Учетная запись Huly", - "CalDavAccessPassword": "Пароль (автоматический)" + "CalDavAccessPassword": "Пароль", + "CalDavAccessPasswordWarning": "Вы не сможете увидеть этот пароль снова. Пожалуйста, сохраните его в безопасном месте." } } diff --git a/plugins/calendar-assets/lang/zh.json b/plugins/calendar-assets/lang/zh.json index fb5a4150d5..89ce74e1ff 100644 --- a/plugins/calendar-assets/lang/zh.json +++ b/plugins/calendar-assets/lang/zh.json @@ -100,10 +100,11 @@ "MeetingDuration": "会议时长", "MeetingInterval": "会议间暂停", "CalDavAccess": "CalDAV 访问", - "CalDavAccessPrompt": "CalDAV 协议允许将您的个人 Huly 日历与外部日历应用同步。请选择一个帐户并使用建议的密码在日历客户端应用中注册 Huly CalDav 服务器。", + "CalDavAccessPrompt": "CalDAV 協定允許將您的個人 Huly 日曆與外部日曆應用程式同步。使用此帳戶和建議的密碼在日曆用戶端應用程式中註冊 Huly CalDAV 伺服器。", "CalDavAccessEnable": "在工作区 {ws} 中启用 CalDAV 对个人日历的访问", "CalDavAccessServer": "CalDAV 服务器", "CalDavAccessAccount": "Huly 帐户", - "CalDavAccessPassword": "密码(自动生成)" + "CalDavAccessPassword": "密码", + "CalDavAccessPasswordWarning": "您将无法再次看到此密码。请将其保存在安全的地方。" } } \ No newline at end of file diff --git a/plugins/calendar-resources/src/components/CalDavAccess.svelte b/plugins/calendar-resources/src/components/CalDavAccess.svelte index 72dc60d5b8..c7a4552d3a 100644 --- a/plugins/calendar-resources/src/components/CalDavAccess.svelte +++ b/plugins/calendar-resources/src/components/CalDavAccess.svelte @@ -1,25 +1,16 @@ @@ -267,19 +209,7 @@
+ {/if} {#if error}
{error}
diff --git a/plugins/calendar-resources/src/components/EditEvent.svelte b/plugins/calendar-resources/src/components/EditEvent.svelte index cb6585b41d..33b499fe27 100644 --- a/plugins/calendar-resources/src/components/EditEvent.svelte +++ b/plugins/calendar-resources/src/components/EditEvent.svelte @@ -214,9 +214,6 @@ readonly={readOnly} placeholder={calendar.string.Description} bind:content={description} - on:changeSize={(e) => { - console.log('ChangeSize', e) - }} />
diff --git a/plugins/calendar/src/index.ts b/plugins/calendar/src/index.ts index bb836199e7..a45dc65b77 100644 --- a/plugins/calendar/src/index.ts +++ b/plugins/calendar/src/index.ts @@ -246,7 +246,7 @@ const calendarPlugin = plugin(calendarId, { CalDavAccessServer: '' as IntlString, CalDavAccessAccount: '' as IntlString, CalDavAccessPassword: '' as IntlString, - CopyValue: '' as IntlString + CalDavAccessPasswordWarning: '' as IntlString }, handler: { DisconnectHandler: '' as Handler diff --git a/plugins/presence-resources/src/store.ts b/plugins/presence-resources/src/store.ts index 430966a573..af6c4b00d4 100644 --- a/plugins/presence-resources/src/store.ts +++ b/plugins/presence-resources/src/store.ts @@ -133,7 +133,6 @@ export function followeeDataUnsubscribe (topic: string, handler: (data: any) => } export function toggleFollowee (person: Ref | undefined): void { - console.log('toggle followee', person) followee.update((p) => (p === person ? undefined : person)) const f = get(followee) @@ -150,7 +149,6 @@ export function toggleFollowee (person: Ref | undefined): void { } } } else { - console.log('no followee') for (const handlers of followeeDataHandlers.values()) { for (const handler of handlers) { handler(undefined) diff --git a/server/account/src/__tests__/serviceOperations.test.ts b/server/account/src/__tests__/serviceOperations.test.ts index 9e1ba3e221..71a405c0d2 100644 --- a/server/account/src/__tests__/serviceOperations.test.ts +++ b/server/account/src/__tests__/serviceOperations.test.ts @@ -1248,7 +1248,6 @@ describe('integration methods', () => { }) describe('getIntegrationSecret', () => { - const mockAccount = 'test-account' const mockSocialId = 'test-social-id' as PersonId const mockSecretKey: IntegrationSecretKey = { socialId: mockSocialId, @@ -1267,56 +1266,11 @@ describe('integration methods', () => { extra: { service: 'github' } }) ;(mockDb.integrationSecret.findOne as jest.Mock).mockResolvedValue(mockSecret) - ;(mockDb.socialId.findOne as jest.Mock).mockResolvedValue({ _id: mockSocialId }) - ;(mockDb.workspace.findOne as jest.Mock).mockResolvedValue({ uuid: 'test-workspace' }) - ;(mockDb.integration.findOne as jest.Mock).mockResolvedValue({}) const result = await getIntegrationSecret(mockCtx, mockDb, mockBranding, mockToken, mockSecretKey) expect(result).toEqual(mockSecret) expect(mockDb.integrationSecret.findOne).toHaveBeenCalledWith(mockSecretKey) - expect(mockDb.socialId.findOne).toHaveBeenCalledWith({ _id: mockSocialId, verifiedOn: { $gt: 0 } }) - }) - - test('should allow verified user to get their secret', async () => { - ;(decodeTokenVerbose as jest.Mock).mockReturnValue({ - account: mockAccount - }) - ;(mockDb.integrationSecret.findOne as jest.Mock).mockResolvedValue(mockSecret) - ;(mockDb.socialId.findOne as jest.Mock).mockResolvedValue({ _id: mockSocialId }) - ;(mockDb.workspace.findOne as jest.Mock).mockResolvedValue({ uuid: 'test-workspace' }) - ;(mockDb.integration.findOne as jest.Mock).mockResolvedValue({}) - - const result = await getIntegrationSecret(mockCtx, mockDb, mockBranding, mockToken, mockSecretKey) - - expect(result).toEqual(mockSecret) - expect(mockDb.integrationSecret.findOne).toHaveBeenCalledWith(mockSecretKey) - expect(mockDb.socialId.findOne).toHaveBeenCalledWith({ - _id: mockSocialId, - personUuid: mockAccount, - verifiedOn: { $gt: 0 } - }) - }) - - test('should throw error when user gets secret for different account', async () => { - ;(decodeTokenVerbose as jest.Mock).mockReturnValue({ - account: mockAccount - }) - ;(mockDb.integrationSecret.findOne as jest.Mock).mockResolvedValue(mockSecret) - ;(mockDb.socialId.findOne as jest.Mock).mockResolvedValue(null) - ;(mockDb.workspace.findOne as jest.Mock).mockResolvedValue({ uuid: 'test-workspace' }) - ;(mockDb.integration.findOne as jest.Mock).mockResolvedValue({}) - - await expect(getIntegrationSecret(mockCtx, mockDb, mockBranding, mockToken, mockSecretKey)).rejects.toThrow( - new PlatformError(new Status(Severity.ERROR, platform.status.Forbidden, {})) - ) - - expect(mockDb.integrationSecret.findOne).not.toHaveBeenCalledWith() - expect(mockDb.socialId.findOne).toHaveBeenCalledWith({ - _id: mockSocialId, - personUuid: mockAccount, - verifiedOn: { $gt: 0 } - }) }) test('should return null when integration secret not found', async () => { diff --git a/server/account/src/operations.ts b/server/account/src/operations.ts index 8aa98f4213..a9e84f1c18 100644 --- a/server/account/src/operations.ts +++ b/server/account/src/operations.ts @@ -1187,9 +1187,10 @@ export async function getWorkspacesInfo ( db: AccountDB, branding: Branding | null, token: string, - ids: WorkspaceUuid[] + params: { ids: WorkspaceUuid[] } ): Promise { const { account } = decodeTokenVerbose(ctx, token) + const { ids } = params if (account !== systemAccountUuid) { ctx.error('getWorkspaceInfos with wrong user', { account, token }) diff --git a/server/account/src/serviceOperations.ts b/server/account/src/serviceOperations.ts index b13b815f91..ad7ad308af 100644 --- a/server/account/src/serviceOperations.ts +++ b/server/account/src/serviceOperations.ts @@ -701,12 +701,16 @@ export async function addIntegrationSecret ( params: IntegrationSecret ): Promise { const { extra, account } = decodeTokenVerbose(ctx, token) + const { socialId, kind, workspaceUuid, key, secret } = params + if (kind == null || socialId == null || workspaceUuid === undefined || key == null) { + throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {})) + } + const existingIntegration = await findExistingIntegration(account, db, params, extra) if (existingIntegration == null) { throw new PlatformError(new Status(Severity.ERROR, platform.status.IntegrationNotFound, {})) } - const { socialId, kind, workspaceUuid, key, secret } = params const secretKey: IntegrationSecretKey = { socialId, kind, workspaceUuid, key } const existingSecret = await db.integrationSecret.findOne(secretKey) if (existingSecret != null) { @@ -724,12 +728,16 @@ export async function updateIntegrationSecret ( params: IntegrationSecret ): Promise { const { extra, account } = decodeTokenVerbose(ctx, token) + const { socialId, kind, workspaceUuid, key, secret } = params + if (kind == null || socialId == null || workspaceUuid === undefined || key == null) { + throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {})) + } + const existingIntegration = await findExistingIntegration(account, db, params, extra) if (existingIntegration == null) { throw new PlatformError(new Status(Severity.ERROR, platform.status.IntegrationNotFound, {})) } - const { socialId, kind, workspaceUuid, key, secret } = params const secretKey: IntegrationSecretKey = { socialId, kind, workspaceUuid, key } const existingSecret = await db.integrationSecret.findOne(secretKey) if (existingSecret == null) { @@ -747,12 +755,16 @@ export async function deleteIntegrationSecret ( params: IntegrationSecretKey ): Promise { const { extra, account } = decodeTokenVerbose(ctx, token) + const { socialId, kind, workspaceUuid, key } = params + if (kind == null || socialId == null || workspaceUuid === undefined || key == null) { + throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {})) + } + const existingIntegration = await findExistingIntegration(account, db, params, extra) if (existingIntegration == null) { throw new PlatformError(new Status(Severity.ERROR, platform.status.IntegrationNotFound, {})) } - const { socialId, kind, workspaceUuid, key } = params const secretKey: IntegrationSecretKey = { socialId, kind, workspaceUuid, key } const existingSecret = await db.integrationSecret.findOne(secretKey) if (existingSecret == null) { @@ -769,13 +781,13 @@ export async function getIntegrationSecret ( token: string, params: IntegrationSecretKey ): Promise { - const { extra, account } = decodeTokenVerbose(ctx, token) - const existingIntegration = await findExistingIntegration(account, db, params, extra) - if (existingIntegration == null) { - return null - } - + const { extra } = decodeTokenVerbose(ctx, token) + verifyAllowedServices(integrationServices, extra) const { socialId, kind, workspaceUuid, key } = params + + if (kind == null || socialId == null || workspaceUuid === undefined || key == null) { + throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {})) + } const existing = await db.integrationSecret.findOne({ socialId, kind, workspaceUuid, key }) return existing @@ -788,20 +800,10 @@ export async function listIntegrationsSecrets ( token: string, params: Partial ): Promise { - const { extra, account } = decodeTokenVerbose(ctx, token) + const { extra } = decodeTokenVerbose(ctx, token) + verifyAllowedServices(integrationServices, extra) const { socialId, kind, workspaceUuid, key } = params - if (!verifyAllowedServices(integrationServices, extra, false)) { - if (socialId != null) { - const existingSocialId = await db.socialId.findOne({ _id: socialId, personUuid: account, verifiedOn: { $gt: 0 } }) - if (existingSocialId == null) { - throw new PlatformError(new Status(Severity.ERROR, platform.status.Forbidden, {})) - } - } else { - throw new PlatformError(new Status(Severity.ERROR, platform.status.Forbidden, {})) - } - } - return await db.integrationSecret.find({ socialId, kind, workspaceUuid, key }) } diff --git a/server/account/src/utils.ts b/server/account/src/utils.ts index 35332ed0d9..5f79395b96 100644 --- a/server/account/src/utils.ts +++ b/server/account/src/utils.ts @@ -1439,7 +1439,7 @@ export async function setTimezoneIfNotDefined ( } // Move to config? -export const integrationServices = ['github', 'telegram-bot', 'telegram', 'mailbox'] +export const integrationServices = ['github', 'telegram-bot', 'telegram', 'mailbox', 'caldav'] export async function findExistingIntegration ( account: AccountUuid,