Compare commits

...
14 Commits
Author SHA1 Message Date
Lauri Ojansivu 058180687a v3.82 2020-03-01 21:44:38 +02:00
Lauri Ojansivu 897506eeac v3.81 2020-03-01 21:30:43 +02:00
Lauri Ojansivu aac7c380c8 - Fix critical and moderate security vulnerabilities reported at 2020-02-26 with
responsible disclosure by [Dejan Zelic](https://twitter.com/dejandayoff),
  Justin Benjamin and others at [Offensive Security](https://twitter.com/offsectraining),
  that follow standard 90 days before public disclosure.
  Thanks to xet7.
- Fix webhook error that prevented some card etc deleting from web UI of board.
  Thanks to xet7.
- Add some more Font Awesome icons.
  Thanks to xet7.
- Remove autofocus from many form input boxes so that they would not cause warnings.
  Thanks to xet7.
2020-03-01 20:59:53 +02:00
Lauri Ojansivu fc35c234a7 Update translations. 2020-03-01 20:38:05 +02:00
Lauri Ojansivu 0d3002f69d Try to make Meteor build time shorter by excluding legacy and cordova.
Thanks to xet7 !
2020-03-01 20:33:23 +02:00
Lauri Ojansivu 7d920e938b Merge branch 'master' of github.com:wekan/wekan 2020-03-01 20:27:22 +02:00
Lauri Ojansivu 26b521e86e Upgrade Meteor to 1.10-rc.2 2020-03-01 20:26:29 +02:00
Lauri Ojansivu 83b042701f Merge pull request #2948 from NicoP-S/master
Make profile.initials available in publications
2020-02-28 23:11:03 +02:00
Nico 21b75edcdd Make profile.initials available in publications 2020-02-28 22:05:33 +01:00
Lauri Ojansivu 493d71a198 Update translations. 2020-02-23 22:45:43 +02:00
Lauri Ojansivu 27f9c6b925 Update translations. 2020-02-22 20:07:16 +02:00
Lauri Ojansivu fa07dcf422 Update ChangeLog. 2020-02-22 16:39:28 +02:00
Lauri Ojansivu 2b9540ce02 Try to fix afterwards loading of cards by adding
fallback when requestIdleCallback is not available.

Thanks to xet7 !

Closes #2878,
closes #2250
2020-02-22 16:32:54 +02:00
Lauri Ojansivu 906c25d5e8 Update translations. 2020-02-22 10:32:48 +02:00
34 changed files with 514 additions and 420 deletions

No files matched your search

+4 -4
View File
@@ -23,7 +23,7 @@ dburles:collection-helpers
idmontie:migrations
matb33:collection-hooks
matteodem:easy-search
mongo@1.8.0
mongo@1.9.0-rc110.2
mquandalle:collection-mutations
# Account system
@@ -38,7 +38,7 @@ wekan-accounts-oidc
# Utilities
check@1.3.1
jquery@1.11.10
random@1.1.0
random@1.2.0-rc110.2
reactive-dict@1.3.0
session@1.2.0
tracker@1.2.0
@@ -67,7 +67,7 @@ templates:tabs
verron:autosize
simple:json-routes
rajit:bootstrap3-datepicker
shell-server@0.4.0
shell-server@0.5.0-rc110.2
simple:rest-accounts-password
useraccounts:core
email@1.2.3
@@ -75,7 +75,7 @@ horka:swipebox
dynamic-import@0.5.1
staringatlights:fast-render
accounts-password@1.5.2
accounts-password@1.6.0-rc110.2
cfs:gridfs
rzymek:fullcalendar
momentjs:moment@2.22.2
+1 -1
View File
@@ -1 +1 @@
METEOR@1.9.2
METEOR@1.10-rc.2
+15 -15
View File
@@ -1,7 +1,7 @@
3stack:presence@1.1.2
accounts-base@1.5.0
accounts-oauth@1.1.16
accounts-password@1.5.3
accounts-base@1.6.0-rc110.2
accounts-oauth@1.2.0-rc110.2
accounts-password@1.6.0-rc110.2
aldeed:collection2@2.10.0
aldeed:collection2-core@1.2.0
aldeed:schema-deny@1.1.0
@@ -17,7 +17,7 @@ base64@1.0.12
binary-heap@1.0.11
blaze@2.3.4
blaze-tools@1.0.10
boilerplate-generator@1.6.0
boilerplate-generator@1.7.0-rc110.2
browser-policy-common@1.0.11
browser-policy-framing@1.1.0
caching-compiler@1.2.1
@@ -75,7 +75,7 @@ htmljs@1.0.11
http@1.4.2
id-map@1.1.0
idmontie:migrations@1.0.3
inter-process-messaging@0.1.0
inter-process-messaging@0.1.1-rc110.2
jquery@1.11.11
kadira:blaze-layout@2.3.0
kadira:dochead@1.5.0
@@ -84,7 +84,7 @@ kenton:accounts-sandstorm@0.7.0
konecty:mongo-counter@0.0.5_3
lamhieu:meteorx@2.1.1
lamhieu:unblock@1.0.0
launch-screen@1.1.1
launch-screen@1.2.0-rc110.2
livedata@1.0.18
localstorage@1.2.0
logging@1.1.20
@@ -104,13 +104,13 @@ meteorspark:util@0.2.0
minifier-css@1.5.0
minifier-js@2.6.0
minifiers@1.1.8-faster-rebuild.0
minimongo@1.4.5
mobile-status-bar@1.0.14
minimongo@1.5.0-rc110.2
mobile-status-bar@1.1.0-rc110.2
modern-browsers@0.1.5
modules@0.15.0
modules-runtime@0.12.0
momentjs:moment@2.24.0
mongo@1.8.1
mongo@1.9.0-rc110.2
mongo-decimal@0.1.1
mongo-dev-server@1.1.0
mongo-id@1.0.7
@@ -127,9 +127,9 @@ mquandalle:mousetrap-bindglobal@0.0.1
mquandalle:perfect-scrollbar@0.6.5_2
msavin:usercache@1.8.0
npm-bcrypt@0.9.3
npm-mongo@3.3.0
oauth@1.2.8
oauth2@1.2.1
npm-mongo@3.5.0-rc110.2
oauth@1.3.0-rc110.2
oauth2@1.3.0-rc110.2
observe-sequence@1.0.16
ongoworks:speakingurl@1.1.0
ordered-dict@1.1.0
@@ -144,7 +144,7 @@ promise@0.11.2
raix:eventemitter@0.1.3
raix:handlebar-helpers@0.2.5
rajit:bootstrap3-datepicker@1.7.1_1
random@1.1.0
random@1.2.0-rc110.2
rate-limit@1.0.9
reactive-dict@1.3.0
reactive-var@1.0.11
@@ -156,7 +156,7 @@ server-render@0.3.1
service-configuration@1.0.11
session@1.2.0
sha@1.0.9
shell-server@0.4.0
shell-server@0.5.0-rc110.2
simple:authenticate-user-by-token@1.0.1
simple:json-routes@2.1.0
simple:rest-accounts-password@1.1.2
@@ -186,7 +186,7 @@ useraccounts:core@1.14.2
useraccounts:flow-routing@1.14.2
useraccounts:unstyled@1.14.2
verron:autosize@3.0.8
webapp@1.8.2
webapp@1.9.0-rc110.2
webapp-hashing@1.0.9
wekan-accounts-cas@0.1.0
wekan-accounts-oidc@1.0.10
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "wekan",
"version": "v3.80.0",
"version": "v3.82.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "wekan",
"version": "v3.80.0",
"version": "v3.82.0",
"description": "Open-Source kanban",
"private": true,
"scripts": {
+45
View File
@@ -1,3 +1,48 @@
# v3.82 2020-03-01 Wekan release
This release reverts the following changes:
- Revert change made at Wekan v3.81, because building did not work: [Try to make Meteor build time shorter
by excluding legacy and cordova. This was made possible by
Meteor 1.10-rc.2](https://github.com/wekan/wekan/commit/0d3002f69d97e646fa7368bfdade4f78c51e9884).
Thanks to xet7.
Thanks to above GitHub users for their contributions and translators for their translations.
# v3.81 2020-03-01 Wekan release
This release [fixes](https://github.com/wekan/wekan/commit/aac7c380c8c389b0683b2bd64e2cc856993f0e30) the following CRITICAL SECURITY VULNERABILITIES and other bugs:
- Fix critical and moderate security vulnerabilities reported at 2020-02-26 with
responsible disclosure by [Dejan Zelic](https://twitter.com/dejandayoff),
Justin Benjamin and others at [Offensive Security](https://twitter.com/offsectraining),
that follow standard 90 days before public disclosure.
Thanks to xet7.
- Fix webhook error that prevented some card etc deleting from web UI of board.
Thanks to xet7.
- Add missing Font Awesome icon to Board Settings Menu.
Thanks to xet7.
- Remove autofocus from many form input boxes so that they would not cause warnings.
Thanks to xet7.
and does the following upgrades:
- [Upgrade Meteor to 1.10-rc.2](https://github.com/wekan/wekan/commit/26b521e86e6ac40b7ba25bbe8dac7bf4d48d43ce).
Thanks to xet7.
- [Try to make Meteor build time shorter by excluding legacy and cordova. This was made possible by
Meteor 1.10-rc.2](https://github.com/wekan/wekan/commit/0d3002f69d97e646fa7368bfdade4f78c51e9884).
Thanks to xet7.
and fixes the following bugs:
- [Try to fix afterwards loading of cards by adding fallback when requestIdleCallback is not
available](https://github.com/wekan/wekan/commit/2b9540ce02de604bf84ea082f2dcb1d01673708c).
Thanks to xet7.
- [Make profile.initials available in publications](https://github.com/wekan/wekan/pull/2948).
Thanks to NicoP-S.
Thanks to above GitHub users for their contributions and translators for their translations.
# v3.80 2020-02-22 Wekan release
This release adds the following features:
+2 -2
View File
@@ -7,7 +7,7 @@ LABEL maintainer="wekan"
ENV BUILD_DEPS="apt-utils libarchive-tools gnupg gosu wget curl bzip2 g++ build-essential git ca-certificates python3" \
DEBUG=false \
NODE_VERSION=v12.16.1 \
METEOR_RELEASE=1.9.0 \
METEOR_RELEASE=1.10-rc.2 \
USE_EDGE=false \
METEOR_EDGE=1.5-beta.17 \
NPM_VERSION=latest \
@@ -249,7 +249,7 @@ RUN \
chown wekan --recursive /home/wekan/.npm /home/wekan/.config /home/wekan/.meteor && \
#gosu wekan:wekan /home/wekan/.meteor/meteor add standard-minifier-js && \
gosu wekan:wekan npm install && \
gosu wekan:wekan /home/wekan/.meteor/meteor build --directory /home/wekan/app_build && \
gosu wekan:wekan /home/wekan/.meteor/meteor build --directory /home/wekan/app_build --exclude-archs web.browser.legacy,web.cordova && \
cp /home/wekan/app/fix-download-unicode/cfs_access-point.txt /home/wekan/app_build/bundle/programs/server/packages/cfs_access-point.js && \
#rm /home/wekan/app_build/bundle/programs/server/npm/node_modules/meteor/rajit_bootstrap3-datepicker/lib/bootstrap-datepicker/node_modules/phantomjs-prebuilt/lib/phantom/bin/phantomjs && \
chown wekan /home/wekan/app_build/bundle/programs/server/packages/cfs_access-point.js && \
+1 -1
View File
@@ -1,5 +1,5 @@
appId: wekan-public/apps/77b94f60-dec9-0136-304e-16ff53095928
appVersion: "v3.80.0"
appVersion: "v3.82.0"
files:
userUploads:
- README.md
+17 -1
View File
@@ -743,9 +743,25 @@ BlazeComponent.extendComponent({
},
updateList() {
// Use fallback when requestIdleCallback is not available on iOS and Safari
// https://www.afasterweb.com/2017/11/20/utilizing-idle-moments/
checkIdleTime =
window.requestIdleCallback ||
function(handler) {
const startTime = Date.now();
return setTimeout(function() {
handler({
didTimeout: false,
timeRemaining() {
return Math.max(0, 50.0 - (Date.now() - startTime));
},
});
}, 1);
};
if (this.spinnerInView()) {
this.cardlimit.set(this.cardlimit.get() + InfiniteScrollIter);
window.requestIdleCallback(() => this.updateList());
checkIdleTime(() => this.updateList());
}
},
+2 -2
View File
@@ -110,7 +110,7 @@ template(name="editUserPopup")
label.hide.userId(type="text" value=user._id)
label
| {{_ 'fullname'}}
input.js-profile-fullname(type="text" value=user.profile.fullname autofocus)
input.js-profile-fullname(type="text" value=user.profile.fullname)
label
| {{_ 'username'}}
span.error.hide.username-taken
@@ -159,7 +159,7 @@ template(name="newUserPopup")
//label.hide.userId(type="text" value=user._id)
label
| {{_ 'fullname'}}
input.js-profile-fullname(type="text" value="" autofocus)
input.js-profile-fullname(type="text" value="")
label
| {{_ 'username'}}
span.error.hide.username-taken
+6 -3
View File
@@ -245,7 +245,7 @@ template(name="outgoingWebhooksPopup")
b  
.materialCheckBox(class="{{#unless enabled}}is-checked{{/unless}}")
input.js-outgoing-webhooks-title(placeholder="{{_ 'webhook-title'}}" type="text" name="title" value=title)
input.js-outgoing-webhooks-url(type="text" name="url" value=url autofocus)
input.js-outgoing-webhooks-url(type="text" name="url" value=url)
input.js-outgoing-webhooks-token(placeholder="{{_ 'webhook-token' }}" type="text" value=token name="token")
select.js-outgoing-webhooks-type(name="type")
each _type in types
@@ -257,7 +257,7 @@ template(name="outgoingWebhooksPopup")
input(type="hidden" value=_id name="id")
input.primary.wide(type="submit" value="{{_ 'save'}}")
form.integration-form
input.js-outgoing-webhooks-title(placeholder="{{_ 'webhook-title'}}" type="text" name="title" autofocus)
input.js-outgoing-webhooks-title(placeholder="{{_ 'webhook-title'}}" type="text" name="title")
input.js-outgoing-webhooks-url(placeholder="{{_ 'URL' }}" type="text" name="url")
input.js-outgoing-webhooks-token(placeholder="{{_ 'webhook-token' }}" type="text" name="token")
select.js-outgoing-webhooks-type(name="type")
@@ -267,7 +267,10 @@ template(name="outgoingWebhooksPopup")
template(name="boardMenuPopup")
ul.pop-over-list
li: a.js-custom-fields {{_ 'custom-fields'}}
li
a.js-custom-fields
i.fa.fa-list-alt
| {{_ 'custom-fields'}}
li
a.js-open-archives
i.fa.fa-archive
+3 -3
View File
@@ -757,7 +757,7 @@
"cardAssigneesPopup-title": "Asignado",
"addmore-detail": "Añadir una descripción detallada",
"show-on-card": "Mostrar en la tarjeta",
"new": "New",
"editUserPopup-title": "Edit User",
"newUserPopup-title": "New User"
"new": "Nuevo",
"editUserPopup-title": "Editar el usuario",
"newUserPopup-title": "Nuevo usuario"
}
+3 -3
View File
@@ -757,7 +757,7 @@
"cardAssigneesPopup-title": "Cessionnaire",
"addmore-detail": "Ajouter une description plus détaillée",
"show-on-card": "Afficher sur la carte",
"new": "New",
"editUserPopup-title": "Edit User",
"newUserPopup-title": "New User"
"new": "Nouveau",
"editUserPopup-title": "Éditer l'utilisateur",
"newUserPopup-title": "Nouvel utilisateur"
}
+3 -3
View File
@@ -757,7 +757,7 @@
"cardAssigneesPopup-title": "גורם אחראי",
"addmore-detail": "הוספת תיאור מפורט",
"show-on-card": "הצגה על הכרטיס",
"new": "New",
"editUserPopup-title": "Edit User",
"newUserPopup-title": "New User"
"new": "חדש",
"editUserPopup-title": "עריכת משתמש",
"newUserPopup-title": "משתמש חדש"
}
+8 -8
View File
@@ -24,7 +24,7 @@
"act-createCard": "scheda __card__ creata nella lista __list__ della corsia __swimlane__ della bacheca __board__",
"act-createCustomField": "creato campo personalizzato __customField__ nella bacheca __board",
"act-deleteCustomField": "campo personalizzato eliminato __customField__ nella bacheca __board",
"act-setCustomField": "edited custom field __customField__: __customFieldValue__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-setCustomField": "campo personalizzato modificato __customField__: __customFieldValue__ sulla scheda __card__ sulla lista __list__ sulla swimlane __swimlane__ sulla bacheca __board__",
"act-createList": "aggiunta lista __list__ alla bacheca __board__",
"act-addBoardMember": "aggiunto membro __member__ alla bacheca __board__",
"act-archivedBoard": "Bacheca __board__ archiviata",
@@ -583,9 +583,9 @@
"default": "Predefinito",
"queue": "Coda",
"subtask-settings": "Impostazioni sotto-compiti",
"card-settings": "Card Settings",
"card-settings": "Impostazioni della scheda",
"boardSubtaskSettingsPopup-title": "Impostazioni sotto-compiti della bacheca",
"boardCardSettingsPopup-title": "Card Settings",
"boardCardSettingsPopup-title": "Impostazioni della scheda",
"deposit-subtasks-board": "Deposita i sotto compiti in questa bacheca",
"deposit-subtasks-list": "Lista di destinaizoni per questi sotto-compiti",
"show-parent-in-minicard": "Mostra genirotri nelle mini schede:",
@@ -755,9 +755,9 @@
"show-desktop-drag-handles": "Mostra maniglie di trascinamento del desktop",
"assignee": "Assegnatario",
"cardAssigneesPopup-title": "Assegnatario",
"addmore-detail": "Add a more detailed description",
"show-on-card": "Show on Card",
"new": "New",
"editUserPopup-title": "Edit User",
"newUserPopup-title": "New User"
"addmore-detail": "Aggiungi una descrizione più dettagliata",
"show-on-card": "Mostra sulla scheda",
"new": "Nuovo",
"editUserPopup-title": "Modifica utente",
"newUserPopup-title": "Nuovo utente"
}
+3 -3
View File
@@ -757,7 +757,7 @@
"cardAssigneesPopup-title": "Przypisujący",
"addmore-detail": "Dodaj bardziej szczegółowy opis",
"show-on-card": "Pokaż na karcie",
"new": "New",
"editUserPopup-title": "Edit User",
"newUserPopup-title": "New User"
"new": "Nowy",
"editUserPopup-title": "Edytuj użytkownika",
"newUserPopup-title": "Nowy użytkownik"
}
+3 -3
View File
@@ -757,7 +757,7 @@
"cardAssigneesPopup-title": "Administrador",
"addmore-detail": "Adicionar descrição detalhada",
"show-on-card": "Mostrar no Cartão",
"new": "New",
"editUserPopup-title": "Edit User",
"newUserPopup-title": "New User"
"new": "Novo",
"editUserPopup-title": "Editar usuário",
"newUserPopup-title": "Novo usuário"
}
+3 -3
View File
@@ -757,7 +757,7 @@
"cardAssigneesPopup-title": "Dodeljen član",
"addmore-detail": "Dodaj podrobnejši opis",
"show-on-card": "Prikaži na kartici",
"new": "New",
"editUserPopup-title": "Edit User",
"newUserPopup-title": "New User"
"new": "Novo",
"editUserPopup-title": "Uredi uporabnika",
"newUserPopup-title": "Nov uporabnik"
}
+20 -20
View File
@@ -17,14 +17,14 @@
"act-completeChecklist": "slutförde checklista __checklist__ i kort __card__ i lista __list__ i simbana __swimlane__ på anslagstavla __board__",
"act-uncompleteChecklist": "ofullbordade checklista __checklist__ på kort __card__ i lista __list__ i simbana __swimlane__ på anslagstavla __board__",
"act-addComment": "kommenterade på kort __card__: __comment__ i lista __list__ i simbana __swimlane__ på anslagstavla __board__",
"act-editComment": "edited comment on card __card__: __comment__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-deleteComment": "deleted comment on card __card__: __comment__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-editComment": "redigerade kommentar på kort __card__: __comment__ i listan __list__ i simbana __swimlane__ i brädet __board__",
"act-deleteComment": "raderade kommentar på kort __card__: __comment__ i listan __list__ i simbana __swimlane__ i brädet __board__",
"act-createBoard": "skapade anslagstavla __board__",
"act-createSwimlane": "skapade simbana __swimlane__ till anslagstavla __board__",
"act-createCard": "skapade kort __card__ i lista __list__ i simbana __swimlane__ på anslagstavla __board__",
"act-createCustomField": "skapade anpassat fält __customField__ på anslagstavlan __board__",
"act-deleteCustomField": "deleted custom field __customField__ at board __board__",
"act-setCustomField": "edited custom field __customField__: __customFieldValue__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-deleteCustomField": "raderade anpasssat fält __customField__ på bräde __board__",
"act-setCustomField": "redigerade anpassat fält __customField__: __customFieldValue__ på kort __card__ i lista __list__ i simbana __swimlane__ på bräde __board__",
"act-createList": "lade till lista __list__ på anslagstavla __board__",
"act-addBoardMember": "lade till medlem __member__ på anslagstavla __board__",
"act-archivedBoard": "Anslagstavla __board__ flyttad till arkivet",
@@ -137,7 +137,7 @@
"board-view": "Anslagstavelsvy",
"board-view-cal": "Kalender",
"board-view-swimlanes": "Simbanor",
"board-view-collapse": "Collapse",
"board-view-collapse": "Kollapsa",
"board-view-lists": "Listor",
"bucket-example": "Gilla \"att-göra-innan-jag-dör-lista\" till exempel",
"cancel": "Avbryt",
@@ -530,7 +530,7 @@
"bidirectional-webhooks": "Two-Way Webhooks",
"outgoingWebhooksPopup-title": "Utgående Webhookar",
"boardCardTitlePopup-title": "Korttitelfiler",
"disable-webhook": "Disable This Webhook",
"disable-webhook": "Avaktivera denna webhook",
"global-webhook": "Globala webhooks",
"new-outgoing-webhook": "Ny utgående webhook",
"no-name": "(Okänd)",
@@ -583,9 +583,9 @@
"default": "Standard",
"queue": "Kö",
"subtask-settings": "Deluppgift inställningar",
"card-settings": "Card Settings",
"card-settings": "Kortinställningar",
"boardSubtaskSettingsPopup-title": "Deluppgiftsinställningar för anslagstavla",
"boardCardSettingsPopup-title": "Card Settings",
"boardCardSettingsPopup-title": "Kortinställningar",
"deposit-subtasks-board": "Insättnings deluppgifter på denna anslagstavla:",
"deposit-subtasks-list": "Landningslista för deluppgifter deponerade här:",
"show-parent-in-minicard": "Visa förälder i minikort:",
@@ -743,21 +743,21 @@
"almostdue": "aktuell förfallotid %s närmar sig",
"pastdue": "aktuell förfallotid %s är förbi",
"duenow": "aktuell förfallotid %s är idag",
"act-newDue": "__list__/__card__ has 1st due reminder [__board__]",
"act-withDue": "__list__/__card__ due reminders [__board__]",
"act-newDue": "__list__/__card__ har en 1:a påminnelse [__board__]",
"act-withDue": "__list__/__card__ påminnelser [__board__]",
"act-almostdue": "påminde om den aktuella förfallotiden (__timeValue__) av __card__ närmar sig",
"act-pastdue": "påminde om den aktuella förfallotiden (__timeValue__) av __card__ är förbi",
"act-duenow": "påminde om den aktuella förfallotiden (__timeValue__) av __card__ är nu",
"act-atUserComment": "You were mentioned in [__board__] __list__/__card__",
"act-atUserComment": "Du omnämndes i [__board__] __list__/__card__",
"delete-user-confirm-popup": "Är du säker på att du vill ta bort det här kontot? Det går inte att ångra sig.",
"accounts-allowUserDelete": "Tillåt användare att själv ta bort sina konton",
"hide-minicard-label-text": "Hide minicard label text",
"show-desktop-drag-handles": "Show desktop drag handles",
"assignee": "Assignee",
"cardAssigneesPopup-title": "Assignee",
"addmore-detail": "Add a more detailed description",
"show-on-card": "Show on Card",
"new": "New",
"editUserPopup-title": "Edit User",
"newUserPopup-title": "New User"
"hide-minicard-label-text": "Dölj etikett för minikort",
"show-desktop-drag-handles": "Visa greppytor i desktop",
"assignee": "Tilldelad till",
"cardAssigneesPopup-title": "Tilldelad till",
"addmore-detail": "Lägg till detaljerad beskrivning",
"show-on-card": "Visa på kort",
"new": "Ny",
"editUserPopup-title": "Redigera användare",
"newUserPopup-title": "Ny användare"
}
+6 -3
View File
@@ -108,7 +108,7 @@ if (Meteor.isServer) {
let participants = [];
let watchers = [];
let title = 'act-activity-notify';
let board = null;
const board = Boards.findOne(activity.boardId);
const description = `act-${activity.activityType}`;
const params = {
activityId: activity._id,
@@ -122,8 +122,11 @@ if (Meteor.isServer) {
params.userId = activity.userId;
}
if (activity.boardId) {
board = activity.board();
params.board = board.title;
if (board.title.length > 0) {
params.board = board.title;
} else {
params.board = '';
}
title = 'act-withBoardTitle';
params.url = board.absoluteUrl();
params.boardId = activity.boardId;
+89 -80
View File
@@ -620,44 +620,6 @@ Users.mutations({
});
Meteor.methods({
setCreateUser(fullname, username, password, isAdmin, isActive, email) {
if (Meteor.user().isAdmin) {
check(fullname, String);
check(username, String);
check(password, String);
check(isAdmin, String);
check(isActive, String);
check(email, String);
const nUsersWithUsername = Users.find({ username }).count();
const nUsersWithEmail = Users.find({ email }).count();
if (nUsersWithUsername > 0) {
throw new Meteor.Error('username-already-taken');
} else if (nUsersWithEmail > 0) {
throw new Meteor.Error('email-already-taken');
} else {
Accounts.createUser({
fullname,
username,
password,
isAdmin,
isActive,
email: email.toLowerCase(),
from: 'admin',
});
}
}
},
setUsername(username, userId) {
check(username, String);
check(userId, String);
const nUsersWithUsername = Users.find({ username }).count();
if (nUsersWithUsername > 0) {
throw new Meteor.Error('username-already-taken');
} else {
Users.update(userId, { $set: { username } });
}
},
setListSortBy(value) {
check(value, String);
Meteor.user().setListSortBy(value);
@@ -678,51 +640,97 @@ Meteor.methods({
check(limit, Number);
Meteor.user().setShowCardsCountAt(limit);
},
setEmail(email, userId) {
if (Array.isArray(email)) {
email = email.shift();
}
check(email, String);
const existingUser = Users.findOne(
{ 'emails.address': email },
{ fields: { _id: 1 } },
);
if (existingUser) {
throw new Meteor.Error('email-already-taken');
} else {
Users.update(userId, {
$set: {
emails: [
{
address: email,
verified: false,
},
],
},
});
}
},
setUsernameAndEmail(username, email, userId) {
check(username, String);
if (Array.isArray(email)) {
email = email.shift();
}
check(email, String);
check(userId, String);
Meteor.call('setUsername', username, userId);
Meteor.call('setEmail', email, userId);
},
setPassword(newPassword, userId) {
check(userId, String);
check(newPassword, String);
if (Meteor.user().isAdmin) {
Accounts.setPassword(userId, newPassword);
}
},
});
if (Meteor.isServer) {
Meteor.methods({
setCreateUser(fullname, username, password, isAdmin, isActive, email) {
if (Meteor.user() && Meteor.user().isAdmin) {
check(fullname, String);
check(username, String);
check(password, String);
check(isAdmin, String);
check(isActive, String);
check(email, String);
const nUsersWithUsername = Users.find({ username }).count();
const nUsersWithEmail = Users.find({ email }).count();
if (nUsersWithUsername > 0) {
throw new Meteor.Error('username-already-taken');
} else if (nUsersWithEmail > 0) {
throw new Meteor.Error('email-already-taken');
} else {
Accounts.createUser({
fullname,
username,
password,
isAdmin,
isActive,
email: email.toLowerCase(),
from: 'admin',
});
}
}
},
setUsername(username, userId) {
if (Meteor.user() && Meteor.user().isAdmin) {
check(username, String);
check(userId, String);
const nUsersWithUsername = Users.find({ username }).count();
if (nUsersWithUsername > 0) {
throw new Meteor.Error('username-already-taken');
} else {
Users.update(userId, { $set: { username } });
}
}
},
setEmail(email, userId) {
if (Meteor.user() && Meteor.user().isAdmin) {
if (Array.isArray(email)) {
email = email.shift();
}
check(email, String);
const existingUser = Users.findOne(
{ 'emails.address': email },
{ fields: { _id: 1 } },
);
if (existingUser) {
throw new Meteor.Error('email-already-taken');
} else {
Users.update(userId, {
$set: {
emails: [
{
address: email,
verified: false,
},
],
},
});
}
}
},
setUsernameAndEmail(username, email, userId) {
if (Meteor.user() && Meteor.user().isAdmin) {
check(username, String);
if (Array.isArray(email)) {
email = email.shift();
}
check(email, String);
check(userId, String);
Meteor.call('setUsername', username, userId);
Meteor.call('setEmail', email, userId);
}
},
setPassword(newPassword, userId) {
if (Meteor.user() && Meteor.user().isAdmin) {
check(userId, String);
check(newPassword, String);
if (Meteor.user().isAdmin) {
Accounts.setPassword(userId, newPassword);
}
}
},
// we accept userId, username, email
inviteUserToBoard(username, boardId) {
check(username, String);
@@ -754,8 +762,9 @@ if (Meteor.isServer) {
throw new Meteor.Error('error-user-notAllowSelf');
} else {
if (posAt <= 0) throw new Meteor.Error('error-user-doesNotExist');
if (Settings.findOne().disableRegistration)
if (Settings.findOne({ disableRegistration: true })) {
throw new Meteor.Error('error-user-notCreated');
}
// Set in lowercase email before creating account
const email = username.toLowerCase();
username = email.substring(0, posAt);
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "wekan",
"version": "v3.80.0",
"version": "v3.82.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "wekan",
"version": "v3.80.0",
"version": "v3.82.0",
"description": "Open-Source kanban",
"private": true,
"scripts": {
+2 -2
View File
@@ -1524,7 +1524,7 @@ var n=this.pipeline.run(e.tokenizer(t)),r=new e.Vector,i=[],o=this._fields.reduc
<ul class="toc-list-h1">
<li>
<a href="#wekan-rest-api" class="toc-h1 toc-link" data-title="Wekan REST API v3.80">Wekan REST API v3.80</a>
<a href="#wekan-rest-api" class="toc-h1 toc-link" data-title="Wekan REST API v3.82">Wekan REST API v3.82</a>
</li>
@@ -2017,7 +2017,7 @@ var n=this.pipeline.run(e.tokenizer(t)),r=new e.Vector,i=[],o=this._fields.reduc
<div class="page-wrapper">
<div class="dark-box"></div>
<div class="content">
<h1 id="wekan-rest-api">Wekan REST API v3.80</h1>
<h1 id="wekan-rest-api">Wekan REST API v3.82</h1>
<blockquote>
<p>Scroll down for code samples, example requests and responses. Select a language for code samples from the tabs above or the mobile navigation menu.</p>
</blockquote>
+1 -1
View File
@@ -1,7 +1,7 @@
swagger: '2.0'
info:
title: Wekan REST API
version: v3.80
version: v3.82
description: |
The REST API allows you to control and extend Wekan with ease.
+1 -1
View File
@@ -51,7 +51,7 @@ cd ..
REM del /S /F /Q node_modules
call meteor npm install
REM del /S /F /Q .build
call meteor build .build --directory
call meteor build .build --directory --exclude-archs web.browser.legacy,web.cordova
copy fix-download-unicode\cfs_access-point.txt .build\bundle\programs\server\packages\cfs_access-point.js
cd .build\bundle\programs\server
call meteor npm install
+1 -1
View File
@@ -146,7 +146,7 @@ do
rm -rf node_modules .meteor/local
npm install
rm -rf .build
meteor build .build --directory
meteor build .build --directory --exclude-archs web.browser.legacy,web.cordova
cp -f fix-download-unicode/cfs_access-point.txt .build/bundle/programs/server/packages/cfs_access-point.js
#Removed binary version of bcrypt because of security vulnerability that is not fixed yet.
#https://github.com/wekan/wekan/commit/4b2010213907c61b0e0482ab55abb06f6a668eac
+1
View File
@@ -10,6 +10,7 @@ rm -rf node_modules
meteor npm install
rm -rf .build
meteor build .build --directory
# --exclude-archs web.browser.legacy,web.cordova
cp -f fix-download-unicode/cfs_access-point.txt .build/bundle/programs/server/packages/cfs_access-point.js
cd .build/bundle/programs/server
rm -rf node_modules
+2 -2
View File
@@ -22,10 +22,10 @@ const pkgdef :Spk.PackageDefinition = (
appTitle = (defaultText = "Wekan"),
# The name of the app as it is displayed to the user.
appVersion = 380,
appVersion = 382,
# Increment this for every release.
appMarketingVersion = (defaultText = "3.80.0~2020-02-22"),
appMarketingVersion = (defaultText = "3.82.0~2020-03-01"),
# Human-readable presentation of the app version.
minUpgradableAppVersion = 0,
+192 -185
View File
@@ -1,192 +1,199 @@
const postCatchError = Meteor.wrapAsync((url, options, resolve) => {
HTTP.post(url, options, (err, res) => {
if (err) {
resolve(null, err.response);
} else {
resolve(null, res);
}
if (Meteor.isServer) {
const postCatchError = Meteor.wrapAsync((url, options, resolve) => {
HTTP.post(url, options, (err, res) => {
if (err) {
resolve(null, err.response);
} else {
resolve(null, res);
}
});
});
});
const Lock = {
_lock: {},
_timer: {},
echoDelay: 500, // echo should be happening much faster
normalDelay: 1e3, // normally user typed comment will be much slower
ECHO: 2,
NORMAL: 1,
NULL: 0,
has(id, value) {
const existing = this._lock[id];
let ret = this.NULL;
if (existing) {
ret = existing === value ? this.ECHO : this.NORMAL;
}
return ret;
},
clear(id, delay) {
const previous = this._timer[id];
if (previous) {
Meteor.clearTimeout(previous);
}
this._timer[id] = Meteor.setTimeout(() => this.unset(id), delay);
},
set(id, value) {
const state = this.has(id, value);
let delay = this.normalDelay;
if (state === this.ECHO) {
delay = this.echoDelay;
}
if (!value) {
// user commented, we set a lock
value = 1;
}
this._lock[id] = value;
this.clear(id, delay); // always auto reset the locker after delay
},
unset(id) {
delete this._lock[id];
},
};
const Lock = {
_lock: {},
_timer: {},
echoDelay: 500, // echo should be happening much faster
normalDelay: 1e3, // normally user typed comment will be much slower
ECHO: 2,
NORMAL: 1,
NULL: 0,
has(id, value) {
const existing = this._lock[id];
let ret = this.NULL;
if (existing) {
ret = existing === value ? this.ECHO : this.NORMAL;
}
return ret;
},
clear(id, delay) {
const previous = this._timer[id];
if (previous) {
Meteor.clearTimeout(previous);
}
this._timer[id] = Meteor.setTimeout(() => this.unset(id), delay);
},
set(id, value) {
const state = this.has(id, value);
let delay = this.normalDelay;
if (state === this.ECHO) {
delay = this.echoDelay;
}
if (!value) {
// user commented, we set a lock
value = 1;
}
this._lock[id] = value;
this.clear(id, delay); // always auto reset the locker after delay
},
unset(id) {
delete this._lock[id];
},
};
const webhooksAtbts = (process.env.WEBHOOKS_ATTRIBUTES &&
process.env.WEBHOOKS_ATTRIBUTES.split(',')) || [
'cardId',
'listId',
'oldListId',
'boardId',
'comment',
'user',
'card',
'commentId',
'swimlaneId',
];
const responseFunc = data => {
const paramCommentId = data.commentId;
const paramCardId = data.cardId;
const paramBoardId = data.boardId;
const newComment = data.comment;
if (paramCardId && paramBoardId && newComment) {
// only process data with the cardid, boardid and comment text, TODO can expand other functions here to react on returned data
const comment = CardComments.findOne({
_id: paramCommentId,
cardId: paramCardId,
boardId: paramBoardId,
});
const board = Boards.findOne(paramBoardId);
const card = Cards.findOne(paramCardId);
if (board && card) {
if (comment) {
Lock.set(comment._id, newComment);
CardComments.direct.update(comment._id, {
$set: {
const webhooksAtbts = (process.env.WEBHOOKS_ATTRIBUTES &&
process.env.WEBHOOKS_ATTRIBUTES.split(',')) || [
'cardId',
'listId',
'oldListId',
'boardId',
'comment',
'user',
'card',
'commentId',
'swimlaneId',
];
const responseFunc = data => {
const paramCommentId = data.commentId;
const paramCardId = data.cardId;
const paramBoardId = data.boardId;
const newComment = data.comment;
if (paramCardId && paramBoardId && newComment) {
// only process data with the cardid, boardid and comment text, TODO can expand other functions here to react on returned data
const comment = CardComments.findOne({
_id: paramCommentId,
cardId: paramCardId,
boardId: paramBoardId,
});
const board = Boards.findOne(paramBoardId);
const card = Cards.findOne(paramCardId);
if (board && card) {
if (comment) {
Lock.set(comment._id, newComment);
CardComments.direct.update(comment._id, {
$set: {
text: newComment,
},
});
}
} else {
const userId = data.userId;
if (userId) {
const inserted = CardComments.direct.insert({
text: newComment,
},
});
}
} else {
const userId = data.userId;
if (userId) {
const inserted = CardComments.direct.insert({
text: newComment,
userId,
cardId,
boardId,
});
Lock.set(inserted._id, newComment);
}
}
}
};
Meteor.methods({
outgoingWebhooks(integration, description, params) {
check(integration, Object);
check(description, String);
check(params, Object);
this.unblock();
// label activity did not work yet, see wekan/models/activities.js
const quoteParams = _.clone(params);
const clonedParams = _.clone(params);
[
'card',
'list',
'oldList',
'board',
'oldBoard',
'comment',
'checklist',
'swimlane',
'oldSwimlane',
'label',
'attachment',
].forEach(key => {
if (quoteParams[key]) quoteParams[key] = `"${params[key]}"`;
});
const userId = params.userId ? params.userId : integrations[0].userId;
const user = Users.findOne(userId);
const text = `${params.user} ${TAPi18n.__(
description,
quoteParams,
user.getLanguage(),
)}\n${params.url}`;
if (text.length === 0) return;
const value = {
text: `${text}`,
};
webhooksAtbts.forEach(key => {
if (params[key]) value[key] = params[key];
});
value.description = description;
//integrations.forEach(integration => {
const is2way = integration.type === Integrations.Const.TWOWAY;
const token = integration.token || '';
const headers = {
'Content-Type': 'application/json',
};
if (token) headers['X-Wekan-Token'] = token;
const options = {
headers,
data: is2way ? { description, ...clonedParams } : value,
};
const url = integration.url;
if (is2way) {
const cid = params.commentId;
const comment = params.comment;
const lockState = cid && Lock.has(cid, comment);
if (cid && lockState !== Lock.NULL) {
// it's a comment and there is a previous lock
return;
} else if (cid) {
Lock.set(cid, comment); // set a lock here
}
}
const response = postCatchError(url, options);
if (
response &&
response.statusCode &&
response.statusCode >= 200 &&
response.statusCode < 300
) {
if (is2way) {
const data = response.data; // only an JSON encoded response will be actioned
if (data) {
try {
responseFunc(data);
} catch (e) {
throw new Meteor.Error('error-process-data');
}
userId,
cardId,
boardId,
});
Lock.set(inserted._id, newComment);
}
}
return response; // eslint-disable-line consistent-return
} else {
throw new Meteor.Error('error-invalid-webhook-response');
}
//});
},
});
};
Meteor.methods({
outgoingWebhooks(integration, description, params) {
if (Meteor.user()) {
check(integration, Object);
check(description, String);
check(params, Object);
this.unblock();
// label activity did not work yet, see wekan/models/activities.js
const quoteParams = _.clone(params);
const clonedParams = _.clone(params);
[
'card',
'list',
'oldList',
'board',
'oldBoard',
'comment',
'checklist',
'swimlane',
'oldSwimlane',
'label',
'attachment',
].forEach(key => {
if (quoteParams[key]) quoteParams[key] = `"${params[key]}"`;
});
const userId = params.userId ? params.userId : integrations[0].userId;
const user = Users.findOne(userId);
const text = `${params.user} ${TAPi18n.__(
description,
quoteParams,
user.getLanguage(),
)}\n${params.url}`;
if (text.length === 0) return;
const value = {
text: `${text}`,
};
webhooksAtbts.forEach(key => {
if (params[key]) value[key] = params[key];
});
value.description = description;
//integrations.forEach(integration => {
const is2way = integration.type === Integrations.Const.TWOWAY;
const token = integration.token || '';
const headers = {
'Content-Type': 'application/json',
};
if (token) headers['X-Wekan-Token'] = token;
const options = {
headers,
data: is2way ? { description, ...clonedParams } : value,
};
if (!Integrations.findOne({ url: integration.url })) return;
const url = integration.url;
if (is2way) {
const cid = params.commentId;
const comment = params.comment;
const lockState = cid && Lock.has(cid, comment);
if (cid && lockState !== Lock.NULL) {
// it's a comment and there is a previous lock
return;
} else if (cid) {
Lock.set(cid, comment); // set a lock here
}
}
const response = postCatchError(url, options);
if (
response &&
response.statusCode &&
response.statusCode >= 200 &&
response.statusCode < 300
) {
if (is2way) {
const data = response.data; // only an JSON encoded response will be actioned
if (data) {
try {
responseFunc(data);
} catch (e) {
throw new Meteor.Error('error-process-data');
}
}
}
return response; // eslint-disable-line consistent-return
} else {
throw new Meteor.Error('error-invalid-webhook-response');
}
}
},
});
}
+1
View File
@@ -192,6 +192,7 @@ Meteor.publishRelations('board', function(boardId, isArchived) {
username: 1,
'profile.fullname': 1,
'profile.avatarUrl': 1,
'profile.initials': 1,
},
},
),
+1
View File
@@ -6,6 +6,7 @@ Meteor.publish('user-miniprofile', function(userId) {
username: 1,
'profile.fullname': 1,
'profile.avatarUrl': 1,
'profile.initials': 1,
},
});
});
+73 -65
View File
@@ -1,68 +1,76 @@
import { MongoInternals } from 'meteor/mongo';
Meteor.methods({
getStatistics() {
const os = require('os');
const pjson = require('/package.json');
const statistics = {};
let wekanVersion = pjson.version;
wekanVersion = wekanVersion.replace('v', '');
statistics.version = wekanVersion;
statistics.os = {
type: os.type(),
platform: os.platform(),
arch: os.arch(),
release: os.release(),
uptime: os.uptime(),
loadavg: os.loadavg(),
totalmem: os.totalmem(),
freemem: os.freemem(),
cpus: os.cpus(),
};
let nodeVersion = process.version;
nodeVersion = nodeVersion.replace('v', '');
statistics.process = {
nodeVersion,
pid: process.pid,
uptime: process.uptime(),
};
// Remove beginning of Meteor release text METEOR@
let meteorVersion = Meteor.release;
meteorVersion = meteorVersion.replace('METEOR@', '');
statistics.meteor = {
meteorVersion,
};
// Thanks to RocketChat for MongoDB version detection !
// https://github.com/RocketChat/Rocket.Chat/blob/develop/app/utils/server/functions/getMongoInfo.js
let mongoVersion;
let mongoStorageEngine;
let mongoOplogEnabled;
try {
const { mongo } = MongoInternals.defaultRemoteCollectionDriver();
oplogEnabled = Boolean(
mongo._oplogHandle && mongo._oplogHandle.onOplogEntry,
);
const { version, storageEngine } = Promise.await(
mongo.db.command({ serverStatus: 1 }),
);
mongoVersion = version;
mongoStorageEngine = storageEngine.name;
mongoOplogEnabled = oplogEnabled;
} catch (e) {
try {
const { version } = Promise.await(mongo.db.command({ buildinfo: 1 }));
mongoVersion = version;
mongoStorageEngine = 'unknown';
} catch (e) {
mongoVersion = 'unknown';
mongoStorageEngine = 'unknown';
if (Meteor.isServer) {
Meteor.methods({
getStatistics() {
if (Meteor.user() && Meteor.user().isAdmin) {
const os = require('os');
const pjson = require('/package.json');
const statistics = {};
let wekanVersion = pjson.version;
wekanVersion = wekanVersion.replace('v', '');
statistics.version = wekanVersion;
statistics.os = {
type: os.type(),
platform: os.platform(),
arch: os.arch(),
release: os.release(),
uptime: os.uptime(),
loadavg: os.loadavg(),
totalmem: os.totalmem(),
freemem: os.freemem(),
cpus: os.cpus(),
};
let nodeVersion = process.version;
nodeVersion = nodeVersion.replace('v', '');
statistics.process = {
nodeVersion,
pid: process.pid,
uptime: process.uptime(),
};
// Remove beginning of Meteor release text METEOR@
let meteorVersion = Meteor.release;
meteorVersion = meteorVersion.replace('METEOR@', '');
statistics.meteor = {
meteorVersion,
};
// Thanks to RocketChat for MongoDB version detection !
// https://github.com/RocketChat/Rocket.Chat/blob/develop/app/utils/server/functions/getMongoInfo.js
let mongoVersion;
let mongoStorageEngine;
let mongoOplogEnabled;
try {
const { mongo } = MongoInternals.defaultRemoteCollectionDriver();
oplogEnabled = Boolean(
mongo._oplogHandle && mongo._oplogHandle.onOplogEntry,
);
const { version, storageEngine } = Promise.await(
mongo.db.command({ serverStatus: 1 }),
);
mongoVersion = version;
mongoStorageEngine = storageEngine.name;
mongoOplogEnabled = oplogEnabled;
} catch (e) {
try {
const { version } = Promise.await(
mongo.db.command({ buildinfo: 1 }),
);
mongoVersion = version;
mongoStorageEngine = 'unknown';
} catch (e) {
mongoVersion = 'unknown';
mongoStorageEngine = 'unknown';
}
}
statistics.mongo = {
mongoVersion,
mongoStorageEngine,
mongoOplogEnabled,
};
return statistics;
} else {
return false;
}
}
statistics.mongo = {
mongoVersion,
mongoStorageEngine,
mongoOplogEnabled,
};
return statistics;
},
});
},
});
}
+1 -1
View File
@@ -206,7 +206,7 @@ parts:
meteor add standard-minifier-js --allow-superuser
meteor npm install --allow-superuser
meteor npm install --allow-superuser --save babel-runtime
meteor build .build --directory --allow-superuser
meteor build .build --directory --allow-superuser --exclude-archs web.browser.legacy,web.cordova
cp -f fix-download-unicode/cfs_access-point.txt .build/bundle/programs/server/packages/cfs_access-point.js
#Removed binary version of bcrypt because of security vulnerability that is not fixed yet.
#https://github.com/wekan/wekan/commit/4b2010213907c61b0e0482ab55abb06f6a668eac