diff --git a/CHANGELOG.md b/CHANGELOG.md index 4fc3001a0..fc8afa6b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,9 +13,10 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and ### Fixed -- A member of a group a secret is shared with can now change it for everyone it is shared with, as the owner and write-grade members can. Their change only reached their own copy, so the owner and the other recipients kept the old value. Membership is checked at every save, so a member who left the group can't save for everyone, even when their copy was not removed. A use-only group share doesn't give this right, and a recipient of a direct share still changes only their own copy until they join such a group; then the right comes at once, with nothing to approve, and the owner is told unless the recipient can change it for everyone as a delegate or through a team folder they can write in. A member's sync through `PUT /api/v1/secrets/{id}/sync` needs a base version and every copy once, may not clear a copy's key and is checked again just before it writes, as a share-save is; otherwise it answers 409, or 403 when the source is a read-only copy from another organisation. (#1285) +- A member of a group a secret is shared with can now change it for everyone it is shared with, as the owner and write-grade members can. Their change only reached their own copy, so the owner and the other recipients kept the old value. Membership is checked at every save, so a member who left the group can't save for everyone, even when their copy was not removed. A use-only group share doesn't give this right, and a recipient of a direct share can't change it until they join such a group; then the right comes at once, with nothing to approve, and the owner is told unless the recipient can change it for everyone as a delegate or through a team folder they can write in. A member's sync through `PUT /api/v1/secrets/{id}/sync` needs a base version and every copy once, may not clear a copy's key and is checked again just before it writes, as a share-save is; otherwise it answers 409, or 403 when the source is a read-only copy from another organisation. (#1285) - A save by a delegate, a team-folder writer or a group member through their copy now keeps the owner's previous value as a version of the owner's secret, so the owner can restore it. Only the writer's own copy kept a version, and a sync through `/sync` kept none at all. (#1285) - Editing a shared secret in the web app updates the recipients' copies again. The copies were never updated, a write-grade member who changed only the password cleared the login and additional fields on the source, and a failed update showed as saved. A failed save now shows an error and changes nothing. (sharing-atomic-share-save, #1253) +- A recipient who may not write a shared secret can no longer change the value of their own copy, which split that copy from the source and every other copy. A copy shared directly, or through a group whose share is use-only or expired, or held as a team-folder Viewer, is view-only: the web app hides Edit, Restore and "Ask for new values" on it, keeps Save disabled in its edit dialog and says it is shared to view only, while moving, starring, archiving, tagging and deleting it still work. An offline edit of such a copy fails on replay with its values kept to copy or discard. `PUT /api/v1/secrets/{id}` and `POST /api/v1/versions/{id}/restore` refuse a change of the value, login or additional fields of a view-only copy with 428 `view_only`, and a change of only other fields, such as the folder, still saves. `PUT /api/v1/secrets/{id}/sync` refuses a received copy's id with 428 `forbidden`, since a sync starts from the source. Filling a secret request for a view-only copy is refused too; a refused fill, also one for a use-only copy or a read-only copy from another organisation, answers 428 instead of 500, stores nothing and leaves the request pending. (user-sharing, sharing-atomic-share-save, #1287) - A save through `PUT /api/v1/secrets/{id}`, a sync through `PUT /api/v1/secrets/{id}/sync` and a version restore could overwrite a change that landed between their read and their write, such as a share-save from the web app while the browser extension saved. They now read and write in one step, so a change that lands meanwhile is kept in the version history instead of overwritten. A save or sync with a base version answers 409, as do a sync or restore without one; a save without one, filling a secret request for a user's secret and setting an expiry try once more on the current version, and answer 409 only if it moves again. (sharing-atomic-share-save) - A delegate or write-grade member who saves a shared secret through their copy is now recorded in the audit log on the owner's secret too, with the holders that were left out. A restore made through a share-save is recorded as the version the client restored from. (sharing-atomic-share-save) - Revoking a partner share while an update to that partner was still being sent could leave the partner's copy in place: the slower update replaced the pending unshare, so the unshare was never sent. An update now never replaces a pending unshare. (sharing-atomic-share-save) diff --git a/l10n/be.js b/l10n/be.js index 3e5da9e50..b1ee1ba59 100644 --- a/l10n/be.js +++ b/l10n/be.js @@ -4,6 +4,8 @@ OC.L10N.register( "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Гэты сакрэт абагулены з многімі партнёрскімі арганізацыямі, таму захаванне чакае ліміту запытаў і потым працягнецца. Не закрывайце гэта акно.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Занадта шмат запытаў да партнёрскіх арганізацый. Нічога не захавана; паспрабуйце яшчэ раз праз хвіліну.", "This version cannot be restored to this secret. Nothing was saved.": "Гэтую версію нельга аднавіць для гэтага сакрэту. Нічога не захавана.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Абагулена з вамі толькі для прагляду. Каб змяніць, папрасіце ўладальніка даць правы на рэдагаванне.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Абагулена з вамі толькі для прагляду. Нічога не захавана; каб змяніць, папрасіце ўладальніка даць правы на рэдагаванне.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Партнёрская арганізацыя, з якой абагулены гэты сакрэт, недаступная ({partners}). Зрабіце змену яшчэ раз онлайн, дзе можна захаваць без іх.", "Save without them": "Захаваць без іх", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Захавана. Атрымальнікі ў партнёрскіх арганізацыях атрымаюць гэтую змену, калі ўладальнік наступным разам захавае гэты сакрэт.", diff --git a/l10n/be.json b/l10n/be.json index f28ba3323..4173ef788 100644 --- a/l10n/be.json +++ b/l10n/be.json @@ -3,6 +3,8 @@ "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Гэты сакрэт абагулены з многімі партнёрскімі арганізацыямі, таму захаванне чакае ліміту запытаў і потым працягнецца. Не закрывайце гэта акно.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Занадта шмат запытаў да партнёрскіх арганізацый. Нічога не захавана; паспрабуйце яшчэ раз праз хвіліну.", "This version cannot be restored to this secret. Nothing was saved.": "Гэтую версію нельга аднавіць для гэтага сакрэту. Нічога не захавана.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Абагулена з вамі толькі для прагляду. Каб змяніць, папрасіце ўладальніка даць правы на рэдагаванне.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Абагулена з вамі толькі для прагляду. Нічога не захавана; каб змяніць, папрасіце ўладальніка даць правы на рэдагаванне.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Партнёрская арганізацыя, з якой абагулены гэты сакрэт, недаступная ({partners}). Зрабіце змену яшчэ раз онлайн, дзе можна захаваць без іх.", "Save without them": "Захаваць без іх", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Захавана. Атрымальнікі ў партнёрскіх арганізацыях атрымаюць гэтую змену, калі ўладальнік наступным разам захавае гэты сакрэт.", diff --git a/l10n/bg.js b/l10n/bg.js index c66f97fea..05911d3d8 100644 --- a/l10n/bg.js +++ b/l10n/bg.js @@ -4,6 +4,8 @@ OC.L10N.register( "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Тази тайна е споделена с много партньорски организации, затова запазването изчаква лимита на заявките и след това продължава. Не затваряйте този прозорец.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Твърде много заявки към партньорски организации. Нищо не е запазено; опитайте отново след минута.", "This version cannot be restored to this secret. Nothing was saved.": "Тази версия не може да бъде възстановена за тази тайна. Нищо не е запазено.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Споделено с вас само за преглед. Помолете собственика за права за редактиране, за да го промените.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Споделено с вас само за преглед. Нищо не е запазено; помолете собственика за права за редактиране, за да го промените.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Партньорска организация, с която е споделена тази тайна, е недостъпна ({partners}). Направете промяната отново онлайн, където можете да запазите без тях.", "Save without them": "Запазване без тях", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Запазено. Получателите в партньорски организации ще получат тази промяна, когато собственикът запази тази тайна следващия път.", diff --git a/l10n/bg.json b/l10n/bg.json index e7f00b5d5..2ed78c507 100644 --- a/l10n/bg.json +++ b/l10n/bg.json @@ -3,6 +3,8 @@ "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Тази тайна е споделена с много партньорски организации, затова запазването изчаква лимита на заявките и след това продължава. Не затваряйте този прозорец.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Твърде много заявки към партньорски организации. Нищо не е запазено; опитайте отново след минута.", "This version cannot be restored to this secret. Nothing was saved.": "Тази версия не може да бъде възстановена за тази тайна. Нищо не е запазено.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Споделено с вас само за преглед. Помолете собственика за права за редактиране, за да го промените.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Споделено с вас само за преглед. Нищо не е запазено; помолете собственика за права за редактиране, за да го промените.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Партньорска организация, с която е споделена тази тайна, е недостъпна ({partners}). Направете промяната отново онлайн, където можете да запазите без тях.", "Save without them": "Запазване без тях", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Запазено. Получателите в партньорски организации ще получат тази промяна, когато собственикът запази тази тайна следващия път.", diff --git a/l10n/bs.js b/l10n/bs.js index c86291493..ff073da0b 100644 --- a/l10n/bs.js +++ b/l10n/bs.js @@ -4,6 +4,8 @@ OC.L10N.register( "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Ova tajna je podijeljena s mnogo partnerskih organizacija, pa čuvanje čeka na ograničenje upita i zatim se nastavlja. Ne zatvarajte ovaj prozor.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Previše upita partnerskim organizacijama. Ništa nije sačuvano; pokušajte ponovo za minutu.", "This version cannot be restored to this secret. Nothing was saved.": "Ova verzija se ne može vratiti za ovu tajnu. Ništa nije sačuvano.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Podijeljeno s vama samo za pregled. Zatražite od vlasnika prava uređivanja da biste je promijenili.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Podijeljeno s vama samo za pregled. Ništa nije sačuvano; zatražite od vlasnika prava uređivanja da biste je promijenili.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Partnerska organizacija s kojom se dijeli ova tajna nije dostupna ({partners}). Napravite promjenu ponovo dok ste na mreži, gdje je možete sačuvati bez njih.", "Save without them": "Sačuvaj bez njih", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Sačuvano. Primaoci u partnerskim organizacijama dobit će ovu promjenu kada vlasnik sljedeći put sačuva ovu tajnu.", diff --git a/l10n/bs.json b/l10n/bs.json index 4165cb384..826ad8858 100644 --- a/l10n/bs.json +++ b/l10n/bs.json @@ -3,6 +3,8 @@ "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Ova tajna je podijeljena s mnogo partnerskih organizacija, pa čuvanje čeka na ograničenje upita i zatim se nastavlja. Ne zatvarajte ovaj prozor.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Previše upita partnerskim organizacijama. Ništa nije sačuvano; pokušajte ponovo za minutu.", "This version cannot be restored to this secret. Nothing was saved.": "Ova verzija se ne može vratiti za ovu tajnu. Ništa nije sačuvano.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Podijeljeno s vama samo za pregled. Zatražite od vlasnika prava uređivanja da biste je promijenili.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Podijeljeno s vama samo za pregled. Ništa nije sačuvano; zatražite od vlasnika prava uređivanja da biste je promijenili.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Partnerska organizacija s kojom se dijeli ova tajna nije dostupna ({partners}). Napravite promjenu ponovo dok ste na mreži, gdje je možete sačuvati bez njih.", "Save without them": "Sačuvaj bez njih", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Sačuvano. Primaoci u partnerskim organizacijama dobit će ovu promjenu kada vlasnik sljedeći put sačuva ovu tajnu.", diff --git a/l10n/ca.js b/l10n/ca.js index 33bf6d047..685c232d3 100644 --- a/l10n/ca.js +++ b/l10n/ca.js @@ -4,6 +4,8 @@ OC.L10N.register( "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Aquest secret es comparteix amb moltes organitzacions associades, així que el desament espera el límit de consultes i després continua. Mantén aquest diàleg obert.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Massa consultes a organitzacions associades. No s'ha desat res; torna-ho a provar d'aquí a un minut.", "This version cannot be restored to this secret. Nothing was saved.": "Aquesta versió no es pot restaurar en aquest secret. No s'ha desat res.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Compartit amb tu només per veure'l. Demana al propietari permisos d'edició per canviar-lo.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Compartit amb tu només per veure'l. No s'ha desat res; demana al propietari permisos d'edició per canviar-lo.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "No es pot contactar amb una organització associada amb qui es comparteix aquest secret ({partners}). Torna a fer el canvi en línia, on pots desar sense ells.", "Save without them": "Desa sense ells", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Desat. Els destinataris d'organitzacions associades rebran aquest canvi quan el propietari torni a desar aquest secret.", diff --git a/l10n/ca.json b/l10n/ca.json index 38c61dc71..b9d301b80 100644 --- a/l10n/ca.json +++ b/l10n/ca.json @@ -3,6 +3,8 @@ "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Aquest secret es comparteix amb moltes organitzacions associades, així que el desament espera el límit de consultes i després continua. Mantén aquest diàleg obert.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Massa consultes a organitzacions associades. No s'ha desat res; torna-ho a provar d'aquí a un minut.", "This version cannot be restored to this secret. Nothing was saved.": "Aquesta versió no es pot restaurar en aquest secret. No s'ha desat res.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Compartit amb tu només per veure'l. Demana al propietari permisos d'edició per canviar-lo.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Compartit amb tu només per veure'l. No s'ha desat res; demana al propietari permisos d'edició per canviar-lo.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "No es pot contactar amb una organització associada amb qui es comparteix aquest secret ({partners}). Torna a fer el canvi en línia, on pots desar sense ells.", "Save without them": "Desa sense ells", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Desat. Els destinataris d'organitzacions associades rebran aquest canvi quan el propietari torni a desar aquest secret.", diff --git a/l10n/cs.js b/l10n/cs.js index c58b881cf..89af5da06 100644 --- a/l10n/cs.js +++ b/l10n/cs.js @@ -4,6 +4,8 @@ OC.L10N.register( "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Toto tajemství je sdíleno s mnoha partnerskými organizacemi, proto ukládání čeká na limit dotazů a poté pokračuje. Nechte toto okno otevřené.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Příliš mnoho dotazů na partnerské organizace. Nic nebylo uloženo; zkuste to znovu za minutu.", "This version cannot be restored to this secret. Nothing was saved.": "Tuto verzi nelze u tohoto tajemství obnovit. Nic nebylo uloženo.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Sdíleno s vámi pouze pro zobrazení. Chcete-li ho změnit, požádejte vlastníka o oprávnění k úpravám.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Sdíleno s vámi pouze pro zobrazení. Nic nebylo uloženo; chcete-li ho změnit, požádejte vlastníka o oprávnění k úpravám.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Partnerská organizace, se kterou je toto tajemství sdíleno, není dostupná ({partners}). Proveďte změnu znovu online, kde ji můžete uložit bez ní.", "Save without them": "Uložit bez nich", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Uloženo. Příjemci v partnerských organizacích dostanou tuto změnu, až vlastník příště uloží toto tajemství.", diff --git a/l10n/cs.json b/l10n/cs.json index cda8b965f..717f5df05 100644 --- a/l10n/cs.json +++ b/l10n/cs.json @@ -3,6 +3,8 @@ "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Toto tajemství je sdíleno s mnoha partnerskými organizacemi, proto ukládání čeká na limit dotazů a poté pokračuje. Nechte toto okno otevřené.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Příliš mnoho dotazů na partnerské organizace. Nic nebylo uloženo; zkuste to znovu za minutu.", "This version cannot be restored to this secret. Nothing was saved.": "Tuto verzi nelze u tohoto tajemství obnovit. Nic nebylo uloženo.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Sdíleno s vámi pouze pro zobrazení. Chcete-li ho změnit, požádejte vlastníka o oprávnění k úpravám.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Sdíleno s vámi pouze pro zobrazení. Nic nebylo uloženo; chcete-li ho změnit, požádejte vlastníka o oprávnění k úpravám.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Partnerská organizace, se kterou je toto tajemství sdíleno, není dostupná ({partners}). Proveďte změnu znovu online, kde ji můžete uložit bez ní.", "Save without them": "Uložit bez nich", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Uloženo. Příjemci v partnerských organizacích dostanou tuto změnu, až vlastník příště uloží toto tajemství.", diff --git a/l10n/da.js b/l10n/da.js index ced9c1301..6c990e314 100644 --- a/l10n/da.js +++ b/l10n/da.js @@ -4,6 +4,8 @@ OC.L10N.register( "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Denne hemmelighed er delt med mange partnerorganisationer, så gemningen venter på opslagsgrænsen og fortsætter derefter. Hold denne dialog åben.", "Too many partner lookups. Nothing was saved; try again in a minute.": "For mange opslag hos partnerorganisationer. Intet blev gemt; prøv igen om et minut.", "This version cannot be restored to this secret. Nothing was saved.": "Denne version kan ikke gendannes for denne hemmelighed. Intet blev gemt.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Delt med dig kun til visning. Bed ejeren om redigeringsrettigheder for at ændre den.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Delt med dig kun til visning. Intet blev gemt; bed ejeren om redigeringsrettigheder for at ændre den.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "En partnerorganisation, som denne hemmelighed er delt med, kan ikke nås ({partners}). Foretag ændringen igen online, hvor du kan gemme uden dem.", "Save without them": "Gem uden dem", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Gemt. Modtagere hos partnerorganisationer får denne ændring, næste gang ejeren gemmer denne hemmelighed.", diff --git a/l10n/da.json b/l10n/da.json index c8053f330..e78123d87 100644 --- a/l10n/da.json +++ b/l10n/da.json @@ -3,6 +3,8 @@ "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Denne hemmelighed er delt med mange partnerorganisationer, så gemningen venter på opslagsgrænsen og fortsætter derefter. Hold denne dialog åben.", "Too many partner lookups. Nothing was saved; try again in a minute.": "For mange opslag hos partnerorganisationer. Intet blev gemt; prøv igen om et minut.", "This version cannot be restored to this secret. Nothing was saved.": "Denne version kan ikke gendannes for denne hemmelighed. Intet blev gemt.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Delt med dig kun til visning. Bed ejeren om redigeringsrettigheder for at ændre den.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Delt med dig kun til visning. Intet blev gemt; bed ejeren om redigeringsrettigheder for at ændre den.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "En partnerorganisation, som denne hemmelighed er delt med, kan ikke nås ({partners}). Foretag ændringen igen online, hvor du kan gemme uden dem.", "Save without them": "Gem uden dem", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Gemt. Modtagere hos partnerorganisationer får denne ændring, næste gang ejeren gemmer denne hemmelighed.", diff --git a/l10n/de.js b/l10n/de.js index 0e92588e8..13fec0b67 100644 --- a/l10n/de.js +++ b/l10n/de.js @@ -4,6 +4,8 @@ OC.L10N.register( "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Dieses Geheimnis ist mit vielen Partnerorganisationen geteilt, daher wartet das Speichern auf das Abfragelimit und wird dann fortgesetzt. Lassen Sie diesen Dialog geöffnet.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Zu viele Abfragen bei Partnerorganisationen. Es wurde nichts gespeichert; versuchen Sie es in einer Minute erneut.", "This version cannot be restored to this secret. Nothing was saved.": "Diese Version kann für dieses Geheimnis nicht wiederhergestellt werden. Es wurde nichts gespeichert.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Nur zum Ansehen mit Ihnen geteilt. Bitten Sie den Eigentümer um Bearbeitungsrechte, um es zu ändern.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Nur zum Ansehen mit Ihnen geteilt. Es wurde nichts gespeichert; bitten Sie den Eigentümer um Bearbeitungsrechte, um es zu ändern.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Eine Partnerorganisation, mit der dieses Geheimnis geteilt ist, ist nicht erreichbar ({partners}). Nehmen Sie die Änderung online erneut vor; dort können Sie ohne sie speichern.", "Save without them": "Ohne sie speichern", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Gespeichert. Empfänger bei Partnerorganisationen erhalten diese Änderung, wenn der Eigentümer dieses Geheimnis das nächste Mal speichert.", diff --git a/l10n/de.json b/l10n/de.json index 427e9aebc..b5bcd272d 100644 --- a/l10n/de.json +++ b/l10n/de.json @@ -3,6 +3,8 @@ "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Dieses Geheimnis ist mit vielen Partnerorganisationen geteilt, daher wartet das Speichern auf das Abfragelimit und wird dann fortgesetzt. Lassen Sie diesen Dialog geöffnet.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Zu viele Abfragen bei Partnerorganisationen. Es wurde nichts gespeichert; versuchen Sie es in einer Minute erneut.", "This version cannot be restored to this secret. Nothing was saved.": "Diese Version kann für dieses Geheimnis nicht wiederhergestellt werden. Es wurde nichts gespeichert.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Nur zum Ansehen mit Ihnen geteilt. Bitten Sie den Eigentümer um Bearbeitungsrechte, um es zu ändern.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Nur zum Ansehen mit Ihnen geteilt. Es wurde nichts gespeichert; bitten Sie den Eigentümer um Bearbeitungsrechte, um es zu ändern.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Eine Partnerorganisation, mit der dieses Geheimnis geteilt ist, ist nicht erreichbar ({partners}). Nehmen Sie die Änderung online erneut vor; dort können Sie ohne sie speichern.", "Save without them": "Ohne sie speichern", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Gespeichert. Empfänger bei Partnerorganisationen erhalten diese Änderung, wenn der Eigentümer dieses Geheimnis das nächste Mal speichert.", diff --git a/l10n/el.js b/l10n/el.js index 296c7a11d..7f600b0b3 100644 --- a/l10n/el.js +++ b/l10n/el.js @@ -4,6 +4,8 @@ OC.L10N.register( "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Αυτό το μυστικό είναι κοινόχρηστο με πολλούς συνεργαζόμενους οργανισμούς, οπότε η αποθήκευση περιμένει το όριο αναζητήσεων και μετά συνεχίζει. Κρατήστε αυτό το παράθυρο ανοιχτό.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Πάρα πολλές αναζητήσεις σε συνεργαζόμενους οργανισμούς. Δεν αποθηκεύτηκε τίποτα· δοκιμάστε ξανά σε ένα λεπτό.", "This version cannot be restored to this secret. Nothing was saved.": "Αυτή η έκδοση δεν μπορεί να επαναφερθεί σε αυτό το μυστικό. Δεν αποθηκεύτηκε τίποτα.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Κοινοποιήθηκε σε εσάς μόνο για προβολή. Ζητήστε από τον κάτοχο δικαιώματα επεξεργασίας για να το αλλάξετε.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Κοινοποιήθηκε σε εσάς μόνο για προβολή. Δεν αποθηκεύτηκε τίποτα· ζητήστε από τον κάτοχο δικαιώματα επεξεργασίας για να το αλλάξετε.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Ένας συνεργαζόμενος οργανισμός με τον οποίο είναι κοινόχρηστο αυτό το μυστικό δεν είναι προσβάσιμος ({partners}). Κάντε ξανά την αλλαγή ενώ είστε συνδεδεμένοι, όπου μπορείτε να αποθηκεύσετε χωρίς αυτούς.", "Save without them": "Αποθήκευση χωρίς αυτούς", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Αποθηκεύτηκε. Οι παραλήπτες σε συνεργαζόμενους οργανισμούς θα λάβουν αυτή την αλλαγή όταν ο κάτοχος αποθηκεύσει ξανά αυτό το μυστικό.", diff --git a/l10n/el.json b/l10n/el.json index 57dc27ee3..171f4cf17 100644 --- a/l10n/el.json +++ b/l10n/el.json @@ -3,6 +3,8 @@ "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Αυτό το μυστικό είναι κοινόχρηστο με πολλούς συνεργαζόμενους οργανισμούς, οπότε η αποθήκευση περιμένει το όριο αναζητήσεων και μετά συνεχίζει. Κρατήστε αυτό το παράθυρο ανοιχτό.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Πάρα πολλές αναζητήσεις σε συνεργαζόμενους οργανισμούς. Δεν αποθηκεύτηκε τίποτα· δοκιμάστε ξανά σε ένα λεπτό.", "This version cannot be restored to this secret. Nothing was saved.": "Αυτή η έκδοση δεν μπορεί να επαναφερθεί σε αυτό το μυστικό. Δεν αποθηκεύτηκε τίποτα.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Κοινοποιήθηκε σε εσάς μόνο για προβολή. Ζητήστε από τον κάτοχο δικαιώματα επεξεργασίας για να το αλλάξετε.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Κοινοποιήθηκε σε εσάς μόνο για προβολή. Δεν αποθηκεύτηκε τίποτα· ζητήστε από τον κάτοχο δικαιώματα επεξεργασίας για να το αλλάξετε.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Ένας συνεργαζόμενος οργανισμός με τον οποίο είναι κοινόχρηστο αυτό το μυστικό δεν είναι προσβάσιμος ({partners}). Κάντε ξανά την αλλαγή ενώ είστε συνδεδεμένοι, όπου μπορείτε να αποθηκεύσετε χωρίς αυτούς.", "Save without them": "Αποθήκευση χωρίς αυτούς", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Αποθηκεύτηκε. Οι παραλήπτες σε συνεργαζόμενους οργανισμούς θα λάβουν αυτή την αλλαγή όταν ο κάτοχος αποθηκεύσει ξανά αυτό το μυστικό.", diff --git a/l10n/en.js b/l10n/en.js index 07ee52ab8..70e3540f0 100644 --- a/l10n/en.js +++ b/l10n/en.js @@ -1679,7 +1679,9 @@ OC.L10N.register( "This secret was changed elsewhere after you opened it. Nothing was saved; open it again and redo your change.": "This secret was changed elsewhere after you opened it. Nothing was saved; open it again and redo your change.", "You are not allowed to save this change for everyone this secret is shared with. Nothing was saved.": "You are not allowed to save this change for everyone this secret is shared with. Nothing was saved.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.", - "This version cannot be restored to this secret. Nothing was saved.": "This version cannot be restored to this secret. Nothing was saved." + "This version cannot be restored to this secret. Nothing was saved.": "This version cannot be restored to this secret. Nothing was saved.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Shared with you to view only. Ask its owner for edit rights to change it.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it." }, "nplurals=2; plural=(n != 1);" ) diff --git a/l10n/en.json b/l10n/en.json index e4aafbe9c..82e1dcf54 100644 --- a/l10n/en.json +++ b/l10n/en.json @@ -1753,7 +1753,9 @@ "This secret was changed elsewhere after you opened it. Nothing was saved; open it again and redo your change.": "This secret was changed elsewhere after you opened it. Nothing was saved; open it again and redo your change.", "You are not allowed to save this change for everyone this secret is shared with. Nothing was saved.": "You are not allowed to save this change for everyone this secret is shared with. Nothing was saved.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.", - "This version cannot be restored to this secret. Nothing was saved.": "This version cannot be restored to this secret. Nothing was saved." + "This version cannot be restored to this secret. Nothing was saved.": "This version cannot be restored to this secret. Nothing was saved.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Shared with you to view only. Ask its owner for edit rights to change it.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it." }, "plurals": "", "pluralForm": "nplurals=2; plural=(n != 1);" diff --git a/l10n/es.js b/l10n/es.js index ae17156d9..deab05735 100644 --- a/l10n/es.js +++ b/l10n/es.js @@ -4,6 +4,8 @@ OC.L10N.register( "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Este secreto se comparte con muchas organizaciones asociadas, así que el guardado espera al límite de consultas y después continúa. Mantén este diálogo abierto.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Demasiadas consultas a organizaciones asociadas. No se ha guardado nada; inténtalo de nuevo en un minuto.", "This version cannot be restored to this secret. Nothing was saved.": "Esta versión no se puede restaurar en este secreto. No se ha guardado nada.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Compartido contigo solo para verlo. Pide al propietario permisos de edición para cambiarlo.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Compartido contigo solo para verlo. No se ha guardado nada; pide al propietario permisos de edición para cambiarlo.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "No se puede contactar con una organización asociada con la que se comparte este secreto ({partners}). Vuelve a hacer el cambio en línea, donde puedes guardar sin ellos.", "Save without them": "Guardar sin ellos", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Guardado. Los destinatarios de organizaciones asociadas recibirán este cambio cuando el propietario vuelva a guardar este secreto.", diff --git a/l10n/es.json b/l10n/es.json index 34766ed91..a45019e91 100644 --- a/l10n/es.json +++ b/l10n/es.json @@ -3,6 +3,8 @@ "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Este secreto se comparte con muchas organizaciones asociadas, así que el guardado espera al límite de consultas y después continúa. Mantén este diálogo abierto.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Demasiadas consultas a organizaciones asociadas. No se ha guardado nada; inténtalo de nuevo en un minuto.", "This version cannot be restored to this secret. Nothing was saved.": "Esta versión no se puede restaurar en este secreto. No se ha guardado nada.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Compartido contigo solo para verlo. Pide al propietario permisos de edición para cambiarlo.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Compartido contigo solo para verlo. No se ha guardado nada; pide al propietario permisos de edición para cambiarlo.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "No se puede contactar con una organización asociada con la que se comparte este secreto ({partners}). Vuelve a hacer el cambio en línea, donde puedes guardar sin ellos.", "Save without them": "Guardar sin ellos", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Guardado. Los destinatarios de organizaciones asociadas recibirán este cambio cuando el propietario vuelva a guardar este secreto.", diff --git a/l10n/et.js b/l10n/et.js index a20108cbb..a315d9dc2 100644 --- a/l10n/et.js +++ b/l10n/et.js @@ -4,6 +4,8 @@ OC.L10N.register( "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "See saladus on jagatud paljude partnerorganisatsioonidega, seega salvestamine ootab päringupiirangu möödumist ja jätkub siis. Hoia see aken avatuna.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Liiga palju partnerorganisatsioonide päringuid. Midagi ei salvestatud; proovi minuti pärast uuesti.", "This version cannot be restored to this secret. Nothing was saved.": "Seda versiooni ei saa selle saladuse jaoks taastada. Midagi ei salvestatud.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Sinuga jagatud ainult vaatamiseks. Selle muutmiseks küsi omanikult muutmisõigust.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Sinuga jagatud ainult vaatamiseks. Midagi ei salvestatud; selle muutmiseks küsi omanikult muutmisõigust.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Partnerorganisatsioon, kellega see saladus on jagatud, ei ole kättesaadav ({partners}). Tee muudatus uuesti võrgus olles, kus saad salvestada ilma nendeta.", "Save without them": "Salvesta ilma nendeta", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Salvestatud. Partnerorganisatsioonide saajad saavad selle muudatuse, kui omanik selle saladuse järgmine kord salvestab.", diff --git a/l10n/et.json b/l10n/et.json index 16fc5af67..f9a0c9d72 100644 --- a/l10n/et.json +++ b/l10n/et.json @@ -3,6 +3,8 @@ "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "See saladus on jagatud paljude partnerorganisatsioonidega, seega salvestamine ootab päringupiirangu möödumist ja jätkub siis. Hoia see aken avatuna.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Liiga palju partnerorganisatsioonide päringuid. Midagi ei salvestatud; proovi minuti pärast uuesti.", "This version cannot be restored to this secret. Nothing was saved.": "Seda versiooni ei saa selle saladuse jaoks taastada. Midagi ei salvestatud.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Sinuga jagatud ainult vaatamiseks. Selle muutmiseks küsi omanikult muutmisõigust.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Sinuga jagatud ainult vaatamiseks. Midagi ei salvestatud; selle muutmiseks küsi omanikult muutmisõigust.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Partnerorganisatsioon, kellega see saladus on jagatud, ei ole kättesaadav ({partners}). Tee muudatus uuesti võrgus olles, kus saad salvestada ilma nendeta.", "Save without them": "Salvesta ilma nendeta", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Salvestatud. Partnerorganisatsioonide saajad saavad selle muudatuse, kui omanik selle saladuse järgmine kord salvestab.", diff --git a/l10n/fi.js b/l10n/fi.js index 4e3ff6304..db094decd 100644 --- a/l10n/fi.js +++ b/l10n/fi.js @@ -4,6 +4,8 @@ OC.L10N.register( "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Tämä salaisuus on jaettu monen kumppaniorganisaation kanssa, joten tallennus odottaa hakurajaa ja jatkuu sitten. Pidä tämä ikkuna auki.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Liian monta hakua kumppaniorganisaatioilta. Mitään ei tallennettu; yritä uudelleen minuutin kuluttua.", "This version cannot be restored to this secret. Nothing was saved.": "Tätä versiota ei voi palauttaa tähän salaisuuteen. Mitään ei tallennettu.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Jaettu sinulle vain katseltavaksi. Pyydä omistajalta muokkausoikeudet, jos haluat muuttaa sitä.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Jaettu sinulle vain katseltavaksi. Mitään ei tallennettu; pyydä omistajalta muokkausoikeudet, jos haluat muuttaa sitä.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Kumppaniorganisaatiota, jonka kanssa tämä salaisuus on jaettu, ei tavoiteta ({partners}). Tee muutos uudelleen verkossa, jossa voit tallentaa ilman heitä.", "Save without them": "Tallenna ilman heitä", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Tallennettu. Kumppaniorganisaatioiden vastaanottajat saavat tämän muutoksen, kun omistaja seuraavan kerran tallentaa tämän salaisuuden.", diff --git a/l10n/fi.json b/l10n/fi.json index d2f397886..1e221b5f8 100644 --- a/l10n/fi.json +++ b/l10n/fi.json @@ -3,6 +3,8 @@ "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Tämä salaisuus on jaettu monen kumppaniorganisaation kanssa, joten tallennus odottaa hakurajaa ja jatkuu sitten. Pidä tämä ikkuna auki.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Liian monta hakua kumppaniorganisaatioilta. Mitään ei tallennettu; yritä uudelleen minuutin kuluttua.", "This version cannot be restored to this secret. Nothing was saved.": "Tätä versiota ei voi palauttaa tähän salaisuuteen. Mitään ei tallennettu.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Jaettu sinulle vain katseltavaksi. Pyydä omistajalta muokkausoikeudet, jos haluat muuttaa sitä.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Jaettu sinulle vain katseltavaksi. Mitään ei tallennettu; pyydä omistajalta muokkausoikeudet, jos haluat muuttaa sitä.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Kumppaniorganisaatiota, jonka kanssa tämä salaisuus on jaettu, ei tavoiteta ({partners}). Tee muutos uudelleen verkossa, jossa voit tallentaa ilman heitä.", "Save without them": "Tallenna ilman heitä", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Tallennettu. Kumppaniorganisaatioiden vastaanottajat saavat tämän muutoksen, kun omistaja seuraavan kerran tallentaa tämän salaisuuden.", diff --git a/l10n/fr.js b/l10n/fr.js index b97dbc4b9..d5a0c9c96 100644 --- a/l10n/fr.js +++ b/l10n/fr.js @@ -4,6 +4,8 @@ OC.L10N.register( "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Ce secret est partagé avec de nombreuses organisations partenaires, l'enregistrement attend donc la limite de recherches puis reprend. Gardez cette fenêtre ouverte.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Trop de recherches auprès des organisations partenaires. Rien n'a été enregistré ; veuillez réessayer dans une minute.", "This version cannot be restored to this secret. Nothing was saved.": "Cette version ne peut pas être restaurée pour ce secret. Rien n'a été enregistré.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Partagé avec vous en lecture seule. Demandez au propriétaire des droits de modification pour le changer.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Partagé avec vous en lecture seule. Rien n'a été enregistré ; demandez au propriétaire des droits de modification pour le changer.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Une organisation partenaire avec laquelle ce secret est partagé est injoignable ({partners}). Refaites la modification en ligne, où vous pouvez enregistrer sans elle.", "Save without them": "Enregistrer sans eux", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Enregistré. Les destinataires des organisations partenaires recevront cette modification lorsque le propriétaire enregistrera de nouveau ce secret.", diff --git a/l10n/fr.json b/l10n/fr.json index 2ddbc0da9..8d9485b06 100644 --- a/l10n/fr.json +++ b/l10n/fr.json @@ -3,6 +3,8 @@ "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Ce secret est partagé avec de nombreuses organisations partenaires, l'enregistrement attend donc la limite de recherches puis reprend. Gardez cette fenêtre ouverte.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Trop de recherches auprès des organisations partenaires. Rien n'a été enregistré ; veuillez réessayer dans une minute.", "This version cannot be restored to this secret. Nothing was saved.": "Cette version ne peut pas être restaurée pour ce secret. Rien n'a été enregistré.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Partagé avec vous en lecture seule. Demandez au propriétaire des droits de modification pour le changer.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Partagé avec vous en lecture seule. Rien n'a été enregistré ; demandez au propriétaire des droits de modification pour le changer.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Une organisation partenaire avec laquelle ce secret est partagé est injoignable ({partners}). Refaites la modification en ligne, où vous pouvez enregistrer sans elle.", "Save without them": "Enregistrer sans eux", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Enregistré. Les destinataires des organisations partenaires recevront cette modification lorsque le propriétaire enregistrera de nouveau ce secret.", diff --git a/l10n/ga.js b/l10n/ga.js index 9c310f6ac..886049d3b 100644 --- a/l10n/ga.js +++ b/l10n/ga.js @@ -4,6 +4,8 @@ OC.L10N.register( "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Tá an rún seo comhroinnte le go leor eagraíochtaí comhpháirtíochta, mar sin tá an sábháil ag fanacht ar an teorainn cuardaigh agus leanfaidh sí ar aghaidh ansin. Coinnigh an fhuinneog seo oscailte.", "Too many partner lookups. Nothing was saved; try again in a minute.": "An iomarca cuardach ar eagraíochtaí comhpháirtíochta. Níor sábháladh aon rud; bain triail eile as i gceann nóiméid.", "This version cannot be restored to this secret. Nothing was saved.": "Ní féidir an leagan seo a athchóiriú don rún seo. Níor sábháladh aon rud.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Comhroinnte leat le féachaint air amháin. Iarr cearta eagarthóireachta ar an úinéir chun é a athrú.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Comhroinnte leat le féachaint air amháin. Níor sábháladh aon rud; iarr cearta eagarthóireachta ar an úinéir chun é a athrú.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Ní féidir teagmháil a dhéanamh le heagraíocht chomhpháirtíochta a bhfuil an rún seo roinnte léi ({partners}). Déan an t-athrú arís ar líne, áit ar féidir leat sábháil gan iad.", "Save without them": "Sábháil gan iad", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Sábháilte. Gheobhaidh faighteoirí in eagraíochtaí comhpháirtíochta an t-athrú seo nuair a shábhálfaidh an t-úinéir an rún seo an chéad uair eile.", diff --git a/l10n/ga.json b/l10n/ga.json index 8e2409fe5..fcdd2c730 100644 --- a/l10n/ga.json +++ b/l10n/ga.json @@ -3,6 +3,8 @@ "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Tá an rún seo comhroinnte le go leor eagraíochtaí comhpháirtíochta, mar sin tá an sábháil ag fanacht ar an teorainn cuardaigh agus leanfaidh sí ar aghaidh ansin. Coinnigh an fhuinneog seo oscailte.", "Too many partner lookups. Nothing was saved; try again in a minute.": "An iomarca cuardach ar eagraíochtaí comhpháirtíochta. Níor sábháladh aon rud; bain triail eile as i gceann nóiméid.", "This version cannot be restored to this secret. Nothing was saved.": "Ní féidir an leagan seo a athchóiriú don rún seo. Níor sábháladh aon rud.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Comhroinnte leat le féachaint air amháin. Iarr cearta eagarthóireachta ar an úinéir chun é a athrú.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Comhroinnte leat le féachaint air amháin. Níor sábháladh aon rud; iarr cearta eagarthóireachta ar an úinéir chun é a athrú.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Ní féidir teagmháil a dhéanamh le heagraíocht chomhpháirtíochta a bhfuil an rún seo roinnte léi ({partners}). Déan an t-athrú arís ar líne, áit ar féidir leat sábháil gan iad.", "Save without them": "Sábháil gan iad", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Sábháilte. Gheobhaidh faighteoirí in eagraíochtaí comhpháirtíochta an t-athrú seo nuair a shábhálfaidh an t-úinéir an rún seo an chéad uair eile.", diff --git a/l10n/hr.js b/l10n/hr.js index 1e4cb951f..9e0c9c42d 100644 --- a/l10n/hr.js +++ b/l10n/hr.js @@ -4,6 +4,8 @@ OC.L10N.register( "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Ova tajna dijeli se s mnogo partnerskih organizacija, pa spremanje čeka ograničenje upita i zatim se nastavlja. Ne zatvarajte ovaj prozor.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Previše upita partnerskim organizacijama. Ništa nije spremljeno; pokušajte ponovno za minutu.", "This version cannot be restored to this secret. Nothing was saved.": "Ova verzija ne može se vratiti za ovu tajnu. Ništa nije spremljeno.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Podijeljeno s vama samo za pregled. Zatražite od vlasnika prava uređivanja kako biste je promijenili.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Podijeljeno s vama samo za pregled. Ništa nije spremljeno; zatražite od vlasnika prava uređivanja kako biste je promijenili.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Partnerska organizacija s kojom se dijeli ova tajna nije dostupna ({partners}). Ponovite promjenu na mreži, gdje je možete spremiti bez njih.", "Save without them": "Spremi bez njih", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Spremljeno. Primatelji u partnerskim organizacijama dobit će ovu promjenu kada vlasnik sljedeći put spremi ovu tajnu.", diff --git a/l10n/hr.json b/l10n/hr.json index e888d51d6..3973121db 100644 --- a/l10n/hr.json +++ b/l10n/hr.json @@ -3,6 +3,8 @@ "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Ova tajna dijeli se s mnogo partnerskih organizacija, pa spremanje čeka ograničenje upita i zatim se nastavlja. Ne zatvarajte ovaj prozor.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Previše upita partnerskim organizacijama. Ništa nije spremljeno; pokušajte ponovno za minutu.", "This version cannot be restored to this secret. Nothing was saved.": "Ova verzija ne može se vratiti za ovu tajnu. Ništa nije spremljeno.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Podijeljeno s vama samo za pregled. Zatražite od vlasnika prava uređivanja kako biste je promijenili.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Podijeljeno s vama samo za pregled. Ništa nije spremljeno; zatražite od vlasnika prava uređivanja kako biste je promijenili.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Partnerska organizacija s kojom se dijeli ova tajna nije dostupna ({partners}). Ponovite promjenu na mreži, gdje je možete spremiti bez njih.", "Save without them": "Spremi bez njih", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Spremljeno. Primatelji u partnerskim organizacijama dobit će ovu promjenu kada vlasnik sljedeći put spremi ovu tajnu.", diff --git a/l10n/hu.js b/l10n/hu.js index 948e1e35d..727f67351 100644 --- a/l10n/hu.js +++ b/l10n/hu.js @@ -4,6 +4,8 @@ OC.L10N.register( "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Ez a titok sok partnerszervezettel van megosztva, ezért a mentés kivárja a lekérdezési korlátot, majd folytatódik. Hagyja nyitva ezt az ablakot.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Túl sok lekérdezés a partnerszervezetek felé. Semmi sem lett mentve; próbálja újra egy perc múlva.", "This version cannot be restored to this secret. Nothing was saved.": "Ez a verzió nem állítható vissza ehhez a titokhoz. Semmi sem lett mentve.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Csak megtekintésre osztották meg Önnel. A módosításhoz kérjen szerkesztési jogot a tulajdonostól.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Csak megtekintésre osztották meg Önnel. Semmi sem lett mentve; a módosításhoz kérjen szerkesztési jogot a tulajdonostól.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Egy partnerszervezet, amellyel ez a titok meg van osztva, nem érhető el ({partners}). Végezze el újra a módosítást online, ahol nélkülük is mentheti.", "Save without them": "Mentés nélkülük", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Mentve. A partnerszervezeteknél lévő címzettek akkor kapják meg ezt a módosítást, amikor a tulajdonos legközelebb menti ezt a titkot.", diff --git a/l10n/hu.json b/l10n/hu.json index 662f33872..183e1c239 100644 --- a/l10n/hu.json +++ b/l10n/hu.json @@ -3,6 +3,8 @@ "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Ez a titok sok partnerszervezettel van megosztva, ezért a mentés kivárja a lekérdezési korlátot, majd folytatódik. Hagyja nyitva ezt az ablakot.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Túl sok lekérdezés a partnerszervezetek felé. Semmi sem lett mentve; próbálja újra egy perc múlva.", "This version cannot be restored to this secret. Nothing was saved.": "Ez a verzió nem állítható vissza ehhez a titokhoz. Semmi sem lett mentve.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Csak megtekintésre osztották meg Önnel. A módosításhoz kérjen szerkesztési jogot a tulajdonostól.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Csak megtekintésre osztották meg Önnel. Semmi sem lett mentve; a módosításhoz kérjen szerkesztési jogot a tulajdonostól.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Egy partnerszervezet, amellyel ez a titok meg van osztva, nem érhető el ({partners}). Végezze el újra a módosítást online, ahol nélkülük is mentheti.", "Save without them": "Mentés nélkülük", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Mentve. A partnerszervezeteknél lévő címzettek akkor kapják meg ezt a módosítást, amikor a tulajdonos legközelebb menti ezt a titkot.", diff --git a/l10n/is.js b/l10n/is.js index 85af0cca5..551ccfe4c 100644 --- a/l10n/is.js +++ b/l10n/is.js @@ -4,6 +4,8 @@ OC.L10N.register( "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Þetta leyndarmál er deilt með mörgum samstarfsaðilum, svo vistunin bíður eftir uppflettimörkunum og heldur svo áfram. Hafðu þennan glugga opinn.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Of margar uppflettingar hjá samstarfsaðilum. Ekkert var vistað; reyndu aftur eftir eina mínútu.", "This version cannot be restored to this secret. Nothing was saved.": "Ekki er hægt að endurheimta þessa útgáfu fyrir þetta leyndarmál. Ekkert var vistað.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Deilt með þér eingöngu til skoðunar. Biddu eigandann um breytingaheimild til að breyta því.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Deilt með þér eingöngu til skoðunar. Ekkert var vistað; biddu eigandann um breytingaheimild til að breyta því.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Ekki næst í samstarfsfyrirtæki sem þetta leyndarmál er samnýtt með ({partners}). Gerðu breytinguna aftur á netinu, þar sem þú getur vistað án þeirra.", "Save without them": "Vista án þeirra", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Vistað. Viðtakendur hjá samstarfsfyrirtækjum fá þessa breytingu þegar eigandinn vistar þetta leyndarmál næst.", diff --git a/l10n/is.json b/l10n/is.json index c9963e85f..69cf816bf 100644 --- a/l10n/is.json +++ b/l10n/is.json @@ -3,6 +3,8 @@ "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Þetta leyndarmál er deilt með mörgum samstarfsaðilum, svo vistunin bíður eftir uppflettimörkunum og heldur svo áfram. Hafðu þennan glugga opinn.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Of margar uppflettingar hjá samstarfsaðilum. Ekkert var vistað; reyndu aftur eftir eina mínútu.", "This version cannot be restored to this secret. Nothing was saved.": "Ekki er hægt að endurheimta þessa útgáfu fyrir þetta leyndarmál. Ekkert var vistað.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Deilt með þér eingöngu til skoðunar. Biddu eigandann um breytingaheimild til að breyta því.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Deilt með þér eingöngu til skoðunar. Ekkert var vistað; biddu eigandann um breytingaheimild til að breyta því.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Ekki næst í samstarfsfyrirtæki sem þetta leyndarmál er samnýtt með ({partners}). Gerðu breytinguna aftur á netinu, þar sem þú getur vistað án þeirra.", "Save without them": "Vista án þeirra", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Vistað. Viðtakendur hjá samstarfsfyrirtækjum fá þessa breytingu þegar eigandinn vistar þetta leyndarmál næst.", diff --git a/l10n/it.js b/l10n/it.js index 3da2623d3..605f756ff 100644 --- a/l10n/it.js +++ b/l10n/it.js @@ -4,6 +4,8 @@ OC.L10N.register( "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Questo segreto è condiviso con molte organizzazioni partner, quindi il salvataggio attende il limite di ricerche e poi prosegue. Tieni aperta questa finestra.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Troppe ricerche presso le organizzazioni partner. Non è stato salvato nulla; riprova tra un minuto.", "This version cannot be restored to this secret. Nothing was saved.": "Questa versione non può essere ripristinata per questo segreto. Non è stato salvato nulla.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Condiviso con te in sola visualizzazione. Chiedi al proprietario i permessi di modifica per cambiarlo.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Condiviso con te in sola visualizzazione. Non è stato salvato nulla; chiedi al proprietario i permessi di modifica per cambiarlo.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Un'organizzazione partner con cui è condiviso questo segreto non è raggiungibile ({partners}). Ripeti la modifica online, dove puoi salvare senza di loro.", "Save without them": "Salva senza di loro", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Salvato. I destinatari presso le organizzazioni partner riceveranno questa modifica quando il proprietario salverà di nuovo questo segreto.", diff --git a/l10n/it.json b/l10n/it.json index 44e2d5bde..ebd53e3ef 100644 --- a/l10n/it.json +++ b/l10n/it.json @@ -3,6 +3,8 @@ "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Questo segreto è condiviso con molte organizzazioni partner, quindi il salvataggio attende il limite di ricerche e poi prosegue. Tieni aperta questa finestra.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Troppe ricerche presso le organizzazioni partner. Non è stato salvato nulla; riprova tra un minuto.", "This version cannot be restored to this secret. Nothing was saved.": "Questa versione non può essere ripristinata per questo segreto. Non è stato salvato nulla.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Condiviso con te in sola visualizzazione. Chiedi al proprietario i permessi di modifica per cambiarlo.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Condiviso con te in sola visualizzazione. Non è stato salvato nulla; chiedi al proprietario i permessi di modifica per cambiarlo.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Un'organizzazione partner con cui è condiviso questo segreto non è raggiungibile ({partners}). Ripeti la modifica online, dove puoi salvare senza di loro.", "Save without them": "Salva senza di loro", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Salvato. I destinatari presso le organizzazioni partner riceveranno questa modifica quando il proprietario salverà di nuovo questo segreto.", diff --git a/l10n/lb.js b/l10n/lb.js index 464ced051..88e1fdcc9 100644 --- a/l10n/lb.js +++ b/l10n/lb.js @@ -4,6 +4,8 @@ OC.L10N.register( "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Dëst Geheimnis ass mat ville Partnerorganisatiounen gedeelt, dofir waart d'Späicheren op d'Ufrolimit a geet duerno weider. Loosst dës Fënster op.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Ze vill Ufroe bei Partnerorganisatiounen. Et gouf näischt gespäichert; probéiert an enger Minutt nach eng Kéier.", "This version cannot be restored to this secret. Nothing was saved.": "Dës Versioun kann net fir dëst Geheimnis restauréiert ginn. Et gouf näischt gespäichert.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Mat Iech nëmmen zum Ukucken gedeelt. Frot de Besëtzer no Ännerungsrechter, fir et z'änneren.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Mat Iech nëmmen zum Ukucken gedeelt. Et gouf näischt gespäichert; frot de Besëtzer no Ännerungsrechter, fir et z'änneren.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Eng Partnerorganisatioun, mat där dëst Geheimnis gedeelt ass, ass net erreechbar ({partners}). Maacht d'Ännerung online nach eng Kéier; do kënnt Dir ouni si späicheren.", "Save without them": "Ouni si späicheren", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Gespäichert. Empfänger bei Partnerorganisatiounen kréien dës Ännerung, wann de Besëtzer dëst Geheimnis déi nächst Kéier späichert.", diff --git a/l10n/lb.json b/l10n/lb.json index 66ccaebbe..82c51e452 100644 --- a/l10n/lb.json +++ b/l10n/lb.json @@ -3,6 +3,8 @@ "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Dëst Geheimnis ass mat ville Partnerorganisatiounen gedeelt, dofir waart d'Späicheren op d'Ufrolimit a geet duerno weider. Loosst dës Fënster op.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Ze vill Ufroe bei Partnerorganisatiounen. Et gouf näischt gespäichert; probéiert an enger Minutt nach eng Kéier.", "This version cannot be restored to this secret. Nothing was saved.": "Dës Versioun kann net fir dëst Geheimnis restauréiert ginn. Et gouf näischt gespäichert.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Mat Iech nëmmen zum Ukucken gedeelt. Frot de Besëtzer no Ännerungsrechter, fir et z'änneren.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Mat Iech nëmmen zum Ukucken gedeelt. Et gouf näischt gespäichert; frot de Besëtzer no Ännerungsrechter, fir et z'änneren.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Eng Partnerorganisatioun, mat där dëst Geheimnis gedeelt ass, ass net erreechbar ({partners}). Maacht d'Ännerung online nach eng Kéier; do kënnt Dir ouni si späicheren.", "Save without them": "Ouni si späicheren", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Gespäichert. Empfänger bei Partnerorganisatiounen kréien dës Ännerung, wann de Besëtzer dëst Geheimnis déi nächst Kéier späichert.", diff --git a/l10n/lt.js b/l10n/lt.js index 3976d8159..39a291dcc 100644 --- a/l10n/lt.js +++ b/l10n/lt.js @@ -4,6 +4,8 @@ OC.L10N.register( "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Ši paslaptis bendrinama su daug partnerių organizacijų, todėl išsaugojimas laukia užklausų ribos ir tada tęsiamas. Neuždarykite šio lango.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Per daug užklausų partnerių organizacijoms. Niekas neišsaugota; bandykite dar kartą po minutės.", "This version cannot be restored to this secret. Nothing was saved.": "Šios versijos negalima atkurti šiai paslapčiai. Niekas neišsaugota.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Bendrinama su jumis tik peržiūrai. Norėdami pakeisti, paprašykite savininko redagavimo teisių.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Bendrinama su jumis tik peržiūrai. Niekas neišsaugota; norėdami pakeisti, paprašykite savininko redagavimo teisių.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Partnerių organizacija, su kuria bendrinama ši paslaptis, nepasiekiama ({partners}). Pakartokite pakeitimą prisijungę, kur galite išsaugoti be jų.", "Save without them": "Išsaugoti be jų", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Išsaugota. Gavėjai partnerių organizacijose gaus šį pakeitimą, kai savininkas kitą kartą išsaugos šią paslaptį.", diff --git a/l10n/lt.json b/l10n/lt.json index 0635621f9..54e785b8d 100644 --- a/l10n/lt.json +++ b/l10n/lt.json @@ -3,6 +3,8 @@ "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Ši paslaptis bendrinama su daug partnerių organizacijų, todėl išsaugojimas laukia užklausų ribos ir tada tęsiamas. Neuždarykite šio lango.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Per daug užklausų partnerių organizacijoms. Niekas neišsaugota; bandykite dar kartą po minutės.", "This version cannot be restored to this secret. Nothing was saved.": "Šios versijos negalima atkurti šiai paslapčiai. Niekas neišsaugota.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Bendrinama su jumis tik peržiūrai. Norėdami pakeisti, paprašykite savininko redagavimo teisių.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Bendrinama su jumis tik peržiūrai. Niekas neišsaugota; norėdami pakeisti, paprašykite savininko redagavimo teisių.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Partnerių organizacija, su kuria bendrinama ši paslaptis, nepasiekiama ({partners}). Pakartokite pakeitimą prisijungę, kur galite išsaugoti be jų.", "Save without them": "Išsaugoti be jų", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Išsaugota. Gavėjai partnerių organizacijose gaus šį pakeitimą, kai savininkas kitą kartą išsaugos šią paslaptį.", diff --git a/l10n/lv.js b/l10n/lv.js index 2427bd25b..30b61ae4b 100644 --- a/l10n/lv.js +++ b/l10n/lv.js @@ -4,6 +4,8 @@ OC.L10N.register( "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Šis noslēpums ir kopīgots ar daudzām partneru organizācijām, tāpēc saglabāšana gaida vaicājumu ierobežojumu un pēc tam turpinās. Neaizveriet šo logu.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Pārāk daudz vaicājumu partneru organizācijām. Nekas netika saglabāts; mēģiniet vēlreiz pēc minūtes.", "This version cannot be restored to this secret. Nothing was saved.": "Šo versiju nevar atjaunot šim noslēpumam. Nekas netika saglabāts.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Kopīgots ar jums tikai skatīšanai. Lai to mainītu, lūdziet īpašniekam rediģēšanas tiesības.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Kopīgots ar jums tikai skatīšanai. Nekas netika saglabāts; lai to mainītu, lūdziet īpašniekam rediģēšanas tiesības.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Partneru organizācija, ar kuru šis noslēpums ir koplietots, nav sasniedzama ({partners}). Veiciet izmaiņas vēlreiz tiešsaistē, kur varat saglabāt bez viņiem.", "Save without them": "Saglabāt bez viņiem", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Saglabāts. Saņēmēji partneru organizācijās saņems šīs izmaiņas, kad īpašnieks nākamreiz saglabās šo noslēpumu.", diff --git a/l10n/lv.json b/l10n/lv.json index d0e4384eb..7e572d029 100644 --- a/l10n/lv.json +++ b/l10n/lv.json @@ -3,6 +3,8 @@ "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Šis noslēpums ir kopīgots ar daudzām partneru organizācijām, tāpēc saglabāšana gaida vaicājumu ierobežojumu un pēc tam turpinās. Neaizveriet šo logu.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Pārāk daudz vaicājumu partneru organizācijām. Nekas netika saglabāts; mēģiniet vēlreiz pēc minūtes.", "This version cannot be restored to this secret. Nothing was saved.": "Šo versiju nevar atjaunot šim noslēpumam. Nekas netika saglabāts.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Kopīgots ar jums tikai skatīšanai. Lai to mainītu, lūdziet īpašniekam rediģēšanas tiesības.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Kopīgots ar jums tikai skatīšanai. Nekas netika saglabāts; lai to mainītu, lūdziet īpašniekam rediģēšanas tiesības.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Partneru organizācija, ar kuru šis noslēpums ir koplietots, nav sasniedzama ({partners}). Veiciet izmaiņas vēlreiz tiešsaistē, kur varat saglabāt bez viņiem.", "Save without them": "Saglabāt bez viņiem", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Saglabāts. Saņēmēji partneru organizācijās saņems šīs izmaiņas, kad īpašnieks nākamreiz saglabās šo noslēpumu.", diff --git a/l10n/mk.js b/l10n/mk.js index ee4a7a838..f5771bb8c 100644 --- a/l10n/mk.js +++ b/l10n/mk.js @@ -4,6 +4,8 @@ OC.L10N.register( "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Оваа тајна е споделена со многу партнерски организации, па зачувувањето чека на ограничувањето на барањата и потоа продолжува. Не го затворајте овој прозорец.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Премногу барања до партнерските организации. Ништо не е зачувано; обидете се повторно за една минута.", "This version cannot be restored to this secret. Nothing was saved.": "Оваа верзија не може да се врати за оваа тајна. Ништо не е зачувано.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Споделено со вас само за прегледување. Побарајте од сопственикот права за уредување за да ја промените.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Споделено со вас само за прегледување. Ништо не е зачувано; побарајте од сопственикот права за уредување за да ја промените.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Партнерска организација со која е споделена оваа тајна не е достапна ({partners}). Направете ја промената повторно на интернет, каде што можете да зачувате без нив.", "Save without them": "Зачувај без нив", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Зачувано. Примачите во партнерските организации ќе ја добијат оваа промена кога сопственикот следниот пат ќе ја зачува оваа тајна.", diff --git a/l10n/mk.json b/l10n/mk.json index 0d9aa8dd0..80256eeab 100644 --- a/l10n/mk.json +++ b/l10n/mk.json @@ -3,6 +3,8 @@ "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Оваа тајна е споделена со многу партнерски организации, па зачувувањето чека на ограничувањето на барањата и потоа продолжува. Не го затворајте овој прозорец.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Премногу барања до партнерските организации. Ништо не е зачувано; обидете се повторно за една минута.", "This version cannot be restored to this secret. Nothing was saved.": "Оваа верзија не може да се врати за оваа тајна. Ништо не е зачувано.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Споделено со вас само за прегледување. Побарајте од сопственикот права за уредување за да ја промените.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Споделено со вас само за прегледување. Ништо не е зачувано; побарајте од сопственикот права за уредување за да ја промените.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Партнерска организација со која е споделена оваа тајна не е достапна ({partners}). Направете ја промената повторно на интернет, каде што можете да зачувате без нив.", "Save without them": "Зачувај без нив", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Зачувано. Примачите во партнерските организации ќе ја добијат оваа промена кога сопственикот следниот пат ќе ја зачува оваа тајна.", diff --git a/l10n/mt.js b/l10n/mt.js index c0aa30136..1aa67c203 100644 --- a/l10n/mt.js +++ b/l10n/mt.js @@ -4,6 +4,8 @@ OC.L10N.register( "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Dan is-sigriet huwa kondiviż ma' ħafna organizzazzjonijiet sħab, għalhekk is-salvataġġ qed jistenna l-limitu tat-tfittxijiet u mbagħad ikompli. Żomm din it-tieqa miftuħa.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Wisq tfittxijiet għand organizzazzjonijiet sħab. Ma ġie ssejvjat xejn; erġa' pprova wara minuta.", "This version cannot be restored to this secret. Nothing was saved.": "Din il-verżjoni ma tistax terġa' tiġi restawrata għal dan is-sigriet. Ma ġie ssejvjat xejn.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Maqsum miegħek biex tarah biss. Itlob lis-sid drittijiet ta' editjar biex tibdlu.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Maqsum miegħek biex tarah biss. Ma ġie ssejvjat xejn; itlob lis-sid drittijiet ta' editjar biex tibdlu.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Organizzazzjoni sieħba li magħha huwa kondiviż dan is-sigriet ma tistax tintlaħaq ({partners}). Erġa' agħmel il-bidla online, fejn tista' tissejvja mingħajrhom.", "Save without them": "Issejvja mingħajrhom", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Issejvjat. Ir-riċevituri f'organizzazzjonijiet sħab jirċievu din il-bidla meta s-sid jerġa' jissejvja dan is-sigriet.", diff --git a/l10n/mt.json b/l10n/mt.json index d53712fa1..4c13284b5 100644 --- a/l10n/mt.json +++ b/l10n/mt.json @@ -3,6 +3,8 @@ "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Dan is-sigriet huwa kondiviż ma' ħafna organizzazzjonijiet sħab, għalhekk is-salvataġġ qed jistenna l-limitu tat-tfittxijiet u mbagħad ikompli. Żomm din it-tieqa miftuħa.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Wisq tfittxijiet għand organizzazzjonijiet sħab. Ma ġie ssejvjat xejn; erġa' pprova wara minuta.", "This version cannot be restored to this secret. Nothing was saved.": "Din il-verżjoni ma tistax terġa' tiġi restawrata għal dan is-sigriet. Ma ġie ssejvjat xejn.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Maqsum miegħek biex tarah biss. Itlob lis-sid drittijiet ta' editjar biex tibdlu.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Maqsum miegħek biex tarah biss. Ma ġie ssejvjat xejn; itlob lis-sid drittijiet ta' editjar biex tibdlu.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Organizzazzjoni sieħba li magħha huwa kondiviż dan is-sigriet ma tistax tintlaħaq ({partners}). Erġa' agħmel il-bidla online, fejn tista' tissejvja mingħajrhom.", "Save without them": "Issejvja mingħajrhom", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Issejvjat. Ir-riċevituri f'organizzazzjonijiet sħab jirċievu din il-bidla meta s-sid jerġa' jissejvja dan is-sigriet.", diff --git a/l10n/nb.js b/l10n/nb.js index 50c1d7c1c..51d99f7fa 100644 --- a/l10n/nb.js +++ b/l10n/nb.js @@ -4,6 +4,8 @@ OC.L10N.register( "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Denne hemmeligheten er delt med mange partnerorganisasjoner, så lagringen venter på oppslagsgrensen og fortsetter deretter. Hold denne dialogen åpen.", "Too many partner lookups. Nothing was saved; try again in a minute.": "For mange oppslag hos partnerorganisasjoner. Ingenting ble lagret; prøv igjen om et minutt.", "This version cannot be restored to this secret. Nothing was saved.": "Denne versjonen kan ikke gjenopprettes for denne hemmeligheten. Ingenting ble lagret.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Delt med deg kun for visning. Be eieren om redigeringstilgang for å endre den.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Delt med deg kun for visning. Ingenting ble lagret; be eieren om redigeringstilgang for å endre den.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "En partnerorganisasjon som denne hemmeligheten er delt med, kan ikke nås ({partners}). Gjør endringen på nytt på nett, der du kan lagre uten dem.", "Save without them": "Lagre uten dem", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Lagret. Mottakere i partnerorganisasjoner får denne endringen neste gang eieren lagrer denne hemmeligheten.", diff --git a/l10n/nb.json b/l10n/nb.json index c6f3d99c4..d0eeb2419 100644 --- a/l10n/nb.json +++ b/l10n/nb.json @@ -3,6 +3,8 @@ "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Denne hemmeligheten er delt med mange partnerorganisasjoner, så lagringen venter på oppslagsgrensen og fortsetter deretter. Hold denne dialogen åpen.", "Too many partner lookups. Nothing was saved; try again in a minute.": "For mange oppslag hos partnerorganisasjoner. Ingenting ble lagret; prøv igjen om et minutt.", "This version cannot be restored to this secret. Nothing was saved.": "Denne versjonen kan ikke gjenopprettes for denne hemmeligheten. Ingenting ble lagret.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Delt med deg kun for visning. Be eieren om redigeringstilgang for å endre den.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Delt med deg kun for visning. Ingenting ble lagret; be eieren om redigeringstilgang for å endre den.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "En partnerorganisasjon som denne hemmeligheten er delt med, kan ikke nås ({partners}). Gjør endringen på nytt på nett, der du kan lagre uten dem.", "Save without them": "Lagre uten dem", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Lagret. Mottakere i partnerorganisasjoner får denne endringen neste gang eieren lagrer denne hemmeligheten.", diff --git a/l10n/nl.js b/l10n/nl.js index 340d9d899..9db4752c1 100644 --- a/l10n/nl.js +++ b/l10n/nl.js @@ -4,6 +4,8 @@ OC.L10N.register( "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Dit geheim is gedeeld met veel partnerorganisaties, dus het opslaan wacht op de opzoeklimiet en gaat daarna verder. Houd dit venster open.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Te veel opzoekingen bij partnerorganisaties. Er is niets opgeslagen; probeer het over een minuut opnieuw.", "This version cannot be restored to this secret. Nothing was saved.": "Deze versie kan niet worden hersteld voor dit geheim. Er is niets opgeslagen.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Met je gedeeld om alleen te bekijken. Vraag de eigenaar om bewerkingsrechten om het te wijzigen.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Met je gedeeld om alleen te bekijken. Er is niets opgeslagen; vraag de eigenaar om bewerkingsrechten om het te wijzigen.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Een partnerorganisatie waarmee dit geheim gedeeld is, is niet bereikbaar ({partners}). Voer de wijziging online opnieuw uit; daar kun je opslaan zonder hen.", "Save without them": "Opslaan zonder hen", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Opgeslagen. Ontvangers bij partnerorganisaties krijgen deze wijziging zodra de eigenaar dit geheim opnieuw opslaat.", diff --git a/l10n/nl.json b/l10n/nl.json index 43e89a8c5..985ab48b0 100644 --- a/l10n/nl.json +++ b/l10n/nl.json @@ -3,6 +3,8 @@ "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Dit geheim is gedeeld met veel partnerorganisaties, dus het opslaan wacht op de opzoeklimiet en gaat daarna verder. Houd dit venster open.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Te veel opzoekingen bij partnerorganisaties. Er is niets opgeslagen; probeer het over een minuut opnieuw.", "This version cannot be restored to this secret. Nothing was saved.": "Deze versie kan niet worden hersteld voor dit geheim. Er is niets opgeslagen.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Met je gedeeld om alleen te bekijken. Vraag de eigenaar om bewerkingsrechten om het te wijzigen.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Met je gedeeld om alleen te bekijken. Er is niets opgeslagen; vraag de eigenaar om bewerkingsrechten om het te wijzigen.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Een partnerorganisatie waarmee dit geheim gedeeld is, is niet bereikbaar ({partners}). Voer de wijziging online opnieuw uit; daar kun je opslaan zonder hen.", "Save without them": "Opslaan zonder hen", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Opgeslagen. Ontvangers bij partnerorganisaties krijgen deze wijziging zodra de eigenaar dit geheim opnieuw opslaat.", diff --git a/l10n/pl.js b/l10n/pl.js index 972803a80..3a3cbf8d3 100644 --- a/l10n/pl.js +++ b/l10n/pl.js @@ -4,6 +4,8 @@ OC.L10N.register( "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Ten sekret jest udostępniony wielu organizacjom partnerskim, więc zapisywanie czeka na limit zapytań, a potem jest kontynuowane. Nie zamykaj tego okna.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Zbyt wiele zapytań do organizacji partnerskich. Nic nie zostało zapisane; spróbuj ponownie za minutę.", "This version cannot be restored to this secret. Nothing was saved.": "Tej wersji nie można przywrócić dla tego sekretu. Nic nie zostało zapisane.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Udostępnione Ci tylko do wglądu. Aby to zmienić, poproś właściciela o prawa do edycji.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Udostępnione Ci tylko do wglądu. Nic nie zostało zapisane; aby to zmienić, poproś właściciela o prawa do edycji.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Organizacja partnerska, której udostępniono ten sekret, jest nieosiągalna ({partners}). Wprowadź zmianę ponownie online, gdzie możesz zapisać bez niej.", "Save without them": "Zapisz bez nich", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Zapisano. Odbiorcy w organizacjach partnerskich otrzymają tę zmianę, gdy właściciel następnym razem zapisze ten sekret.", diff --git a/l10n/pl.json b/l10n/pl.json index b7d2c9e3b..32fb836be 100644 --- a/l10n/pl.json +++ b/l10n/pl.json @@ -3,6 +3,8 @@ "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Ten sekret jest udostępniony wielu organizacjom partnerskim, więc zapisywanie czeka na limit zapytań, a potem jest kontynuowane. Nie zamykaj tego okna.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Zbyt wiele zapytań do organizacji partnerskich. Nic nie zostało zapisane; spróbuj ponownie za minutę.", "This version cannot be restored to this secret. Nothing was saved.": "Tej wersji nie można przywrócić dla tego sekretu. Nic nie zostało zapisane.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Udostępnione Ci tylko do wglądu. Aby to zmienić, poproś właściciela o prawa do edycji.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Udostępnione Ci tylko do wglądu. Nic nie zostało zapisane; aby to zmienić, poproś właściciela o prawa do edycji.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Organizacja partnerska, której udostępniono ten sekret, jest nieosiągalna ({partners}). Wprowadź zmianę ponownie online, gdzie możesz zapisać bez niej.", "Save without them": "Zapisz bez nich", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Zapisano. Odbiorcy w organizacjach partnerskich otrzymają tę zmianę, gdy właściciel następnym razem zapisze ten sekret.", diff --git a/l10n/pt.js b/l10n/pt.js index 274e7efc8..835e0a177 100644 --- a/l10n/pt.js +++ b/l10n/pt.js @@ -4,6 +4,8 @@ OC.L10N.register( "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Este segredo está partilhado com muitas organizações parceiras, por isso a gravação aguarda o limite de consultas e depois continua. Mantenha esta janela aberta.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Demasiadas consultas a organizações parceiras. Nada foi guardado; tente novamente dentro de um minuto.", "This version cannot be restored to this secret. Nothing was saved.": "Esta versão não pode ser restaurada para este segredo. Nada foi guardado.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Partilhado consigo apenas para visualização. Peça ao proprietário direitos de edição para o alterar.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Partilhado consigo apenas para visualização. Nada foi guardado; peça ao proprietário direitos de edição para o alterar.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Uma organização parceira com quem este segredo é partilhado está inacessível ({partners}). Faça a alteração novamente online, onde pode guardar sem eles.", "Save without them": "Guardar sem eles", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Guardado. Os destinatários em organizações parceiras recebem esta alteração quando o proprietário voltar a guardar este segredo.", diff --git a/l10n/pt.json b/l10n/pt.json index aa055417c..e34b183f7 100644 --- a/l10n/pt.json +++ b/l10n/pt.json @@ -3,6 +3,8 @@ "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Este segredo está partilhado com muitas organizações parceiras, por isso a gravação aguarda o limite de consultas e depois continua. Mantenha esta janela aberta.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Demasiadas consultas a organizações parceiras. Nada foi guardado; tente novamente dentro de um minuto.", "This version cannot be restored to this secret. Nothing was saved.": "Esta versão não pode ser restaurada para este segredo. Nada foi guardado.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Partilhado consigo apenas para visualização. Peça ao proprietário direitos de edição para o alterar.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Partilhado consigo apenas para visualização. Nada foi guardado; peça ao proprietário direitos de edição para o alterar.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Uma organização parceira com quem este segredo é partilhado está inacessível ({partners}). Faça a alteração novamente online, onde pode guardar sem eles.", "Save without them": "Guardar sem eles", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Guardado. Os destinatários em organizações parceiras recebem esta alteração quando o proprietário voltar a guardar este segredo.", diff --git a/l10n/rm.js b/l10n/rm.js index 6530655fe..a5a789b66 100644 --- a/l10n/rm.js +++ b/l10n/rm.js @@ -4,6 +4,8 @@ OC.L10N.register( "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Quest secret è parti cun bleras organisaziuns partenarias, perquai spetga la memorisaziun il limit da dumondas e cuntinuescha lura. Tegna avert quest dialog.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Memia bleras dumondas tar organisaziuns partenarias. Nagut n'è vegnì memorisà; emprova anc ina giada en ina minuta.", "This version cannot be restored to this secret. Nothing was saved.": "Questa versiun na po betg vegnir restaurada per quest secret. Nagut n'è vegnì memorisà.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Parti cun tai mo per guardar. Dumonda il possessur per dretgs da modifitgar, per al midar.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Parti cun tai mo per guardar. Nagut n'è vegnì memorisà; dumonda il possessur per dretgs da modifitgar, per al midar.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Ina organisaziun partenaria cun la quala quest secret è partì n'è betg cuntanschibla ({partners}). Fa la midada danovamain online, nua che ti pos memorisar senza els.", "Save without them": "Memorisar senza els", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Memorisà. Destinaturs en organisaziuns partenarias survegnan questa midada, cura che il proprietari memorisescha la proxima giada quest secret.", diff --git a/l10n/rm.json b/l10n/rm.json index 6217a42fc..191128adf 100644 --- a/l10n/rm.json +++ b/l10n/rm.json @@ -3,6 +3,8 @@ "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Quest secret è parti cun bleras organisaziuns partenarias, perquai spetga la memorisaziun il limit da dumondas e cuntinuescha lura. Tegna avert quest dialog.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Memia bleras dumondas tar organisaziuns partenarias. Nagut n'è vegnì memorisà; emprova anc ina giada en ina minuta.", "This version cannot be restored to this secret. Nothing was saved.": "Questa versiun na po betg vegnir restaurada per quest secret. Nagut n'è vegnì memorisà.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Parti cun tai mo per guardar. Dumonda il possessur per dretgs da modifitgar, per al midar.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Parti cun tai mo per guardar. Nagut n'è vegnì memorisà; dumonda il possessur per dretgs da modifitgar, per al midar.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Ina organisaziun partenaria cun la quala quest secret è partì n'è betg cuntanschibla ({partners}). Fa la midada danovamain online, nua che ti pos memorisar senza els.", "Save without them": "Memorisar senza els", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Memorisà. Destinaturs en organisaziuns partenarias survegnan questa midada, cura che il proprietari memorisescha la proxima giada quest secret.", diff --git a/l10n/ro.js b/l10n/ro.js index b5b42ebce..b54955f46 100644 --- a/l10n/ro.js +++ b/l10n/ro.js @@ -4,6 +4,8 @@ OC.L10N.register( "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Acest secret este partajat cu multe organizații partenere, așa că salvarea așteaptă limita de interogări și apoi continuă. Păstrați această fereastră deschisă.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Prea multe interogări către organizațiile partenere. Nu s-a salvat nimic; încercați din nou peste un minut.", "This version cannot be restored to this secret. Nothing was saved.": "Această versiune nu poate fi restaurată pentru acest secret. Nu s-a salvat nimic.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Partajat cu dumneavoastră doar pentru vizualizare. Cereți proprietarului drepturi de editare pentru a-l modifica.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Partajat cu dumneavoastră doar pentru vizualizare. Nu s-a salvat nimic; cereți proprietarului drepturi de editare pentru a-l modifica.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "O organizație parteneră cu care este partajat acest secret nu poate fi contactată ({partners}). Refaceți modificarea online, unde puteți salva fără ei.", "Save without them": "Salvați fără ei", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Salvat. Destinatarii din organizațiile partenere vor primi această modificare când proprietarul va salva din nou acest secret.", diff --git a/l10n/ro.json b/l10n/ro.json index ce2173eca..b340da049 100644 --- a/l10n/ro.json +++ b/l10n/ro.json @@ -3,6 +3,8 @@ "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Acest secret este partajat cu multe organizații partenere, așa că salvarea așteaptă limita de interogări și apoi continuă. Păstrați această fereastră deschisă.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Prea multe interogări către organizațiile partenere. Nu s-a salvat nimic; încercați din nou peste un minut.", "This version cannot be restored to this secret. Nothing was saved.": "Această versiune nu poate fi restaurată pentru acest secret. Nu s-a salvat nimic.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Partajat cu dumneavoastră doar pentru vizualizare. Cereți proprietarului drepturi de editare pentru a-l modifica.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Partajat cu dumneavoastră doar pentru vizualizare. Nu s-a salvat nimic; cereți proprietarului drepturi de editare pentru a-l modifica.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "O organizație parteneră cu care este partajat acest secret nu poate fi contactată ({partners}). Refaceți modificarea online, unde puteți salva fără ei.", "Save without them": "Salvați fără ei", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Salvat. Destinatarii din organizațiile partenere vor primi această modificare când proprietarul va salva din nou acest secret.", diff --git a/l10n/ru.js b/l10n/ru.js index ed87e8181..ef875f0f5 100644 --- a/l10n/ru.js +++ b/l10n/ru.js @@ -4,6 +4,8 @@ OC.L10N.register( "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Этот секрет доступен многим партнёрским организациям, поэтому сохранение ждёт снятия лимита запросов и затем продолжится. Не закрывайте это окно.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Слишком много запросов к партнёрским организациям. Ничего не сохранено; попробуйте ещё раз через минуту.", "This version cannot be restored to this secret. Nothing was saved.": "Эту версию нельзя восстановить для этого секрета. Ничего не сохранено.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Предоставлено вам только для просмотра. Чтобы изменить, попросите владельца дать права на редактирование.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Предоставлено вам только для просмотра. Ничего не сохранено; чтобы изменить, попросите владельца дать права на редактирование.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Партнёрская организация, с которой поделён этот секрет, недоступна ({partners}). Повторите изменение в сети, где можно сохранить без неё.", "Save without them": "Сохранить без них", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Сохранено. Получатели в партнёрских организациях получат это изменение, когда владелец в следующий раз сохранит этот секрет.", diff --git a/l10n/ru.json b/l10n/ru.json index ed4ea1031..4ac2e703d 100644 --- a/l10n/ru.json +++ b/l10n/ru.json @@ -3,6 +3,8 @@ "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Этот секрет доступен многим партнёрским организациям, поэтому сохранение ждёт снятия лимита запросов и затем продолжится. Не закрывайте это окно.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Слишком много запросов к партнёрским организациям. Ничего не сохранено; попробуйте ещё раз через минуту.", "This version cannot be restored to this secret. Nothing was saved.": "Эту версию нельзя восстановить для этого секрета. Ничего не сохранено.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Предоставлено вам только для просмотра. Чтобы изменить, попросите владельца дать права на редактирование.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Предоставлено вам только для просмотра. Ничего не сохранено; чтобы изменить, попросите владельца дать права на редактирование.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Партнёрская организация, с которой поделён этот секрет, недоступна ({partners}). Повторите изменение в сети, где можно сохранить без неё.", "Save without them": "Сохранить без них", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Сохранено. Получатели в партнёрских организациях получат это изменение, когда владелец в следующий раз сохранит этот секрет.", diff --git a/l10n/sk.js b/l10n/sk.js index aa1ebb16a..11dcc8a38 100644 --- a/l10n/sk.js +++ b/l10n/sk.js @@ -4,6 +4,8 @@ OC.L10N.register( "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Toto tajomstvo je zdieľané s mnohými partnerskými organizáciami, preto ukladanie čaká na limit dopytov a potom pokračuje. Nechajte toto okno otvorené.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Príliš veľa dopytov na partnerské organizácie. Nič sa neuložilo; skúste to znova o minútu.", "This version cannot be restored to this secret. Nothing was saved.": "Túto verziu nemožno obnoviť pre toto tajomstvo. Nič sa neuložilo.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Zdieľané s vami len na zobrazenie. Ak ho chcete zmeniť, požiadajte vlastníka o oprávnenie na úpravy.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Zdieľané s vami len na zobrazenie. Nič sa neuložilo; ak ho chcete zmeniť, požiadajte vlastníka o oprávnenie na úpravy.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Partnerská organizácia, s ktorou je toto tajomstvo zdieľané, nie je dostupná ({partners}). Urobte zmenu znova online, kde ju môžete uložiť bez nej.", "Save without them": "Uložiť bez nich", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Uložené. Príjemcovia v partnerských organizáciách dostanú túto zmenu, keď vlastník nabudúce uloží toto tajomstvo.", diff --git a/l10n/sk.json b/l10n/sk.json index 78cdadcc2..0779b5ab6 100644 --- a/l10n/sk.json +++ b/l10n/sk.json @@ -3,6 +3,8 @@ "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Toto tajomstvo je zdieľané s mnohými partnerskými organizáciami, preto ukladanie čaká na limit dopytov a potom pokračuje. Nechajte toto okno otvorené.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Príliš veľa dopytov na partnerské organizácie. Nič sa neuložilo; skúste to znova o minútu.", "This version cannot be restored to this secret. Nothing was saved.": "Túto verziu nemožno obnoviť pre toto tajomstvo. Nič sa neuložilo.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Zdieľané s vami len na zobrazenie. Ak ho chcete zmeniť, požiadajte vlastníka o oprávnenie na úpravy.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Zdieľané s vami len na zobrazenie. Nič sa neuložilo; ak ho chcete zmeniť, požiadajte vlastníka o oprávnenie na úpravy.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Partnerská organizácia, s ktorou je toto tajomstvo zdieľané, nie je dostupná ({partners}). Urobte zmenu znova online, kde ju môžete uložiť bez nej.", "Save without them": "Uložiť bez nich", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Uložené. Príjemcovia v partnerských organizáciách dostanú túto zmenu, keď vlastník nabudúce uloží toto tajomstvo.", diff --git a/l10n/sl.js b/l10n/sl.js index 74697cf37..bd7c85d9e 100644 --- a/l10n/sl.js +++ b/l10n/sl.js @@ -4,6 +4,8 @@ OC.L10N.register( "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Ta skrivnost je deljena z mnogimi partnerskimi organizacijami, zato shranjevanje čaka na omejitev poizvedb in se nato nadaljuje. Pustite to okno odprto.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Preveč poizvedb pri partnerskih organizacijah. Nič ni bilo shranjeno; poskusite znova čez minuto.", "This version cannot be restored to this secret. Nothing was saved.": "Te različice ni mogoče obnoviti za to skrivnost. Nič ni bilo shranjeno.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Deljeno z vami samo za ogled. Če jo želite spremeniti, prosite lastnika za pravice urejanja.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Deljeno z vami samo za ogled. Nič ni bilo shranjeno; če jo želite spremeniti, prosite lastnika za pravice urejanja.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Partnerska organizacija, s katero je deljena ta skrivnost, ni dosegljiva ({partners}). Spremembo ponovite na spletu, kjer lahko shranite brez njih.", "Save without them": "Shrani brez njih", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Shranjeno. Prejemniki v partnerskih organizacijah bodo to spremembo prejeli, ko bo lastnik naslednjič shranil to skrivnost.", diff --git a/l10n/sl.json b/l10n/sl.json index 9bfcc64f4..6b1cebd9c 100644 --- a/l10n/sl.json +++ b/l10n/sl.json @@ -3,6 +3,8 @@ "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Ta skrivnost je deljena z mnogimi partnerskimi organizacijami, zato shranjevanje čaka na omejitev poizvedb in se nato nadaljuje. Pustite to okno odprto.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Preveč poizvedb pri partnerskih organizacijah. Nič ni bilo shranjeno; poskusite znova čez minuto.", "This version cannot be restored to this secret. Nothing was saved.": "Te različice ni mogoče obnoviti za to skrivnost. Nič ni bilo shranjeno.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Deljeno z vami samo za ogled. Če jo želite spremeniti, prosite lastnika za pravice urejanja.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Deljeno z vami samo za ogled. Nič ni bilo shranjeno; če jo želite spremeniti, prosite lastnika za pravice urejanja.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Partnerska organizacija, s katero je deljena ta skrivnost, ni dosegljiva ({partners}). Spremembo ponovite na spletu, kjer lahko shranite brez njih.", "Save without them": "Shrani brez njih", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Shranjeno. Prejemniki v partnerskih organizacijah bodo to spremembo prejeli, ko bo lastnik naslednjič shranil to skrivnost.", diff --git a/l10n/sq.js b/l10n/sq.js index 6a0b4f784..9bd6c8550 100644 --- a/l10n/sq.js +++ b/l10n/sq.js @@ -4,6 +4,8 @@ OC.L10N.register( "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Ky sekret është ndarë me shumë organizata partnere, prandaj ruajtja po pret kufirin e kërkimeve dhe pastaj vazhdon. Mbajeni këtë dritare të hapur.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Shumë kërkime te organizatat partnere. Asgjë nuk u ruajt; provoni përsëri pas një minute.", "This version cannot be restored to this secret. Nothing was saved.": "Ky version nuk mund të rikthehet për këtë sekret. Asgjë nuk u ruajt.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Ndarë me ju vetëm për shikim. Kërkojini pronarit të drejta redaktimi për ta ndryshuar.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Ndarë me ju vetëm për shikim. Asgjë nuk u ruajt; kërkojini pronarit të drejta redaktimi për ta ndryshuar.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Një organizatë partnere me të cilën ndahet ky sekret nuk mund të arrihet ({partners}). Bëjeni sërish ndryshimin në linjë, ku mund ta ruani pa ata.", "Save without them": "Ruaje pa ata", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "U ruajt. Marrësit në organizatat partnere do ta marrin këtë ndryshim kur pronari ta ruajë herën tjetër këtë sekret.", diff --git a/l10n/sq.json b/l10n/sq.json index 06067ec4a..ac6068c24 100644 --- a/l10n/sq.json +++ b/l10n/sq.json @@ -3,6 +3,8 @@ "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Ky sekret është ndarë me shumë organizata partnere, prandaj ruajtja po pret kufirin e kërkimeve dhe pastaj vazhdon. Mbajeni këtë dritare të hapur.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Shumë kërkime te organizatat partnere. Asgjë nuk u ruajt; provoni përsëri pas një minute.", "This version cannot be restored to this secret. Nothing was saved.": "Ky version nuk mund të rikthehet për këtë sekret. Asgjë nuk u ruajt.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Ndarë me ju vetëm për shikim. Kërkojini pronarit të drejta redaktimi për ta ndryshuar.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Ndarë me ju vetëm për shikim. Asgjë nuk u ruajt; kërkojini pronarit të drejta redaktimi për ta ndryshuar.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Një organizatë partnere me të cilën ndahet ky sekret nuk mund të arrihet ({partners}). Bëjeni sërish ndryshimin në linjë, ku mund ta ruani pa ata.", "Save without them": "Ruaje pa ata", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "U ruajt. Marrësit në organizatat partnere do ta marrin këtë ndryshim kur pronari ta ruajë herën tjetër këtë sekret.", diff --git a/l10n/sr.js b/l10n/sr.js index 4d02c3050..6c613fdb4 100644 --- a/l10n/sr.js +++ b/l10n/sr.js @@ -4,6 +4,8 @@ OC.L10N.register( "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Ова тајна је дељена са много партнерских организација, па чување чека ограничење упита и затим се наставља. Не затварајте овај прозор.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Превише упита партнерским организацијама. Ништа није сачувано; покушајте поново за минут.", "This version cannot be restored to this secret. Nothing was saved.": "Ова верзија не може да се врати за ову тајну. Ништа није сачувано.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Подељено са вама само за преглед. Затражите од власника права уређивања да бисте је променили.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Подељено са вама само за преглед. Ништа није сачувано; затражите од власника права уређивања да бисте је променили.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Партнерска организација са којом се дели ова тајна није доступна ({partners}). Поновите измену на мрежи, где можете да сачувате без њих.", "Save without them": "Сачувај без њих", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Сачувано. Примаоци у партнерским организацијама добиће ову измену када власник следећи пут сачува ову тајну.", diff --git a/l10n/sr.json b/l10n/sr.json index ac21a4fff..f7031d3e1 100644 --- a/l10n/sr.json +++ b/l10n/sr.json @@ -3,6 +3,8 @@ "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Ова тајна је дељена са много партнерских организација, па чување чека ограничење упита и затим се наставља. Не затварајте овај прозор.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Превише упита партнерским организацијама. Ништа није сачувано; покушајте поново за минут.", "This version cannot be restored to this secret. Nothing was saved.": "Ова верзија не може да се врати за ову тајну. Ништа није сачувано.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Подељено са вама само за преглед. Затражите од власника права уређивања да бисте је променили.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Подељено са вама само за преглед. Ништа није сачувано; затражите од власника права уређивања да бисте је променили.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Партнерска организација са којом се дели ова тајна није доступна ({partners}). Поновите измену на мрежи, где можете да сачувате без њих.", "Save without them": "Сачувај без њих", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Сачувано. Примаоци у партнерским организацијама добиће ову измену када власник следећи пут сачува ову тајну.", diff --git a/l10n/sv.js b/l10n/sv.js index ca9a0f939..7228ae880 100644 --- a/l10n/sv.js +++ b/l10n/sv.js @@ -4,6 +4,8 @@ OC.L10N.register( "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Den här hemligheten delas med många partnerorganisationer, så sparandet väntar på uppslagsgränsen och fortsätter sedan. Håll den här dialogen öppen.", "Too many partner lookups. Nothing was saved; try again in a minute.": "För många uppslag hos partnerorganisationer. Inget sparades; försök igen om en minut.", "This version cannot be restored to this secret. Nothing was saved.": "Den här versionen kan inte återställas för den här hemligheten. Inget sparades.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Delad med dig endast för visning. Be ägaren om redigeringsrättigheter för att ändra den.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Delad med dig endast för visning. Inget sparades; be ägaren om redigeringsrättigheter för att ändra den.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "En partnerorganisation som den här hemligheten delas med kan inte nås ({partners}). Gör om ändringen online, där du kan spara utan dem.", "Save without them": "Spara utan dem", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Sparat. Mottagare i partnerorganisationer får ändringen nästa gång ägaren sparar den här hemligheten.", diff --git a/l10n/sv.json b/l10n/sv.json index 6736d9eed..93dd2b4f5 100644 --- a/l10n/sv.json +++ b/l10n/sv.json @@ -3,6 +3,8 @@ "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Den här hemligheten delas med många partnerorganisationer, så sparandet väntar på uppslagsgränsen och fortsätter sedan. Håll den här dialogen öppen.", "Too many partner lookups. Nothing was saved; try again in a minute.": "För många uppslag hos partnerorganisationer. Inget sparades; försök igen om en minut.", "This version cannot be restored to this secret. Nothing was saved.": "Den här versionen kan inte återställas för den här hemligheten. Inget sparades.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Delad med dig endast för visning. Be ägaren om redigeringsrättigheter för att ändra den.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Delad med dig endast för visning. Inget sparades; be ägaren om redigeringsrättigheter för att ändra den.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "En partnerorganisation som den här hemligheten delas med kan inte nås ({partners}). Gör om ändringen online, där du kan spara utan dem.", "Save without them": "Spara utan dem", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Sparat. Mottagare i partnerorganisationer får ändringen nästa gång ägaren sparar den här hemligheten.", diff --git a/l10n/tr.js b/l10n/tr.js index 5fea5a1c6..60444f94f 100644 --- a/l10n/tr.js +++ b/l10n/tr.js @@ -4,6 +4,8 @@ OC.L10N.register( "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Bu sır birçok ortak kuruluşla paylaşılıyor, bu yüzden kaydetme sorgu sınırını bekliyor ve ardından devam ediyor. Bu pencereyi açık tutun.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Ortak kuruluşlara çok fazla sorgu yapıldı. Hiçbir şey kaydedilmedi; bir dakika sonra tekrar deneyin.", "This version cannot be restored to this secret. Nothing was saved.": "Bu sürüm bu gizliye geri yüklenemez. Hiçbir şey kaydedilmedi.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Sizinle yalnızca görüntülemeniz için paylaşıldı. Değiştirmek için sahibinden düzenleme izni isteyin.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Sizinle yalnızca görüntülemeniz için paylaşıldı. Hiçbir şey kaydedilmedi; değiştirmek için sahibinden düzenleme izni isteyin.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Bu gizlinin paylaşıldığı bir ortak kuruluşa ulaşılamıyor ({partners}). Değişikliği çevrimiçiyken yeniden yapın; orada onlar olmadan kaydedebilirsiniz.", "Save without them": "Onlar olmadan kaydet", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Kaydedildi. Ortak kuruluşlardaki alıcılar, sahip bu gizliyi bir sonraki kaydedişinde bu değişikliği alır.", diff --git a/l10n/tr.json b/l10n/tr.json index ee979fdaa..4da7c3d94 100644 --- a/l10n/tr.json +++ b/l10n/tr.json @@ -3,6 +3,8 @@ "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Bu sır birçok ortak kuruluşla paylaşılıyor, bu yüzden kaydetme sorgu sınırını bekliyor ve ardından devam ediyor. Bu pencereyi açık tutun.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Ortak kuruluşlara çok fazla sorgu yapıldı. Hiçbir şey kaydedilmedi; bir dakika sonra tekrar deneyin.", "This version cannot be restored to this secret. Nothing was saved.": "Bu sürüm bu gizliye geri yüklenemez. Hiçbir şey kaydedilmedi.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Sizinle yalnızca görüntülemeniz için paylaşıldı. Değiştirmek için sahibinden düzenleme izni isteyin.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Sizinle yalnızca görüntülemeniz için paylaşıldı. Hiçbir şey kaydedilmedi; değiştirmek için sahibinden düzenleme izni isteyin.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Bu gizlinin paylaşıldığı bir ortak kuruluşa ulaşılamıyor ({partners}). Değişikliği çevrimiçiyken yeniden yapın; orada onlar olmadan kaydedebilirsiniz.", "Save without them": "Onlar olmadan kaydet", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Kaydedildi. Ortak kuruluşlardaki alıcılar, sahip bu gizliyi bir sonraki kaydedişinde bu değişikliği alır.", diff --git a/l10n/uk.js b/l10n/uk.js index 7c0d2803c..a24b6b56a 100644 --- a/l10n/uk.js +++ b/l10n/uk.js @@ -4,6 +4,8 @@ OC.L10N.register( "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Цей секрет спільний із багатьма партнерськими організаціями, тому збереження чекає на ліміт запитів і потім продовжиться. Не закривайте це вікно.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Забагато запитів до партнерських організацій. Нічого не збережено; спробуйте ще раз за хвилину.", "This version cannot be restored to this secret. Nothing was saved.": "Цю версію не можна відновити для цього секрету. Нічого не збережено.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Надано вам лише для перегляду. Щоб змінити, попросіть власника надати права на редагування.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Надано вам лише для перегляду. Нічого не збережено; щоб змінити, попросіть власника надати права на редагування.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Партнерська організація, з якою поділено цей секрет, недоступна ({partners}). Повторіть зміну онлайн, де можна зберегти без неї.", "Save without them": "Зберегти без них", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Збережено. Одержувачі в партнерських організаціях отримають цю зміну, коли власник наступного разу збереже цей секрет.", diff --git a/l10n/uk.json b/l10n/uk.json index 7101677b2..2cc7304cf 100644 --- a/l10n/uk.json +++ b/l10n/uk.json @@ -3,6 +3,8 @@ "This secret is shared with many partner organisations, so the save is waiting for the lookup limit and then continues. Keep this dialog open.": "Цей секрет спільний із багатьма партнерськими організаціями, тому збереження чекає на ліміт запитів і потім продовжиться. Не закривайте це вікно.", "Too many partner lookups. Nothing was saved; try again in a minute.": "Забагато запитів до партнерських організацій. Нічого не збережено; спробуйте ще раз за хвилину.", "This version cannot be restored to this secret. Nothing was saved.": "Цю версію не можна відновити для цього секрету. Нічого не збережено.", + "Shared with you to view only. Ask its owner for edit rights to change it.": "Надано вам лише для перегляду. Щоб змінити, попросіть власника надати права на редагування.", + "Shared with you to view only. Nothing was saved; ask its owner for edit rights to change it.": "Надано вам лише для перегляду. Нічого не збережено; щоб змінити, попросіть власника надати права на редагування.", "A partner organisation this secret is shared with cannot be reached ({partners}). Make the change again online, where you can save without them.": "Партнерська організація, з якою поділено цей секрет, недоступна ({partners}). Повторіть зміну онлайн, де можна зберегти без неї.", "Save without them": "Зберегти без них", "Saved. Recipients at partner organisations get this change when the owner next saves this secret.": "Збережено. Одержувачі в партнерських організаціях отримають цю зміну, коли власник наступного разу збереже цей секрет.", diff --git a/lib/Controller/SecretRequestFillController.php b/lib/Controller/SecretRequestFillController.php index 66e5f8314..21a16b02f 100644 --- a/lib/Controller/SecretRequestFillController.php +++ b/lib/Controller/SecretRequestFillController.php @@ -32,6 +32,8 @@ use InvalidArgumentException; use OCA\Keepiq\AppInfo\Application; +use OCA\Keepiq\Exception\ForbiddenException; +use OCA\Keepiq\Exception\NotFoundException; use OCA\Keepiq\Service\EncryptionSuiteService; use OCA\Keepiq\Service\SecretRequestService; use OCP\AppFramework\Http; @@ -190,6 +192,13 @@ public function fill( data: ['message' => $e->getMessage()], statusCode: $status ); + } catch (ForbiddenException|NotFoundException) { + // The refusal speaks to the secret's holder; the filler gets its + // outcome only. The request stays pending. + return new JSONResponse( + data: ['message' => 'The secret this request writes to cannot be changed'], + statusCode: Http::STATUS_FORBIDDEN + ); } catch (Throwable) { return new JSONResponse( data: ['message' => 'Unable to fulfil request'], diff --git a/lib/Controller/SecretVersionController.php b/lib/Controller/SecretVersionController.php index e2f126ca3..443dcb064 100644 --- a/lib/Controller/SecretVersionController.php +++ b/lib/Controller/SecretVersionController.php @@ -27,6 +27,8 @@ use InvalidArgumentException; use OCA\Keepiq\AppInfo\Application; +use OCA\Keepiq\Exception\ForbiddenException; +use OCA\Keepiq\Exception\NotFoundException; use OCA\Keepiq\Exception\StaleWriteException; use OCA\Keepiq\Service\SecretVersionService; use OCP\AppFramework\Http; @@ -126,8 +128,8 @@ public function show(string $id): JSONResponse { /** * Restore a version onto this one row. The web app restores through - * share-save (`restoredFrom`) and uses this route only for a copy holder - * without a write grade, whose restore changes their own copy alone. + * share-save (`restoredFrom`). A copy whose holder may not write its + * source is view-only and its restore is refused. * * @param string $id The version UUID * @param string|null $baseUpdatedAt The head version the restore was chosen on @@ -153,12 +155,24 @@ public function restore(string $id, ?string $baseUpdatedAt = null): JSONResponse data: ['message' => $exception->getMessage(), 'current' => $exception->getCurrent()->jsonSerialize()], statusCode: Http::STATUS_CONFLICT ); + } catch (ForbiddenException $exception) { + $body = ['message' => $exception->getMessage()]; + if ($exception->policyCode() !== null) { + $body['code'] = $exception->policyCode(); + } + + return new JSONResponse(data: $body, statusCode: Http::STATUS_FORBIDDEN); + } catch (NotFoundException $exception) { + return new JSONResponse( + data: ['message' => $exception->getMessage()], + statusCode: Http::STATUS_NOT_FOUND + ); } catch (InvalidArgumentException $exception) { return new JSONResponse( data: ['message' => $exception->getMessage()], statusCode: Http::STATUS_BAD_REQUEST ); - } + }//end try return new JSONResponse(data: $secret->jsonSerialize()); }//end restore() diff --git a/lib/Db/Secret.php b/lib/Db/Secret.php index 68fd09396..e1eb04951 100644 --- a/lib/Db/Secret.php +++ b/lib/Db/Secret.php @@ -112,6 +112,14 @@ class Secret extends Entity implements JsonSerializable { */ public const READ_ONLY_REFUSAL = 'A copy from another organisation is read-only'; + /** + * What a value change of a copy answers when its holder may not write + * the source (keepiq#1287). + * + * @var string + */ + public const VIEW_ONLY_REFUSAL = 'Shared with you to view only. Ask its owner for edit rights to change it.'; + /** * What the holder of a read-only copy may still change: where it is filed * (sharing-federated-recipients task 3.5). `baseUpdatedAt` only names the diff --git a/lib/Exception/ViewOnlyCopyException.php b/lib/Exception/ViewOnlyCopyException.php new file mode 100644 index 000000000..f550f59f3 --- /dev/null +++ b/lib/Exception/ViewOnlyCopyException.php @@ -0,0 +1,60 @@ + + * @copyright 2026 Conduction B.V. + * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * @version GIT: + * + * @link https://conduction.nl + */ + +declare(strict_types=1); + +namespace OCA\Keepiq\Exception; + +use OCA\Keepiq\Db\Secret; + +/** + * Thrown when the holder of a view-only copy changes its value. + * + * @spec openspec/specs/user-sharing/spec.md#requirement-view-only-copies + */ +class ViewOnlyCopyException extends ForbiddenException { + /** + * The machine-readable code the refusal carries. + */ + public const CODE = 'view_only'; + + /** + * Constructor. + * + * @return void + * + * @spec openspec/specs/user-sharing/spec.md#requirement-view-only-copies + */ + public function __construct() { + parent::__construct(message: Secret::VIEW_ONLY_REFUSAL); + }//end __construct() + + /** + * The code `view_only`. + * + * @return string|null + * + * @spec openspec/specs/user-sharing/spec.md#requirement-view-only-copies + */ + public function policyCode(): ?string { + return self::CODE; + }//end policyCode() +}//end class diff --git a/lib/Service/SecretRequestService.php b/lib/Service/SecretRequestService.php index 6faee6da1..fc4e89668 100644 --- a/lib/Service/SecretRequestService.php +++ b/lib/Service/SecretRequestService.php @@ -81,6 +81,7 @@ class SecretRequestService { * @param SecretMapper $secretMapper Reads the Secret a request writes to * @param ContainerInterface $container Resolves SecretService lazily (see fill) * @param SecretPlaceholderCleaner $placeholderCleaner Removes an unfilled placeholder + * @param ViewOnlyCopyGuard $viewOnlyCopies Refuses a fill onto a copy its holder may not write * * @return void */ @@ -93,6 +94,7 @@ public function __construct( private SecretMapper $secretMapper, private ContainerInterface $container, private SecretPlaceholderCleaner $placeholderCleaner, + private ViewOnlyCopyGuard $viewOnlyCopies, ) { }//end __construct() @@ -160,6 +162,8 @@ public function refusalReason(string $token): string { * @return SecretRequest * * @throws InvalidArgumentException + * @throws \OCA\Keepiq\Exception\ForbiddenException When the secret's holder may not change it, as with a copy shared with them to view only + * @throws \OCA\Keepiq\Exception\NotFoundException When the secret is a copy whose source cannot be resolved, or is gone by the write * * @spec openspec/changes/add-secret-audit-trail/tasks.md#task-3.5 */ @@ -311,6 +315,8 @@ private function persistFilledValues( * @return void * * @throws InvalidArgumentException With code 409 when the row moved twice during the fill + * @throws \OCA\Keepiq\Exception\ForbiddenException When the owner may not change the secret, as with a copy shared with them to view only + * @throws \OCA\Keepiq\Exception\NotFoundException When the secret is a copy whose source cannot be resolved, or is gone by the write * * @spec openspec/specs/secret-requests/spec.md#requirement-requestable-fields * @spec openspec/specs/offline-edit-queue/spec.md#requirement-concurrent-server-changes-are-never-overwritten-silently @@ -328,6 +334,10 @@ private function writeFilledValues(Secret $secret, array $data): void { return; } + // Before the hold-back: it stores a filled extra-field blob on its own, + // and that is a value change too. + $this->viewOnlyCopies->assertMayChangeValue(row: $secret, fields: array_keys($data), userId: $secret->getOwnerId()); + $data = $this->holdBackAdditionalFields(secret: $secret, data: $data); if ($data === []) { return; diff --git a/lib/Service/SecretService.php b/lib/Service/SecretService.php index 889b1108d..dafe8ed78 100644 --- a/lib/Service/SecretService.php +++ b/lib/Service/SecretService.php @@ -142,6 +142,7 @@ class SecretService { * @param LinkShareService $linkShareService The link share service (cascade delete) * @param LoggerInterface $logger The logger interface * @param IDBConnection $db The transaction an update's version lock runs in + * @param ViewOnlyCopyGuard $viewOnlyCopies Refuses a value change of a copy its holder may not write * @param SecretRequestService|null $secretRequestService The secret-request service * @param ShareService|null $shareService The share service * @param GroupShareMapper|null $groupShareMapper The group-share mapper @@ -170,6 +171,7 @@ public function __construct( private LinkShareService $linkShareService, private LoggerInterface $logger, private IDBConnection $db, + private ViewOnlyCopyGuard $viewOnlyCopies, private ?SecretRequestService $secretRequestService = null, private ?ShareService $shareService = null, private ?GroupShareMapper $groupShareMapper = null, @@ -906,7 +908,7 @@ private function requireFolderOwnedBy(?string $folderId, string $userId): void { * @return Secret * * @throws NotFoundException When the secret does not exist - * @throws ForbiddenException When the secret belongs to another user + * @throws ForbiddenException When the secret belongs to another user, or its value changes on a copy its holder may only view * @throws WriteLockedException When a compromise-recovery migration is in progress * @throws InvalidArgumentException When a provided field is invalid * @throws StaleWriteException When `baseUpdatedAt` names an older version, or the row moved on after it was read @@ -926,6 +928,11 @@ private function requireFolderOwnedBy(?string $folderId, string $userId): void { */ public function update(string $id, array $data, string $userId, ?DateTime $savedAt = null): Secret { $secret = $this->loadForUpdate(id: $id, fields: array_keys($data), userId: $userId); + $this->viewOnlyCopies->assertMayChangeValue( + row: $secret, + fields: $this->changedValueFields(secret: $secret, data: $data), + userId: $userId + ); // The write is locked against the version just read, whether or not // the client named one; the check below compares a named one. A @@ -1531,6 +1538,42 @@ public function loadForUpdate(string $id, array $fields, string $userId): Secret return $this->loadOwned(id: $id, userId: $userId)->assertEditableByHolder(fields: $fields); }//end loadForUpdate() + /** + * The value fields an update writes with a value other than the stored + * one, compared as update() stores them. Resending the stored ciphertext + * changes nothing, so it does not count. + * + * @param Secret $secret The row as loaded + * @param array $data The update data + * + * @return string[] + */ + private function changedValueFields(Secret $secret, array $data): array { + $stored = [ + 'key' => $secret->getKey(), + 'login' => $secret->getLogin(), + 'additionalFields' => $secret->getAdditionalFields(), + ]; + + $changed = []; + foreach ($stored as $field => $value) { + if (array_key_exists($field, $data) === false) { + continue; + } + + $new = $this->nullableString(value: $data[$field]); + if ($field === 'key') { + $new = (string)$data[$field]; + } + + if ($new !== $value) { + $changed[] = $field; + } + } + + return $changed; + }//end changedValueFields() + /** * Assert the user has an active encryption suite, or block. * diff --git a/lib/Service/SecretVersionService.php b/lib/Service/SecretVersionService.php index 883acfc83..06482ad4a 100644 --- a/lib/Service/SecretVersionService.php +++ b/lib/Service/SecretVersionService.php @@ -7,8 +7,8 @@ * pre-update snapshots (ciphertext copied verbatim — never decrypted), * metadata listing, blob reads gated exactly like head reads, and restore * (snapshot the current head first, then set the head to the selected - * version). restore() changes one row only; the web app restores through - * share-save and calls it only for a copy holder without a write grade. + * version). restore() changes one row only and refuses a copy its holder + * may only view; the web app restores through share-save. * * @category Service * @package OCA\Keepiq\Service @@ -63,6 +63,7 @@ class SecretVersionService { * @param SecretVersionAccessGuard $accessGuard The read-authorization guard * @param LoggerInterface $logger The logger * @param IDBConnection $db The restore's transaction + * @param ViewOnlyCopyGuard $viewOnlyCopies Refuses a restore of a copy its holder may not write * @param IEventDispatcher|null $eventDispatcher The audit event dispatcher * @param AuditEventFactory $auditEvents The audit-event factory * @param OfflineEditGuard $editGuard Refuses a restore over a head that moved on @@ -75,6 +76,7 @@ public function __construct( private SecretVersionAccessGuard $accessGuard, private LoggerInterface $logger, private IDBConnection $db, + private ViewOnlyCopyGuard $viewOnlyCopies, private ?IEventDispatcher $eventDispatcher = null, private AuditEventFactory $auditEvents = new AuditEventFactory(), private OfflineEditGuard $editGuard = new OfflineEditGuard(), @@ -212,6 +214,8 @@ public function getVersion(string $versionId, string $userId): SecretVersion { * @return Secret The updated head * * @throws \InvalidArgumentException On not found / not owned / suite blocked / a malformed base + * @throws \OCA\Keepiq\Exception\ForbiddenException When the head is a copy its holder may only view + * @throws \OCA\Keepiq\Exception\NotFoundException When the head is a copy whose source cannot be resolved * @throws StaleWriteException When the head moved on from `$baseUpdatedAt`, or from the version read * * @spec openspec/specs/secret-version-history/spec.md#requirement-list-view-and-restore-versions @@ -220,6 +224,11 @@ public function getVersion(string $versionId, string $userId): SecretVersion { public function restore(string $versionId, string $userId, ?string $baseUpdatedAt = null): Secret { $version = $this->getVersion(versionId: $versionId, userId: $userId); $secret = $this->reload(id: $version->getSecretId()); + $this->viewOnlyCopies->assertMayChangeValue( + row: $secret, + fields: ViewOnlyCopyGuard::VALUE_FIELDS, + userId: $userId + ); $this->editGuard->assertUnchangedSince(secret: $secret, baseUpdatedAt: $baseUpdatedAt); $restored = $this->atomic( diff --git a/lib/Service/ShareSyncService.php b/lib/Service/ShareSyncService.php index 4653e7792..7723e531f 100644 --- a/lib/Service/ShareSyncService.php +++ b/lib/Service/ShareSyncService.php @@ -34,14 +34,20 @@ use OCA\Keepiq\Db\Secret; use OCA\Keepiq\Db\SecretMapper; use OCA\Keepiq\Db\ShareTargetMapper; +use OCA\Keepiq\Exception\ForbiddenException; use OCA\Keepiq\Service\ShareSync\ShareSyncGuards; use OCA\Keepiq\Service\ShareSync\ShareWriteContext; use OCP\AppFramework\Db\DoesNotExistException; +use OCP\AppFramework\Db\MultipleObjectsReturnedException; use OCP\AppFramework\Db\TTransactional; use OCP\IDBConnection; /** * Pushes an updated encrypted blob to every recipient of a secret. + * + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) 14 against a threshold of 13: + * telling a source from a received copy takes both outcomes of the share-row + * lookup and a refusal of its own. */ class ShareSyncService { use TTransactional; @@ -120,8 +126,10 @@ public function __construct( * @return int Number of recipient copies updated. * * @throws InvalidArgumentException When validation or optimistic-lock check fails + * @throws ForbiddenException When the secret is a read-only copy or a received copy * * @spec openspec/specs/user-sharing/spec.md#requirement-sync-on-update + * @spec openspec/specs/user-sharing/spec.md#requirement-view-only-copies * @spec openspec/specs/use-only-shares/spec.md#requirement-the-server-refuses-what-it-can-enforce * @spec openspec/specs/folder-permission-grades/spec.md#requirement-grade-changes-and-non-owner-writes-are-audited */ @@ -133,6 +141,7 @@ public function syncUpdate( ): int { $source = $this->auth->loadSecret(secretId: $secretId); $this->guards->assertWritable(source: $source); + $this->assertNotACopy(secret: $source); $writesOn = $this->resolveSyncWriter(source: $source, userId: $userId); $this->guards->assertBaseNamed(writesOn: $writesOn, expectedUpdatedAt: $expectedUpdatedAt); @@ -170,6 +179,31 @@ public function syncUpdate( ); }//end syncUpdate() + /** + * Refuse a sync that starts from a received copy. A copy is owned by its + * holder, so the owner check would pass and the sync would write that copy + * alone, whether or not the holder may write its source. + * + * @param Secret $secret The secret the sync names + * + * @return void + * + * @throws ForbiddenException When the secret is a received copy + * + * @spec openspec/specs/user-sharing/spec.md#requirement-view-only-copies + */ + private function assertNotACopy(Secret $secret): void { + try { + $this->mapper->findByRecipientSecret(recipientSecretId: $secret->getId()); + } catch (DoesNotExistException) { + return; + } catch (MultipleObjectsReturnedException) { + // More than one share row: still a copy. + } + + throw new ForbiddenException(message: 'A sync starts from the source secret, not from a copy'); + }//end assertNotACopy() + /** * Attribute a sync by anyone but the owner to the writer on the source * (§3.3), as a share-save through a copy is: a team writer as diff --git a/lib/Service/ViewOnlyCopyGuard.php b/lib/Service/ViewOnlyCopyGuard.php new file mode 100644 index 000000000..843af6ce1 --- /dev/null +++ b/lib/Service/ViewOnlyCopyGuard.php @@ -0,0 +1,109 @@ + + * @copyright 2026 Conduction B.V. + * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * @version GIT: + * + * @link https://conduction.nl + */ + +declare(strict_types=1); + +namespace OCA\Keepiq\Service; + +use OCA\Keepiq\Db\Secret; +use OCA\Keepiq\Db\SecretMapper; +use OCA\Keepiq\Db\ShareTargetMapper; +use OCA\Keepiq\Exception\NotFoundException; +use OCA\Keepiq\Exception\ViewOnlyCopyException; +use OCA\Keepiq\Service\ShareSync\ShareWriteContext; +use OCP\AppFramework\Db\DoesNotExistException; +use OCP\AppFramework\Db\MultipleObjectsReturnedException; + +/** + * A copy is view-only for its holder unless they write its source for every + * copy, as ShareWriteContext::standingOn() decides it: as its owner or a + * delegate, on a team-folder write or manage grade, or as a member of a group + * it is shared with in full. This is the rule a sync is authorized on. + */ +class ViewOnlyCopyGuard { + /** + * The fields that hold a secret's value. + * + * @var string[] + */ + public const VALUE_FIELDS = ['key', 'login', 'additionalFields']; + + /** + * Constructor. + * + * @param ShareTargetMapper $targets The share targets (copy to source) + * @param SecretMapper $secrets The secrets + * @param ShareWriteContext $contexts The holder's standing on the source + * + * @return void + * + * @spec exclude Constructor wiring only. + */ + public function __construct( + private ShareTargetMapper $targets, + private SecretMapper $secrets, + private ShareWriteContext $contexts, + ) { + }//end __construct() + + /** + * Refuse a change of the value of a copy its holder may not write. + * A change that leaves the value alone, and a row that is not a copy, + * pass. + * + * @param Secret $row The holder's row, already checked to be theirs + * @param string[] $fields The fields the change writes + * @param string $userId The holder + * + * @return void + * + * @throws NotFoundException When the copy's share row or source cannot be resolved + * @throws ViewOnlyCopyException When the holder may not write the copy's source + * + * @spec openspec/specs/user-sharing/spec.md#requirement-view-only-copies + */ + public function assertMayChangeValue(Secret $row, array $fields, string $userId): void { + if (array_intersect(self::VALUE_FIELDS, $fields) === []) { + return; + } + + try { + $target = $this->targets->findByRecipientSecret(recipientSecretId: $row->getId()); + } catch (DoesNotExistException) { + return; + } catch (MultipleObjectsReturnedException) { + throw new NotFoundException(message: 'Secret not found'); + } + + try { + $source = $this->secrets->findById($target->getSourceSecretId()); + } catch (DoesNotExistException|MultipleObjectsReturnedException) { + throw new NotFoundException(message: 'Secret not found'); + } + + // Not through resolveSyncWriter(): the services this guards must not + // depend on the sync. + $standing = $this->contexts->standingOn(source: $source, userId: $userId); + if ($this->contexts->writesForEveryone(standing: $standing) === false) { + throw new ViewOnlyCopyException(); + } + }//end assertMayChangeValue() +}//end class diff --git a/openspec/changes/sharing-atomic-share-save/design.md b/openspec/changes/sharing-atomic-share-save/design.md index 4213ab923..f07ea8b84 100644 --- a/openspec/changes/sharing-atomic-share-save/design.md +++ b/openspec/changes/sharing-atomic-share-save/design.md @@ -5,7 +5,7 @@ At development `94ad83fa`: - `PUT /api/v1/secrets/{id}` (`SecretUpdateController`) saves the caller's own row and checks an optional `baseUpdatedAt`. -- `PUT /api/v1/secrets/{sourceSecretId}/sync` (`ShareSyncService::syncUpdate`) writes recipient copies in its own transaction; the caller is the owner, a delegate or a write-grade member (`resolveSyncWriter`). +- `PUT /api/v1/secrets/{sourceSecretId}/sync` (`ShareSyncService::syncUpdate`) writes recipient copies in its own transaction; the caller is the owner, a delegate or a write-grade member (`resolveSyncWriter`), and a sync that names a received copy instead of the source is refused (#1287). - `PUT /api/v1/federated-shares/{id}` (`FederatedShareService::update`) writes one partner share's ciphertext without a version check and notifies the partner through `FederatedNotificationDelivery`. - `POST /api/v1/shares/recipient-certificates` returns certificates for at most 100 users per call; `POST /api/v1/federation/recipient-certificate` returns a partner certificate that the browser verifies against the pinned root. @@ -22,7 +22,7 @@ At development `94ad83fa`: ## Decisions -**D1. `{id}` is always the caller's own row.** On the owner path it is the source; on the copy-editor path it is the caller's recipient copy, and the caller must be the owner, a delegate or hold a write or manage grade on the source. A copy holder without one keeps using `PUT /api/v1/secrets/{id}` for their own copy only. +**D1. `{id}` is always the caller's own row.** On the owner path it is the source; on the copy-editor path it is the caller's recipient copy, and the caller must be the owner, a delegate or hold a write or manage grade on the source. A copy holder without one holds a view-only copy (keepiq#1287): the browser refuses their share-save before sending anything, and `PUT /api/v1/secrets/{id}` refuses a value change of that copy with 428 `view_only`, so a view-only copy can't drift from its source. **D2. Compare-and-set inside the transaction.** The server advances `updated_at` with `UPDATE … WHERE id = :id AND updated_at = :base` and treats 0 affected rows as stale. On the copy-editor path the source is advanced first, so an owner save and a copy save of one secret queue up instead of deadlocking. The completeness check runs again under that lock. The new version is at least the base plus one second, because `updated_at` is stored in whole seconds. @@ -34,7 +34,7 @@ At development `94ad83fa`: **D6. Notify after commit, queued in the row.** Writing a partner share stores `SHARE_UPDATED` as its pending notification inside the transaction; after the commit the server delivers it, and `RetryFederatedNotificationsJob` picks up whatever a crash left behind. The stored notification is leased for 60 seconds, so the retry job doesn't send it again while the first send is still running. A share revoked meanwhile is never overwritten. -**D7. A restore is a share-save.** The browser decrypts the version and sends it as a full-value patch with `restoredFrom`, so the restored value reaches every copy in the same transaction, and the server records the restore audit event there. A copy holder without a write grade can only change their own copy, so they restore through `POST /api/v1/versions/{id}/restore`, which also records the restore and now takes an optional `baseUpdatedAt`. +**D7. A restore is a share-save.** The browser decrypts the version and sends it as a full-value patch with `restoredFrom`, so the restored value reaches every copy in the same transaction, and the server records the restore audit event there. A copy holder without a write grade can't restore: the web app offers no Restore on a view-only copy, and `POST /api/v1/versions/{id}/restore` refuses it with 428 `view_only`. That route changes one row only, records the restore and takes an optional `baseUpdatedAt`; the web app doesn't use it. ## Security and zero-knowledge diff --git a/openspec/changes/sharing-atomic-share-save/specs/folder-permission-grades/spec.md b/openspec/changes/sharing-atomic-share-save/specs/folder-permission-grades/spec.md index 868cfc1c0..535302a00 100644 --- a/openspec/changes/sharing-atomic-share-save/specs/folder-permission-grades/spec.md +++ b/openspec/changes/sharing-atomic-share-save/specs/folder-permission-grades/spec.md @@ -1,7 +1,7 @@ ## MODIFIED Requirements ### Requirement: A write-grade member may update a folder secret for all recipients -The system MUST allow a `write`-grade member to update a folder secret such that the change reaches the source and every local recipient in one share-save on the copy-editor path. The value MUST be re-encrypted under each holder's public certificate by the writer's client; the server MUST NOT decrypt, re-encrypt, or hold plaintext. Partner shares stay with the owner's next save. +The system MUST allow a `write`-grade member to update a folder secret such that the change reaches the source and every local recipient in one share-save on the copy-editor path. The value MUST be re-encrypted under each holder's public certificate by the writer's client; the server MUST NOT decrypt, re-encrypt, or hold plaintext. Partner shares stay with the owner's next save. A member whose effective grade is `read` holds a view-only copy (user-sharing, "View-Only Copies"): they MUST NOT change its value, neither for every holder nor for their own copy alone. #### Scenario: Write-grade member rotates a shared credential - GIVEN user W holds a `write` grade on a folder containing secret S shared to recipients R @@ -12,3 +12,8 @@ The system MUST allow a `write`-grade member to update a folder secret such that - GIVEN user V holds a `read` grade on a folder containing secret S - WHEN V attempts a value update that would propagate to recipients - THEN the system MUST reject the request and change no recipient's copy + +#### Scenario: Read-grade member cannot change their own copy +- GIVEN user V holds a `read` grade on a folder containing secret S +- WHEN V sends `PUT /api/v1/secrets/{id}` for their copy of S with a new value +- THEN the system MUST answer 428 with `error` `view_only` and leave V's copy unchanged diff --git a/openspec/changes/sharing-atomic-share-save/specs/offline-edit-queue/spec.md b/openspec/changes/sharing-atomic-share-save/specs/offline-edit-queue/spec.md index 45e9f94ed..8bb01ac66 100644 --- a/openspec/changes/sharing-atomic-share-save/specs/offline-edit-queue/spec.md +++ b/openspec/changes/sharing-atomic-share-save/specs/offline-edit-queue/spec.md @@ -25,13 +25,14 @@ When the administrator setting `offline_edits_enabled` is true and the vault is ### Requirement: Failed entries are kept, never dropped silently -A replay answered with 403 or 404, a share-save refused with 400, or a share-save stopped by an unreachable partner or by the partner lookup limit MUST move the entry to a failed list where the user can copy their values (decrypted in the browser) or discard the entry, with the reason shown next to it, also after a reload. An entry stopped by an unreachable partner or the lookup limit MUST also offer to try again. A 423 or a network error MUST keep the entry queued. A failed entry MUST NOT stop the replay of the entries after it. +A replay answered with 403 or 404, a share-save refused with 400, a share-save stopped by an unreachable partner or by the partner lookup limit, or a share-save of a copy the user may only view (user-sharing, "View-Only Copies") MUST move the entry to a failed list where the user can copy their values (decrypted in the browser) or discard the entry, with the reason shown next to it, also after a reload. Offline the web app doesn't know a copy's grade, so it lets the user edit any copy; the replay MUST refuse a value change of a view-only copy in the browser, before anything is sent. An entry stopped by an unreachable partner or the lookup limit MUST also offer to try again; one refused as view-only MUST NOT, as no retry can save it. A 423 or a network error MUST keep the entry queued. A failed entry MUST NOT stop the replay of the entries after it. #### Scenario: Write grade removed while offline - **GIVEN** a team-folder member who edited a folder secret offline, and whose grade was lowered to read meanwhile - **WHEN** the replay runs -- **THEN** the replay MUST save the change to the member's own copy only, since the queue doesn't know the grade the edit was made under, and MUST NOT write the source or any other copy +- **THEN** the replay MUST send nothing for the entry and write neither the member's copy, the source nor any other copy +- **AND** the entry MUST move to the failed list with the reason that the secret is shared with the member to view only, with copy and discard actions and without one to try again #### Scenario: A refused share-save is kept @@ -94,7 +95,7 @@ A queued update that changes a value, login or additional fields MUST be replaye - **GIVEN** a queued edit of a copy whose replay was refused with 409 `stale`, because the owner saved the secret meanwhile - **WHEN** the user keeps their change, before or after a reload - **THEN** the replay MUST send the copy version and the source version that 409 named, and save when neither has moved again -- **AND** when the copy was written after its source, such as by a plain update of the copy, the 409 names the source version the edit was made from, so keeping the change MAY first be refused with 409 `stale_source` and cost the user one more choice before it saves +- **AND** when the copy was written after its source, such as by a change of only its folder, the 409 names the source version the edit was made from, so keeping the change MAY first be refused with 409 `stale_source` and cost the user one more choice before it saves #### Scenario: A pending sync from before the change is finished diff --git a/openspec/changes/sharing-atomic-share-save/specs/secret-version-history/spec.md b/openspec/changes/sharing-atomic-share-save/specs/secret-version-history/spec.md index 0ba2b3991..0a8396efe 100644 --- a/openspec/changes/sharing-atomic-share-save/specs/secret-version-history/spec.md +++ b/openspec/changes/sharing-atomic-share-save/specs/secret-version-history/spec.md @@ -1,17 +1,22 @@ ## MODIFIED Requirements ### Requirement: List, view, and restore versions -The system MUST let a user list versions newest-first (metadata only), view a version via client-side decryption identical to a head read, and restore a version — creating a new head version and reaching every copy in the same share-save. +The system MUST let a user list versions newest-first (metadata only), view a version via client-side decryption identical to a head read, and restore a version — creating a new head version and reaching every copy in the same share-save. The holder of a view-only copy (user-sharing, "View-Only Copies") MAY list and view its versions but MUST NOT restore one: the web app MUST NOT offer Restore on it, and `POST /api/v1/versions/{id}/restore` MUST answer 428 with `error` `view_only` and change nothing. #### Scenario: Restore becomes a new head and syncs - GIVEN a secret shared with a recipient and a prior version `V` - WHEN the owner restores `V` - THEN the current head MUST first be snapshotted, the head MUST become `V`'s values, and the recipient's copy MUST hold `V`'s values in the same transaction +#### Scenario: A view-only holder cannot restore +- GIVEN a secret shared directly with Bob, whose copy has a prior version `V` +- WHEN Bob sends `POST /api/v1/versions/{id}/restore` for `V` +- THEN the system MUST answer 428 with `error` `view_only`, and Bob's copy and its version list MUST stay as they were + ## ADDED Requirements ### Requirement: A restore is one share-save of the version -The web app MUST restore a version by decrypting it in the browser and sending it as one share-save with `restoredFrom` and the version's whole value, based on the head's `updatedAt`. A refused or failed share-save MUST leave the head, every copy and the version history unchanged and MUST show an error. A copy holder without a write grade restores only their own copy, through the version restore route, which records the restore too. That route MUST accept an optional `baseUpdatedAt` and, when it differs from the row's `updatedAt`, change nothing and answer 409 as a stale update does. With or without a base, a save that changes the row between the route's read and its write MUST make the route change nothing and answer 409 too. +The web app MUST restore a version by decrypting it in the browser and sending it as one share-save with `restoredFrom` and the version's whole value, based on the head's `updatedAt`. A refused or failed share-save MUST leave the head, every copy and the version history unchanged and MUST show an error. The version restore route, `POST /api/v1/versions/{id}/restore`, changes one row only and records the restore too; the web app doesn't use it. That route MUST accept an optional `baseUpdatedAt` and, when it differs from the row's `updatedAt`, change nothing and answer 409 as a stale update does. With or without a base, a save that changes the row between the route's read and its write MUST make the route change nothing and answer 409 too. #### Scenario: A failed restore changes nothing - GIVEN a shared secret whose head changed in another browser after this one opened it diff --git a/openspec/changes/sharing-atomic-share-save/specs/user-sharing/spec.md b/openspec/changes/sharing-atomic-share-save/specs/user-sharing/spec.md index 3bfc92c9e..70f2732d6 100644 --- a/openspec/changes/sharing-atomic-share-save/specs/user-sharing/spec.md +++ b/openspec/changes/sharing-atomic-share-save/specs/user-sharing/spec.md @@ -1,7 +1,7 @@ ## MODIFIED Requirements ### Requirement: Sync on Update -When the owner, or a recipient allowed to write the source, updates the value, login or additional fields of a shared secret, the change MUST reach every copy in the same request, through `PUT /api/v1/secrets/{id}/share-save`. The browser MUST encrypt the change for each holder's certificate; the server MUST NOT decrypt or re-encrypt anything. +When the owner, or a recipient allowed to write the source, updates the value, login or additional fields of a shared secret, the change MUST reach every copy in the same request, through `PUT /api/v1/secrets/{id}/share-save`. The browser MUST encrypt the change for each holder's certificate; the server MUST NOT decrypt or re-encrypt anything. Any other recipient's copy is view-only (see "View-Only Copies"). #### Scenario: Owner updates shared secret - GIVEN a secret is shared with one or more users @@ -14,7 +14,7 @@ When the owner, or a recipient allowed to write the source, updates the value, l - GIVEN a secret has been shared with user B, who holds a write grade on it: a `write` or `manage` team-folder grade, or membership of a group the secret is shared with in full (not use-only) - WHEN user B updates their copy of the secret - THEN the browser MUST encrypt the updated value for the original owner and all other recipients and send it in one share-save -- AND a recipient who holds the secret through a direct share only, without a write grade, MUST change only their own copy +- AND a recipient without a write grade MUST NOT be able to change the value of their copy (see "View-Only Copies") #### Scenario: Only the changed fields reach the copies - GIVEN a shared secret with a login and additional fields diff --git a/openspec/parity/capabilities.json b/openspec/parity/capabilities.json index 688298e69..202e7e769 100644 --- a/openspec/parity/capabilities.json +++ b/openspec/parity/capabilities.json @@ -1513,7 +1513,7 @@ "nextcloud-passwords": "yes", "built": { "state": "built", - "evidence": "lib/Service/SecretService.php:892 versionService->snapshot on every user update; src/components/SecretDetailSidebar.vue:781 VersionHistoryPanel -> src/store/modules/secretVersion.js:42 GET /api/v1/secrets/{secretId}/versions, :68 view, :108 POST /api/v1/versions/{id}/restore (appinfo/routes.php:330-332) -> lib/Controller/SecretVersionController.php:139; src/components/VersionHistoryPanel.vue:155 restore after VersionRestoreDialog confirm", + "evidence": "lib/Service/SecretService.php:1075 versionService->snapshot on every user update; src/components/SecretDetailSidebar.vue:907 VersionHistoryPanel -> src/store/modules/secretVersion.js:51 GET /api/v1/secrets/{secretId}/versions, :78 view, :114 restore as saveShared with restoredFrom -> PUT /api/v1/secrets/{id}/share-save (appinfo/routes.php:184) -> lib/Controller/ShareSaveController.php:90; src/components/VersionHistoryPanel.vue:156 restore after VersionRestoreDialog confirm", "owner": "ConductionNL/keepiq", "reachedOn": "SecretList page (/secrets/:id) -> detail sidebar -> Version history panel -> View / Restore", "note": "Each update snapshots the prior value; the owner can view an earlier version decrypted in session and restore it after a confirm, with the current value kept as a new version.", diff --git a/openspec/specs/folder-permission-grades/spec.md b/openspec/specs/folder-permission-grades/spec.md index bbb88f5b4..0ba3d9b0a 100644 --- a/openspec/specs/folder-permission-grades/spec.md +++ b/openspec/specs/folder-permission-grades/spec.md @@ -39,7 +39,7 @@ The system MUST record a `read` (default), `write` or `manage` grade on every te - **THEN** Bob's grade MUST become `write` ### Requirement: A write-grade member may update a folder secret for all recipients -The system MUST allow a `write`-grade member to update a folder secret such that the change propagates to every recipient. The value MUST be re-encrypted under each recipient's public certificate by the writer's client; the server MUST NOT decrypt, re-encrypt, or hold plaintext. +The system MUST allow a `write`-grade member to update a folder secret such that the change propagates to every recipient. The value MUST be re-encrypted under each recipient's public certificate by the writer's client; the server MUST NOT decrypt, re-encrypt, or hold plaintext. A member whose effective grade is `read` holds a view-only copy (user-sharing, "View-Only Copies"): they MUST NOT change its value, neither for every holder nor for their own copy alone. #### Scenario: Write-grade member rotates a shared credential - GIVEN user W holds a `write` grade on a folder containing secret S shared to recipients R @@ -52,6 +52,11 @@ The system MUST allow a `write`-grade member to update a folder secret such that - WHEN V attempts a value update that would propagate to recipients - THEN the system MUST reject the request and change no recipient's copy +#### Scenario: Read-grade member cannot change their own copy +- GIVEN user V holds a `read` grade on a folder containing secret S +- WHEN V sends `PUT /api/v1/secrets/{id}` for their copy of S with a new value +- THEN the system MUST answer 428 with `error` `view_only` and leave V's copy unchanged + ### Requirement: Effective grade is the highest grade along the ancestor folder chain The system MUST compute a member's effective grade for a secret or a team folder as the highest grade granted by any ancestor team folder, with `manage` above `write` above `read`. A subfolder MAY raise the grade; it MUST NOT lower it below any ancestor's grade. diff --git a/openspec/specs/offline-edit-queue/spec.md b/openspec/specs/offline-edit-queue/spec.md index 0a89c212d..9dd9534be 100644 --- a/openspec/specs/offline-edit-queue/spec.md +++ b/openspec/specs/offline-edit-queue/spec.md @@ -67,13 +67,14 @@ When the browser is online and the vault is unlocked, the web app MUST replay qu ### Requirement: Failed entries are kept, never dropped silently -A replay answered with 403 or 404 MUST move the entry to a failed list where the user can copy their values (decrypted in the browser) or discard the entry. A 423 or a network error MUST keep the entry queued. An entry whose owner row saved but whose recipient sync failed MUST retry only the sync step. +A replay answered with 403 or 404, or a value change of a copy the user may only view (user-sharing, "View-Only Copies"), MUST move the entry to a failed list where the user can copy their values (decrypted in the browser) or discard the entry. A 423 or a network error MUST keep the entry queued. An entry whose owner row saved but whose recipient sync failed MUST retry only the sync step. #### Scenario: Write grade removed while offline - **GIVEN** a team-folder member who edited a folder secret offline, and whose grade was lowered to read meanwhile -- **WHEN** the replay's sync request is refused with 403 -- **THEN** the entry MUST appear under "Changes that could not sync" with copy and discard actions +- **WHEN** the replay runs +- **THEN** the replay MUST send nothing for the entry, since the copy is now view-only +- **AND** the entry MUST appear under "Changes that could not sync" with copy and discard actions ### Requirement: Pending changes block logout and rotation diff --git a/openspec/specs/secret-requests/spec.md b/openspec/specs/secret-requests/spec.md index 9e5f7d465..df0972d92 100644 --- a/openspec/specs/secret-requests/spec.md +++ b/openspec/specs/secret-requests/spec.md @@ -145,6 +145,13 @@ Anyone with the fill-in link MUST be able to submit values for the requested fie - THEN the SecretRequest MUST remain `pending` so the link can be used again - AND it MUST NOT be reported as `fulfilled` +#### Scenario: A fill onto a secret its owner may not change is refused + +- GIVEN a pending request whose linked Secret is a copy its owner may not change: shared with them to view only (user-sharing, "View-Only Copies"), use-only, a read-only copy from another organisation, or a copy whose source can no longer be found +- WHEN an external party submits values via the token link +- THEN the system MUST store nothing and answer 428 with `error` `forbidden` and the message "The secret this request writes to cannot be changed", which says nothing about the owner's access +- AND the SecretRequest MUST remain `pending` + #### Scenario: Requester cannot read after submission - GIVEN a SecretRequest has been fulfilled - WHEN the requester retrieves the linked Secret diff --git a/openspec/specs/secret-version-history/spec.md b/openspec/specs/secret-version-history/spec.md index 1755b7431..27bab850d 100644 --- a/openspec/specs/secret-version-history/spec.md +++ b/openspec/specs/secret-version-history/spec.md @@ -20,13 +20,18 @@ The system MUST snapshot a secret's pre-update state as an immutable version whe - THEN a version row MUST retain `C0` with the actor and prior encryption_suite_id, and the head MUST hold `C1` ### Requirement: List, view, and restore versions -The system MUST let a user list versions newest-first (metadata only), view a version via client-side decryption identical to a head read, and restore a version — creating a new head version and propagating via sync-on-update. +The system MUST let a user list versions newest-first (metadata only), view a version via client-side decryption identical to a head read, and restore a version — creating a new head version and propagating via sync-on-update. The holder of a view-only copy (user-sharing, "View-Only Copies") MAY list and view its versions but MUST NOT restore one: the web app MUST NOT offer Restore on it, and `POST /api/v1/versions/{id}/restore` MUST answer 428 with `error` `view_only` and change nothing. #### Scenario: Restore becomes a new head and syncs - GIVEN a secret shared with a recipient and a prior version `V` - WHEN the owner restores `V` - THEN the current head MUST first be snapshotted, the head MUST become `V`'s values, and the change MUST propagate to the recipient's copy +#### Scenario: A view-only holder cannot restore +- GIVEN a secret shared directly with Bob, whose copy has a prior version `V` +- WHEN Bob sends `POST /api/v1/versions/{id}/restore` for `V` +- THEN the system MUST answer 428 with `error` `view_only`, and Bob's copy and its version list MUST stay as they were + ### Requirement: Admin-configurable retention and pruning The system MUST bound retention by count and/or age (defaults 20 versions / 365 days, 0 = unlimited), administrator-configurable, pruned in bounded batches by a background job that never touches the head. diff --git a/openspec/specs/secrets-write-ui/spec.md b/openspec/specs/secrets-write-ui/spec.md index 85179c377..21369ec66 100644 --- a/openspec/specs/secrets-write-ui/spec.md +++ b/openspec/specs/secrets-write-ui/spec.md @@ -80,6 +80,13 @@ Until this requirement, the only writers were the write-for-application dialog, import, and an external recipient filling a secret request — so obtaining one on your own secret meant asking a stranger to submit it. +On a copy shared with the user to view only (user-sharing, "View-Only Copies"), the detail view MUST NOT offer Edit and MUST say "Shared with you to view only. Ask its owner for edit rights to change it."; when the edit dialog learns from the write-context that the copy is view-only, it MUST show the same note and keep Save disabled. Offline the copy's grade is not known, so Edit stays available there and the replay refuses the change (offline-edit-queue). + +#### Scenario: A view-only copy offers no Edit +- **GIVEN** a secret shared directly with the user +- **WHEN** the user opens their copy online +- **THEN** the detail view MUST NOT show Edit and MUST say that it is shared with them to view only + #### Scenario: Edit a secret's value - **WHEN** the user edits a secret, changes the value, and saves - **THEN** the browser MUST RSA-encrypt the new value and PUT it diff --git a/openspec/specs/secrets/spec.md b/openspec/specs/secrets/spec.md index 37fd570f5..e5f7c7f91 100644 --- a/openspec/specs/secrets/spec.md +++ b/openspec/specs/secrets/spec.md @@ -121,7 +121,7 @@ The system MUST decrypt and return secret fields when the user has their master - THEN the app MUST send them to the lock screen, keeping the requested route as the return address ### Requirement: Update Secret -The system MUST allow a user to update any field of a secret they own, including moving it to a different folder. Updated encrypted fields MUST be re-encrypted before storage. +The system MUST allow a user to update any field of a secret they own, including moving it to a different folder. Updated encrypted fields MUST be re-encrypted before storage. On a copy shared with the user to view only (user-sharing, "View-Only Copies"), `PUT /api/v1/secrets/{id}` MUST refuse a change of `key`, `login` or `additionalFields` with HTTP 428 and `error` `view_only`, and change nothing; a field sent with the value already stored is not a change, and an update that changes only other fields MUST still save. #### Scenario: Owner updates a secret - GIVEN a user owns a secret @@ -129,6 +129,12 @@ The system MUST allow a user to update any field of a secret they own, including - THEN the system MUST persist the change - AND any updated encrypted fields MUST be re-encrypted before storage +#### Scenario: A new value for a view-only copy is refused +- GIVEN a copy shared with Bob to view only +- WHEN Bob sends `PUT /api/v1/secrets/{id}` with a new `key` and a new `folderId` +- THEN the system MUST answer 428 with `code` and `error` `view_only` and the message "Shared with you to view only. Ask its owner for edit rights to change it." +- AND neither the value nor the folder MUST change + ### Requirement: Delete Secret The system MUST allow a user to delete a secret they own. Deletion MUST cascade to any SecretShares derived from this secret and any SecretRequests linked to it. diff --git a/openspec/specs/sharing-group/spec.md b/openspec/specs/sharing-group/spec.md index 2b9002747..54769773a 100644 --- a/openspec/specs/sharing-group/spec.md +++ b/openspec/specs/sharing-group/spec.md @@ -90,13 +90,14 @@ The e2e test keeps the copy through a direct share, which leaving the group does - **THEN** Alice MUST be notified that Dan can now change the secret for everyone, with nothing to approve, and no second share MUST be created for Dan - **AND** the write context of Dan's copy MUST answer `effectiveGrade: 'write'` at once, before Alice answers -#### Scenario: A direct-share recipient changes only their own copy +#### Scenario: A direct-share recipient cannot change their copy @e2e tests/e2e/workflows/share-save.spec.ts - **GIVEN** Alice also shared the secret directly with Dan, who is in no group it is shared with -- **WHEN** Dan saves a change to his copy +- **WHEN** Dan tries to save a change to his copy - **THEN** the write context MUST NOT answer `write` for Dan, and a share-save for every copy MUST be refused +- **AND** his copy MUST be view-only, so a change of its value through `PUT /api/v1/secrets/{id}` MUST be refused with 428 `view_only` (see `user-sharing`) #### Scenario: Knowing a copy's id reveals nothing diff --git a/openspec/specs/user-sharing/spec.md b/openspec/specs/user-sharing/spec.md index 591def78e..c9daeb5e7 100644 --- a/openspec/specs/user-sharing/spec.md +++ b/openspec/specs/user-sharing/spec.md @@ -9,7 +9,7 @@ @e2e exclude No user-sharing UI is built in v0.1; all sharing scenarios require the encrypted secret CRUD surface (itself unbuilt) — covered by integration tests, not Playwright UI flows. -A user can share a secret with another Nextcloud user or with a Nextcloud user group. Because encryption is asymmetric, sharing works by creating an encrypted copy of the secret using the recipient's public certificate. Both the original and all shared copies stay in sync: when the owner, a delegate or a recipient who holds a write grade on it updates the secret, the change is written back to all copies. +A user can share a secret with another Nextcloud user or with a Nextcloud user group. Because encryption is asymmetric, sharing works by creating an encrypted copy of the secret using the recipient's public certificate. Both the original and all shared copies stay in sync: when the owner, a delegate or a recipient who holds a write grade on it updates the secret, the change is written back to all copies. Any other recipient's copy is view-only. Group sharing expands statically to individual shares at share time. When new members join a group, the owner is notified and asked to approve adding those who don't hold a copy yet. When members leave a group, their group-derived shares are automatically revoked. A direct share is never created or removed by a change in group membership. What its holder may do with their copy does follow membership, though: a holder who is in a group the secret is shared with in full saves for everyone, also when they joined that group after their copy was made. The owner is then told, with nothing to approve (see `sharing-group`). @@ -191,7 +191,7 @@ The marks MUST come from an endpoint that takes the search term and the user ids - WHEN it reaches the endpoint - THEN the system MUST refuse it with 400 ### Requirement: Sync on Update -When the owner, a delegate, or a recipient who holds a write grade on it updates a shared secret, the change MUST be propagated to all copies. +When the owner, a delegate, or a recipient who holds a write grade on it updates a shared secret, the change MUST be propagated to all copies. Any other recipient's copy is view-only (see "View-Only Copies"). A sync names the source secret; one that names a received copy MUST be refused. #### Scenario: Owner updates shared secret - GIVEN a secret is shared with one or more users @@ -203,7 +203,28 @@ When the owner, a delegate, or a recipient who holds a write grade on it updates - GIVEN a secret has been shared with user B, who holds a write grade on it: a `write` or `manage` team-folder grade, or membership of a group the secret is shared with in full (not use-only) - WHEN user B updates their copy of the secret - THEN the system MUST re-encrypt the updated value for the original owner and all other recipients -- AND a recipient who holds the secret through a direct share only, without a write grade, MUST change only their own copy +- AND a recipient without a write grade MUST NOT be able to change the value of their copy (see "View-Only Copies") + +### Requirement: View-Only Copies +A received copy is view-only for its holder unless they may write its source: as its owner or a delegate, with an effective `write` or `manage` grade on a team folder that holds it, or as a member of a group the source is shared with through a full group share that has not expired (see `sharing-group`). A team-folder Viewer (`read`), a recipient of a direct share only, and a member of a group whose share is use-only or expired hold view-only copies. The system MUST refuse a change of the value, login or additional fields of a view-only copy and change nothing, whether it comes through `PUT /api/v1/secrets/{id}`, `POST /api/v1/versions/{id}/restore`, `PUT /api/v1/secrets/{id}/sync` or a fill of a secret request for that copy. A field sent with the value already stored is not a change. The update and the restore MUST answer HTTP 428 with `code` and `error` set to `view_only` and the message "Shared with you to view only. Ask its owner for edit rights to change it." A sync starts from the source, so a sync that names any received copy MUST answer 428 with `error` `forbidden`, whatever the holder's grade. A change of any other field, such as the folder, MUST still save. A suite migration re-seals the copy under its holder's new key with values encrypted in their browser; the server can't tell a re-seal from a new value, so it doesn't check it. + +The web app MUST read the copy's write-context to tell a view-only copy apart. On a view-only copy it MUST NOT offer Edit, a version restore or asking for new values, MUST say "Shared with you to view only. Ask its owner for edit rights to change it.", and MUST keep moving it to a folder, starring, archiving, tagging and deleting it. Its edit dialog MUST NOT save, so the web app offers no way to change its name or URL either, as on a read-only copy from another organisation. A share-save of a view-only copy MUST be refused in the browser before anything is sent. + +#### Scenario: A direct-share recipient cannot change the value +- GIVEN a secret Alice shared directly with Bob +- WHEN Bob sends `PUT /api/v1/secrets/{id}` for his copy with a new value +- THEN the system MUST answer 428 with `error` `view_only` and leave Bob's copy, Alice's secret and every other copy unchanged + +#### Scenario: A view-only holder still files their copy +- GIVEN a secret Alice shared directly with Bob, and a folder of Bob's +- WHEN Bob moves his copy to that folder and archives it +- THEN the system MUST store the new folder and the archive, and the value MUST stay as Alice saved it + +#### Scenario: A team-folder Viewer sees no Edit +- GIVEN user V holds a `read` grade on a team folder containing secret S +- WHEN V opens their copy of S +- THEN the detail view MUST NOT show Edit, Restore or "Ask for new values" +- AND it MUST say that the secret is shared with V to view only ### Requirement: Share with Group (Static Expansion) The system MUST allow a secret owner to share a secret with a Nextcloud user group. At the moment of sharing, the system MUST create an individual SecretShare (with `group_share_id` set) for each current member of the group who has an active EncryptionSuite. A GroupShare record MUST be created to track the relationship. @@ -466,6 +487,7 @@ The system MUST allow the original owner to revoke a share, removing the recipie - [ ] The copy is encrypted with the recipient's public certificate — the sender cannot read it after sharing - [ ] The recipient receives a Nextcloud notification when a secret is shared with them - [ ] Updates by the owner, a delegate or a recipient who holds a write grade on it propagate to all copies of the shared secret +- [ ] A recipient without a write grade cannot change the value of their copy - [ ] The original owner can revoke a share at any time - [ ] Revoking a share deletes the recipient's copy - [ ] Sharing fails with a clear error if the recipient has no EncryptionSuite diff --git a/src/components/SecretDetailSidebar.vue b/src/components/SecretDetailSidebar.vue index 1980dfc55..dca50e82f 100644 --- a/src/components/SecretDetailSidebar.vue +++ b/src/components/SecretDetailSidebar.vue @@ -77,6 +77,7 @@ (!offlineReadOnly || offlineEditable) && !useOnly && !federatedReadOnly + && !viewOnlyCopy " variant="primary" data-testid="secret-detail-edit" @@ -220,6 +221,20 @@ ) }} + + + {{ + t( + 'keepiq', + 'Shared with you to view only. Ask its owner for edit rights to change it.', + ) + }} +

-

+