Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1a7ee618be | ||
|
|
405e0b9bb2 | ||
|
|
d3e37d2912 | ||
|
|
2859457600 | ||
|
|
4857bce5d9 | ||
|
|
16dbbfa98c | ||
|
|
67d23ff8ae | ||
|
|
30680f13d6 | ||
|
|
3b526cad40 | ||
|
|
55f0ac959a | ||
|
|
6dc515210a | ||
|
|
7777dd3b45 | ||
|
|
e9a874144d | ||
|
|
77b5244723 | ||
|
|
af560bc9b4 | ||
|
|
c569565ec0 | ||
|
|
80f1222af4 | ||
|
|
76ff965619 | ||
|
|
2ca01b589f |
No files matched your search
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "wekan",
|
||||
"version": "v3.12.0",
|
||||
"version": "v3.14.0",
|
||||
"description": "Open-Source kanban",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
@@ -53,16 +53,21 @@
|
||||
"prettier-eslint": "^8.8.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.1.2",
|
||||
"@babel/runtime": "^7.5.4",
|
||||
"ajv": "^5.0.0",
|
||||
"babel-runtime": "^6.26.0",
|
||||
"bson-ext": "^2.0.0",
|
||||
"bcrypt": "^3.0.2",
|
||||
"bson": "^4.0.0",
|
||||
"bunyan": "^1.8.12",
|
||||
"es6-promise": "^4.2.4",
|
||||
"hoek": "^5.0.4",
|
||||
"gridfs-stream": "^0.5.3",
|
||||
"ldapjs": "^1.0.2",
|
||||
"meteor-node-stubs": "^0.4.1",
|
||||
"mongodb": "^2.2.19",
|
||||
"os": "^0.1.1",
|
||||
"page": "^1.8.6",
|
||||
"qs": "^6.5.2",
|
||||
"source-map-support": "^0.5.9",
|
||||
"source-map-support": "^0.5.12",
|
||||
"xss": "^1.0.6"
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,29 @@
|
||||
# v3.14 2019-08-11 Wekan release
|
||||
|
||||
This release adds the following new features:
|
||||
|
||||
- [On wekan master specifying ATTACHMENTS_STORE_PATH, it will try its best keeping original attachments, only newer
|
||||
attachments will be stored into specified path](https://github.com/wekan/wekan/pull/2607).
|
||||
Thanks to whowillcare.
|
||||
- [Made image upload in summernote as attachment to wekan board instead of base64 string,
|
||||
which would make the comments use less bytes and be able to take advantage of using local file system feature
|
||||
as attachment](https://github.com/wekan/wekan/pull/2608).
|
||||
Thanks to whowillcare.
|
||||
|
||||
and fixes the following bugs:
|
||||
|
||||
- [Fix bug: Unable to disable richer comment editor](https://github.com/wekan/wekan/pull/2607).
|
||||
Thanks to whowillcare.
|
||||
- [Changed rm to rm -f in wekan snap build, and add packages that somehow didn't get install during snapcraft
|
||||
build](https://github.com/wekan/wekan/pull/2608).
|
||||
Thanks to whowillcare.
|
||||
|
||||
Thanks to above GitHub users for their contributions and translators for their translations.
|
||||
|
||||
# v3.13 2019-08-09 Wekan release
|
||||
|
||||
Update translations. Thanks to translators.
|
||||
|
||||
# v3.12 2019-08-09 Wekan release
|
||||
|
||||
This release adds the following new features:
|
||||
@@ -9,9 +35,15 @@ This release adds the following new features:
|
||||
server admin switchs to this setting, their old attachments won't be available
|
||||
anymore, unless someone make a script to export them out to the filesystem.
|
||||
Thanks to whowillcare.
|
||||
- [Allowing user to insert video, link and image, or paste in html with sanitization.
|
||||
In user comments display area, images can be clicked and shown as
|
||||
swipebox](https://github.com/wekan/wekan/pull/2593).
|
||||
Thanks to whowillcare.
|
||||
|
||||
and fixes the following bugs:
|
||||
|
||||
- [Fix comment-editor marking issue](https://github.com/wekan/wekan/issues/2575).
|
||||
Thanks to whowillcare.
|
||||
- [Bugfix: style kbd font color became white after introduced summernote editor
|
||||
to card comments](https://github.com/wekan/wekan/pull/2600).
|
||||
Thanks to whowillcare.
|
||||
|
||||
@@ -22,6 +22,7 @@ ENV BUILD_DEPS="apt-utils bsdtar gnupg gosu wget curl bzip2 g++ build-essential
|
||||
ACCOUNTS_LOCKOUT_UNKNOWN_USERS_LOCKOUT_PERIOD=60 \
|
||||
ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURE_WINDOW=15 \
|
||||
RICHER_CARD_COMMENT_EDITOR=true \
|
||||
ATTACHMENTS_STORE_PATH="" \
|
||||
MAX_IMAGE_PIXEL="" \
|
||||
IMAGE_COMPRESS_RATIO="" \
|
||||
BIGEVENTS_PATTERN="" \
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
appId: wekan-public/apps/77b94f60-dec9-0136-304e-16ff53095928
|
||||
appVersion: "v3.12.0"
|
||||
appVersion: "v3.14.0"
|
||||
files:
|
||||
userUploads:
|
||||
- README.md
|
||||
|
||||
@@ -55,27 +55,12 @@ Template.cardAttachmentsPopup.events({
|
||||
'change .js-attach-file'(event) {
|
||||
const card = this;
|
||||
const processFile = f => {
|
||||
const file = new FS.File(f);
|
||||
if (card.isLinkedCard()) {
|
||||
file.boardId = Cards.findOne(card.linkedId).boardId;
|
||||
file.cardId = card.linkedId;
|
||||
} else {
|
||||
file.boardId = card.boardId;
|
||||
file.swimlaneId = card.swimlaneId;
|
||||
file.listId = card.listId;
|
||||
file.cardId = card._id;
|
||||
}
|
||||
file.userId = Meteor.userId();
|
||||
if (file.original) {
|
||||
file.original.name = f.name;
|
||||
}
|
||||
const attachment = Attachments.insert(file);
|
||||
|
||||
if (attachment && attachment._id && attachment.isImage()) {
|
||||
card.setCover(attachment._id);
|
||||
}
|
||||
|
||||
Popup.close();
|
||||
Utils.processUploadedAttachment(card, f, attachment => {
|
||||
if (attachment && attachment._id && attachment.isImage()) {
|
||||
card.setCover(attachment._id);
|
||||
}
|
||||
Popup.close();
|
||||
});
|
||||
};
|
||||
|
||||
FS.Utility.eachFile(event, f => {
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
import _sanitizeXss from 'xss';
|
||||
const enableRicherEditor =
|
||||
Meteor.settings.public.RICHER_CARD_COMMENT_EDITOR || true;
|
||||
const sanitizeXss = (input, options) => {
|
||||
const defaultAllowedIframeSrc = /^(https:){0,1}\/\/.*?(youtube|vimeo|dailymotion|youku)/i;
|
||||
const allowedIframeSrcRegex = (function() {
|
||||
@@ -104,7 +102,7 @@ Template.editor.onRendered(() => {
|
||||
autosize($textarea);
|
||||
$textarea.escapeableTextComplete(mentions);
|
||||
};
|
||||
if (enableRicherEditor) {
|
||||
if (Meteor.settings.public.RICHER_CARD_COMMENT_EDITOR !== false) {
|
||||
const isSmall = Utils.isMiniScreen();
|
||||
const toolbar = isSmall
|
||||
? [
|
||||
@@ -178,36 +176,71 @@ Template.editor.onRendered(() => {
|
||||
const $summernote = getSummernote(this);
|
||||
if (files && files.length > 0) {
|
||||
const image = files[0];
|
||||
const reader = new FileReader();
|
||||
const currentCard = Cards.findOne(Session.get('currentCard'));
|
||||
const MAX_IMAGE_PIXEL = Utils.MAX_IMAGE_PIXEL;
|
||||
const COMPRESS_RATIO = Utils.IMAGE_COMPRESS_RATIO;
|
||||
const processData = function(dataURL) {
|
||||
const insertImage = src => {
|
||||
const img = document.createElement('img');
|
||||
img.src = dataURL;
|
||||
img.src = src;
|
||||
img.setAttribute('width', '100%');
|
||||
$summernote.summernote('insertNode', img);
|
||||
};
|
||||
reader.onload = function(e) {
|
||||
const dataurl = e && e.target && e.target.result;
|
||||
if (dataurl !== undefined) {
|
||||
if (MAX_IMAGE_PIXEL) {
|
||||
const processData = function(fileObj) {
|
||||
Utils.processUploadedAttachment(
|
||||
currentCard,
|
||||
fileObj,
|
||||
attachment => {
|
||||
if (
|
||||
attachment &&
|
||||
attachment._id &&
|
||||
attachment.isImage()
|
||||
) {
|
||||
attachment.one('uploaded', function() {
|
||||
const maxTry = 3;
|
||||
const checkItvl = 500;
|
||||
let retry = 0;
|
||||
const checkUrl = function() {
|
||||
// even though uploaded event fired, attachment.url() is still null somehow //TODO
|
||||
const url = attachment.url();
|
||||
if (url) {
|
||||
insertImage(url);
|
||||
} else {
|
||||
retry++;
|
||||
if (retry < maxTry) {
|
||||
setTimeout(checkUrl, checkItvl);
|
||||
}
|
||||
}
|
||||
};
|
||||
checkUrl();
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
};
|
||||
if (MAX_IMAGE_PIXEL) {
|
||||
const reader = new FileReader();
|
||||
reader.onload = function(e) {
|
||||
const dataurl = e && e.target && e.target.result;
|
||||
if (dataurl !== undefined) {
|
||||
// need to shrink image
|
||||
Utils.shrinkImage({
|
||||
dataurl,
|
||||
maxSize: MAX_IMAGE_PIXEL,
|
||||
ratio: COMPRESS_RATIO,
|
||||
callback(changed) {
|
||||
if (changed !== false && !!changed) {
|
||||
processData(changed);
|
||||
toBlob: true,
|
||||
callback(blob) {
|
||||
if (blob !== false) {
|
||||
blob.name = image.name;
|
||||
processData(blob);
|
||||
}
|
||||
},
|
||||
});
|
||||
} else {
|
||||
processData(dataurl);
|
||||
}
|
||||
}
|
||||
};
|
||||
reader.readAsDataURL(image);
|
||||
};
|
||||
reader.readAsDataURL(image);
|
||||
} else {
|
||||
processData(image);
|
||||
}
|
||||
}
|
||||
},
|
||||
onPaste() {
|
||||
|
||||
@@ -26,6 +26,31 @@ Utils = {
|
||||
|
||||
MAX_IMAGE_PIXEL: Meteor.settings.public.MAX_IMAGE_PIXEL,
|
||||
COMPRESS_RATIO: Meteor.settings.public.IMAGE_COMPRESS_RATIO,
|
||||
processUploadedAttachment(card, fileObj, callback) {
|
||||
const next = attachment => {
|
||||
if (typeof callback === 'function') {
|
||||
callback(attachment);
|
||||
}
|
||||
};
|
||||
if (!card) {
|
||||
return next();
|
||||
}
|
||||
const file = new FS.File(fileObj);
|
||||
if (card.isLinkedCard()) {
|
||||
file.boardId = Cards.findOne(card.linkedId).boardId;
|
||||
file.cardId = card.linkedId;
|
||||
} else {
|
||||
file.boardId = card.boardId;
|
||||
file.swimlaneId = card.swimlaneId;
|
||||
file.listId = card.listId;
|
||||
file.cardId = card._id;
|
||||
}
|
||||
file.userId = Meteor.userId();
|
||||
if (file.original) {
|
||||
file.original.name = fileObj.name;
|
||||
}
|
||||
return next(Attachments.insert(file));
|
||||
},
|
||||
shrinkImage(options) {
|
||||
// shrink image to certain size
|
||||
const dataurl = options.dataurl,
|
||||
|
||||
@@ -232,6 +232,10 @@ services:
|
||||
#- ACCOUNTS_LOCKOUT_UNKNOWN_USERS_LOCKOUT_PERIOD=60
|
||||
#- ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURE_WINDOW=15
|
||||
#---------------------------------------------------------------
|
||||
# ==== STORE ATTACHMENT ON SERVER FILESYSTEM INSTEAD OF MONGODB ====
|
||||
# https://github.com/wekan/wekan/pull/2603
|
||||
#- ATTACHMENTS_STORE_PATH = <pathname> # pathname can be relative or fullpath
|
||||
#---------------------------------------------------------------
|
||||
# ==== RICH TEXT EDITOR IN CARD COMMENTS ====
|
||||
# https://github.com/wekan/wekan/pull/2560
|
||||
- RICHER_CARD_COMMENT_EDITOR=true
|
||||
|
||||
+162
-20
@@ -10,27 +10,169 @@ const defaultStoreOptions = {
|
||||
return {};
|
||||
},
|
||||
};
|
||||
const Store = localFSStore
|
||||
? new FS.Store.FileSystem(storeName, {
|
||||
path: localFSStore,
|
||||
...defaultStoreOptions,
|
||||
})
|
||||
: new FS.Store.GridFS(storeName, {
|
||||
// XXX Add a new store for cover thumbnails so we don't load big images in
|
||||
// the general board view
|
||||
// If the uploaded document is not an image we need to enforce browser
|
||||
// download instead of execution. This is particularly important for HTML
|
||||
// files that the browser will just execute if we don't serve them with the
|
||||
// appropriate `application/octet-stream` MIME header which can lead to user
|
||||
// data leaks. I imagine other formats (like PDF) can also be attack vectors.
|
||||
// See https://github.com/wekan/wekan/issues/99
|
||||
// XXX Should we use `beforeWrite` option of CollectionFS instead of
|
||||
// collection-hooks?
|
||||
// We should use `beforeWrite`.
|
||||
...defaultStoreOptions,
|
||||
});
|
||||
let store;
|
||||
if (localFSStore) {
|
||||
// have to reinvent methods from FS.Store.GridFS and FS.Store.FileSystem
|
||||
const fs = Npm.require('fs');
|
||||
const path = Npm.require('path');
|
||||
const mongodb = Npm.require('mongodb');
|
||||
const Grid = Npm.require('gridfs-stream');
|
||||
// calulate the absolute path here, because FS.Store.FileSystem didn't expose the aboslutepath or FS.Store didn't expose api calls :(
|
||||
let pathname = localFSStore;
|
||||
/*eslint camelcase: ["error", {allow: ["__meteor_bootstrap__"]}] */
|
||||
|
||||
if (!pathname && __meteor_bootstrap__ && __meteor_bootstrap__.serverDir) {
|
||||
pathname = path.join(
|
||||
__meteor_bootstrap__.serverDir,
|
||||
`../../../cfs/files/${storeName}`,
|
||||
);
|
||||
}
|
||||
|
||||
if (!pathname)
|
||||
throw new Error('FS.Store.FileSystem unable to determine path');
|
||||
|
||||
// Check if we have '~/foo/bar'
|
||||
if (pathname.split(path.sep)[0] === '~') {
|
||||
const homepath =
|
||||
process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE;
|
||||
if (homepath) {
|
||||
pathname = pathname.replace('~', homepath);
|
||||
} else {
|
||||
throw new Error('FS.Store.FileSystem unable to resolve "~" in path');
|
||||
}
|
||||
}
|
||||
|
||||
// Set absolute path
|
||||
const absolutePath = path.resolve(pathname);
|
||||
|
||||
const _FStore = new FS.Store.FileSystem(storeName, {
|
||||
path: localFSStore,
|
||||
...defaultStoreOptions,
|
||||
});
|
||||
const GStore = {
|
||||
fileKey(fileObj) {
|
||||
const key = {
|
||||
_id: null,
|
||||
filename: null,
|
||||
};
|
||||
|
||||
// If we're passed a fileObj, we retrieve the _id and filename from it.
|
||||
if (fileObj) {
|
||||
const info = fileObj._getInfo(storeName, {
|
||||
updateFileRecordFirst: false,
|
||||
});
|
||||
key._id = info.key || null;
|
||||
key.filename =
|
||||
info.name ||
|
||||
fileObj.name({ updateFileRecordFirst: false }) ||
|
||||
`${fileObj.collectionName}-${fileObj._id}`;
|
||||
}
|
||||
|
||||
// If key._id is null at this point, createWriteStream will let GridFS generate a new ID
|
||||
return key;
|
||||
},
|
||||
db: undefined,
|
||||
mongoOptions: { useNewUrlParser: true },
|
||||
mongoUrl: process.env.MONGO_URL,
|
||||
init() {
|
||||
this._init(err => {
|
||||
this.inited = !err;
|
||||
});
|
||||
},
|
||||
_init(callback) {
|
||||
const self = this;
|
||||
mongodb.MongoClient.connect(self.mongoUrl, self.mongoOptions, function(
|
||||
err,
|
||||
db,
|
||||
) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
self.db = db;
|
||||
return callback(null);
|
||||
});
|
||||
return;
|
||||
},
|
||||
createReadStream(fileKey, options) {
|
||||
const self = this;
|
||||
if (!self.inited) {
|
||||
self.init();
|
||||
return undefined;
|
||||
}
|
||||
options = options || {};
|
||||
|
||||
// Init GridFS
|
||||
const gfs = new Grid(self.db, mongodb);
|
||||
|
||||
// Set the default streamning settings
|
||||
const settings = {
|
||||
_id: new mongodb.ObjectID(fileKey._id),
|
||||
root: `cfs_gridfs.${storeName}`,
|
||||
};
|
||||
|
||||
// Check if this should be a partial read
|
||||
if (
|
||||
typeof options.start !== 'undefined' &&
|
||||
typeof options.end !== 'undefined'
|
||||
) {
|
||||
// Add partial info
|
||||
settings.range = {
|
||||
startPos: options.start,
|
||||
endPos: options.end,
|
||||
};
|
||||
}
|
||||
return gfs.createReadStream(settings);
|
||||
},
|
||||
};
|
||||
GStore.init();
|
||||
const CRS = 'createReadStream';
|
||||
const _CRS = `_${CRS}`;
|
||||
const FStore = _FStore._transform;
|
||||
FStore[_CRS] = FStore[CRS].bind(FStore);
|
||||
FStore[CRS] = function(fileObj, options) {
|
||||
let stream;
|
||||
try {
|
||||
const localFile = path.join(
|
||||
absolutePath,
|
||||
FStore.storage.fileKey(fileObj),
|
||||
);
|
||||
const state = fs.statSync(localFile);
|
||||
if (state) {
|
||||
stream = FStore[_CRS](fileObj, options);
|
||||
}
|
||||
} catch (e) {
|
||||
// file is not there, try GridFS ?
|
||||
stream = undefined;
|
||||
}
|
||||
if (stream) return stream;
|
||||
else {
|
||||
try {
|
||||
const stream = GStore[CRS](GStore.fileKey(fileObj), options);
|
||||
return stream;
|
||||
} catch (e) {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
}.bind(FStore);
|
||||
store = _FStore;
|
||||
} else {
|
||||
store = new FS.Store.GridFS(localFSStore ? `G${storeName}` : storeName, {
|
||||
// XXX Add a new store for cover thumbnails so we don't load big images in
|
||||
// the general board view
|
||||
// If the uploaded document is not an image we need to enforce browser
|
||||
// download instead of execution. This is particularly important for HTML
|
||||
// files that the browser will just execute if we don't serve them with the
|
||||
// appropriate `application/octet-stream` MIME header which can lead to user
|
||||
// data leaks. I imagine other formats (like PDF) can also be attack vectors.
|
||||
// See https://github.com/wekan/wekan/issues/99
|
||||
// XXX Should we use `beforeWrite` option of CollectionFS instead of
|
||||
// collection-hooks?
|
||||
// We should use `beforeWrite`.
|
||||
...defaultStoreOptions,
|
||||
});
|
||||
}
|
||||
Attachments = new FS.Collection('attachments', {
|
||||
stores: [Store],
|
||||
stores: [store],
|
||||
});
|
||||
|
||||
if (Meteor.isServer) {
|
||||
|
||||
+4
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "wekan",
|
||||
"version": "v3.12.0",
|
||||
"version": "v3.14.0",
|
||||
"description": "Open-Source kanban",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
@@ -55,12 +55,15 @@
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.5.4",
|
||||
"ajv": "^5.0.0",
|
||||
"babel-runtime": "^6.26.0",
|
||||
"bcrypt": "^3.0.2",
|
||||
"bson": "^4.0.0",
|
||||
"bunyan": "^1.8.12",
|
||||
"es6-promise": "^4.2.4",
|
||||
"gridfs-stream": "^0.5.3",
|
||||
"ldapjs": "^1.0.2",
|
||||
"meteor-node-stubs": "^0.4.1",
|
||||
"mongodb": "^2.2.19",
|
||||
"os": "^0.1.1",
|
||||
"page": "^1.8.6",
|
||||
"qs": "^6.5.2",
|
||||
|
||||
@@ -22,10 +22,10 @@ const pkgdef :Spk.PackageDefinition = (
|
||||
appTitle = (defaultText = "Wekan"),
|
||||
# The name of the app as it is displayed to the user.
|
||||
|
||||
appVersion = 314,
|
||||
appVersion = 316,
|
||||
# Increment this for every release.
|
||||
|
||||
appMarketingVersion = (defaultText = "3.12.0~2019-08-09"),
|
||||
appMarketingVersion = (defaultText = "3.14.0~2019-08-11"),
|
||||
# Human-readable presentation of the app version.
|
||||
|
||||
minUpgradableAppVersion = 0,
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
Meteor.startup(() => {
|
||||
const RCCE = process.env.RICHER_CARD_COMMENT_EDITOR;
|
||||
if (RCCE) {
|
||||
Meteor.settings.public.RICHER_CARD_COMMENT_EDITOR = RCCE !== 'false';
|
||||
}
|
||||
});
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
# All supported keys are defined here together with descriptions and default values
|
||||
|
||||
# list of supported keys
|
||||
keys="DEBUG MONGO_URL MONGODB_BIND_UNIX_SOCKET MONGO_URL MONGODB_BIND_IP MONGODB_PORT MAIL_URL MAIL_FROM ROOT_URL PORT DISABLE_MONGODB CADDY_ENABLED CADDY_BIND_PORT WITH_API RICHER_CARD_COMMENT_EDITOR ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURES_BEFORE ACCOUNTS_LOCKOUT_KNOWN_USERS_PERIOD ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURE_WINDOW ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURES_BERORE ACCOUNTS_LOCKOUT_UNKNOWN_USERS_LOCKOUT_PERIOD ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURE_WINDOW MAX_IMAGE_PIXEL IMAGE_COMPRESS_RATIO BIGEVENTS_PATTERN NOTIFY_DUE_DAYS_BEFORE_AND_AFTER NOTIFY_DUE_AT_HOUR_OF_DAY EMAIL_NOTIFICATION_TIMEOUT CORS CORS_ALLOW_HEADERS CORS_EXPOSE_HEADERS MATOMO_ADDRESS MATOMO_SITE_ID MATOMO_DO_NOT_TRACK MATOMO_WITH_USERNAME BROWSER_POLICY_ENABLED TRUSTED_URL WEBHOOKS_ATTRIBUTES OAUTH2_ENABLED OAUTH2_LOGIN_STYLE OAUTH2_CLIENT_ID OAUTH2_SECRET OAUTH2_SERVER_URL OAUTH2_AUTH_ENDPOINT OAUTH2_USERINFO_ENDPOINT OAUTH2_TOKEN_ENDPOINT OAUTH2_ID_MAP OAUTH2_USERNAME_MAP OAUTH2_FULLNAME_MAP OAUTH2_ID_TOKEN_WHITELIST_FIELDS OAUTH2_EMAIL_MAP OAUTH2_REQUEST_PERMISSIONS LDAP_ENABLE LDAP_PORT LDAP_HOST LDAP_BASEDN LDAP_LOGIN_FALLBACK LDAP_RECONNECT LDAP_TIMEOUT LDAP_IDLE_TIMEOUT LDAP_CONNECT_TIMEOUT LDAP_AUTHENTIFICATION LDAP_AUTHENTIFICATION_USERDN LDAP_AUTHENTIFICATION_PASSWORD LDAP_LOG_ENABLED LDAP_BACKGROUND_SYNC LDAP_BACKGROUND_SYNC_INTERVAL LDAP_BACKGROUND_SYNC_KEEP_EXISTANT_USERS_UPDATED LDAP_BACKGROUND_SYNC_IMPORT_NEW_USERS LDAP_ENCRYPTION LDAP_CA_CERT LDAP_REJECT_UNAUTHORIZED LDAP_USER_AUTHENTICATION LDAP_USER_AUTHENTICATION_FIELD LDAP_USER_SEARCH_FILTER LDAP_USER_SEARCH_SCOPE LDAP_USER_SEARCH_FIELD LDAP_SEARCH_PAGE_SIZE LDAP_SEARCH_SIZE_LIMIT LDAP_GROUP_FILTER_ENABLE LDAP_GROUP_FILTER_OBJECTCLASS LDAP_GROUP_FILTER_GROUP_ID_ATTRIBUTE LDAP_GROUP_FILTER_GROUP_MEMBER_ATTRIBUTE LDAP_GROUP_FILTER_GROUP_MEMBER_FORMAT LDAP_GROUP_FILTER_GROUP_NAME LDAP_UNIQUE_IDENTIFIER_FIELD LDAP_UTF8_NAMES_SLUGIFY LDAP_USERNAME_FIELD LDAP_FULLNAME_FIELD LDAP_MERGE_EXISTING_USERS LDAP_SYNC_USER_DATA LDAP_SYNC_USER_DATA_FIELDMAP LDAP_SYNC_GROUP_ROLES LDAP_DEFAULT_DOMAIN LDAP_EMAIL_MATCH_ENABLE LDAP_EMAIL_MATCH_REQUIRE LDAP_EMAIL_MATCH_VERIFIED LDAP_EMAIL_FIELD LDAP_SYNC_ADMIN_STATUS LDAP_SYNC_ADMIN_GROUPS HEADER_LOGIN_ID HEADER_LOGIN_FIRSTNAME HEADER_LOGIN_LASTNAME HEADER_LOGIN_EMAIL LOGOUT_WITH_TIMER LOGOUT_IN LOGOUT_ON_HOURS LOGOUT_ON_MINUTES DEFAULT_AUTHENTICATION_METHOD"
|
||||
keys="DEBUG MONGO_URL MONGODB_BIND_UNIX_SOCKET MONGO_URL MONGODB_BIND_IP MONGODB_PORT MAIL_URL MAIL_FROM ROOT_URL PORT DISABLE_MONGODB CADDY_ENABLED CADDY_BIND_PORT WITH_API RICHER_CARD_COMMENT_EDITOR ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURES_BEFORE ACCOUNTS_LOCKOUT_KNOWN_USERS_PERIOD ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURE_WINDOW ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURES_BERORE ACCOUNTS_LOCKOUT_UNKNOWN_USERS_LOCKOUT_PERIOD ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURE_WINDOW MAX_IMAGE_PIXEL IMAGE_COMPRESS_RATIO BIGEVENTS_PATTERN NOTIFY_DUE_DAYS_BEFORE_AND_AFTER NOTIFY_DUE_AT_HOUR_OF_DAY EMAIL_NOTIFICATION_TIMEOUT CORS CORS_ALLOW_HEADERS CORS_EXPOSE_HEADERS MATOMO_ADDRESS MATOMO_SITE_ID MATOMO_DO_NOT_TRACK MATOMO_WITH_USERNAME BROWSER_POLICY_ENABLED TRUSTED_URL WEBHOOKS_ATTRIBUTES OAUTH2_ENABLED OAUTH2_LOGIN_STYLE OAUTH2_CLIENT_ID OAUTH2_SECRET OAUTH2_SERVER_URL OAUTH2_AUTH_ENDPOINT OAUTH2_USERINFO_ENDPOINT OAUTH2_TOKEN_ENDPOINT OAUTH2_ID_MAP OAUTH2_USERNAME_MAP OAUTH2_FULLNAME_MAP OAUTH2_ID_TOKEN_WHITELIST_FIELDS OAUTH2_EMAIL_MAP OAUTH2_REQUEST_PERMISSIONS LDAP_ENABLE LDAP_PORT LDAP_HOST LDAP_BASEDN LDAP_LOGIN_FALLBACK LDAP_RECONNECT LDAP_TIMEOUT LDAP_IDLE_TIMEOUT LDAP_CONNECT_TIMEOUT LDAP_AUTHENTIFICATION LDAP_AUTHENTIFICATION_USERDN LDAP_AUTHENTIFICATION_PASSWORD LDAP_LOG_ENABLED LDAP_BACKGROUND_SYNC LDAP_BACKGROUND_SYNC_INTERVAL LDAP_BACKGROUND_SYNC_KEEP_EXISTANT_USERS_UPDATED LDAP_BACKGROUND_SYNC_IMPORT_NEW_USERS LDAP_ENCRYPTION LDAP_CA_CERT LDAP_REJECT_UNAUTHORIZED LDAP_USER_AUTHENTICATION LDAP_USER_AUTHENTICATION_FIELD LDAP_USER_SEARCH_FILTER LDAP_USER_SEARCH_SCOPE LDAP_USER_SEARCH_FIELD LDAP_SEARCH_PAGE_SIZE LDAP_SEARCH_SIZE_LIMIT LDAP_GROUP_FILTER_ENABLE LDAP_GROUP_FILTER_OBJECTCLASS LDAP_GROUP_FILTER_GROUP_ID_ATTRIBUTE LDAP_GROUP_FILTER_GROUP_MEMBER_ATTRIBUTE LDAP_GROUP_FILTER_GROUP_MEMBER_FORMAT LDAP_GROUP_FILTER_GROUP_NAME LDAP_UNIQUE_IDENTIFIER_FIELD LDAP_UTF8_NAMES_SLUGIFY LDAP_USERNAME_FIELD LDAP_FULLNAME_FIELD LDAP_MERGE_EXISTING_USERS LDAP_SYNC_USER_DATA LDAP_SYNC_USER_DATA_FIELDMAP LDAP_SYNC_GROUP_ROLES LDAP_DEFAULT_DOMAIN LDAP_EMAIL_MATCH_ENABLE LDAP_EMAIL_MATCH_REQUIRE LDAP_EMAIL_MATCH_VERIFIED LDAP_EMAIL_FIELD LDAP_SYNC_ADMIN_STATUS LDAP_SYNC_ADMIN_GROUPS HEADER_LOGIN_ID HEADER_LOGIN_FIRSTNAME HEADER_LOGIN_LASTNAME HEADER_LOGIN_EMAIL LOGOUT_WITH_TIMER LOGOUT_IN LOGOUT_ON_HOURS LOGOUT_ON_MINUTES DEFAULT_AUTHENTICATION_METHOD ATTACHMENTS_STORE_PATH"
|
||||
|
||||
# default values
|
||||
DESCRIPTION_DEBUG="Debug OIDC OAuth2 etc. Example: sudo snap set wekan debug='true'"
|
||||
|
||||
@@ -81,6 +81,12 @@ echo -e "\t$ snap set $SNAP_NAME image-compress-ratio='80'"
|
||||
echo -e "Disabled:"
|
||||
echo -e "\t$ snap set $SNAP_NAME image-compress-ratio=''"
|
||||
echo -e "\n"
|
||||
echo -e "Allow to set attachment upload into specified server location. Create that directory first. https://github.com/wekan/wekan/pull/2603"
|
||||
echo -e "Example:"
|
||||
echo -e "\t$ snap set $SNAP_NAME attachments-store-path='/var/snap/wekan/common/attachments'"
|
||||
echo -e "Disabled:"
|
||||
echo -e "\t$ snap set $SNAP_NAME attachments-store-path=''"
|
||||
echo -e "\n"
|
||||
echo -e "BIGEVENTS DUE ETC NOTIFICATIONS https://github.com/wekan/wekan/pull/2541"
|
||||
echo -e "Big events pattern: Notify always due etc regardless of notification settings. Default: due, All: received|start|due|end, Disabled: NONE"
|
||||
echo -e "Default:"
|
||||
|
||||
+6
-4
@@ -201,6 +201,7 @@ parts:
|
||||
rm -rf package-lock.json .build
|
||||
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
|
||||
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.
|
||||
@@ -214,15 +215,16 @@ parts:
|
||||
# Change to directory .build/bundle/programs/server
|
||||
cd .build/bundle/programs/server
|
||||
npm install
|
||||
npm install --allow-superuser --save babel-runtime
|
||||
#meteor npm install --save bcrypt
|
||||
# Change back to Wekan source directory
|
||||
cd ../../../..
|
||||
cp -r .build/bundle/* $SNAPCRAFT_PART_INSTALL/
|
||||
cp .build/bundle/.node_version.txt $SNAPCRAFT_PART_INSTALL/
|
||||
rm $SNAPCRAFT_PART_INSTALL/lib/node_modules/wekan
|
||||
rm $SNAPCRAFT_PART_INSTALL/programs/server/npm/node_modules/meteor/rajit_bootstrap3-datepicker/lib/bootstrap-datepicker/node_modules/phantomjs-prebuilt/lib/phantom/bin/phantomjs
|
||||
rm $SNAPCRAFT_PART_INSTALL/lib/node_modules/node-pre-gyp/node_modules/tar/lib/.mkdir.js.swp
|
||||
rm $SNAPCRAFT_PART_INSTALL/lib/node_modules/node-gyp/node_modules/tar/lib/.mkdir.js.swp
|
||||
rm -f $SNAPCRAFT_PART_INSTALL/lib/node_modules/wekan
|
||||
rm -f $SNAPCRAFT_PART_INSTALL/programs/server/npm/node_modules/meteor/rajit_bootstrap3-datepicker/lib/bootstrap-datepicker/node_modules/phantomjs-prebuilt/lib/phantom/bin/phantomjs
|
||||
rm -f $SNAPCRAFT_PART_INSTALL/lib/node_modules/node-pre-gyp/node_modules/tar/lib/.mkdir.js.swp
|
||||
rm -f $SNAPCRAFT_PART_INSTALL/lib/node_modules/node-gyp/node_modules/tar/lib/.mkdir.js.swp
|
||||
organize:
|
||||
README: README.wekan
|
||||
prime:
|
||||
|
||||
Reference in new issue
Block a user