mirror of
https://github.com/wekan/wekan.git
synced 2025-12-19 00:40:12 +01:00
Fixed Non-ASCII attachment filename will crash when downloading.
Thanks to xet7 ! Fixes #2759
This commit is contained in:
parent
843ff8eaaa
commit
c2da477735
277 changed files with 30568 additions and 52 deletions
199
packages/wekan-cfs-access-point/access-point-common.js
Normal file
199
packages/wekan-cfs-access-point/access-point-common.js
Normal file
|
|
@ -0,0 +1,199 @@
|
|||
rootUrlPathPrefix = __meteor_runtime_config__.ROOT_URL_PATH_PREFIX || "";
|
||||
// Adjust the rootUrlPathPrefix if necessary
|
||||
if (rootUrlPathPrefix.length > 0) {
|
||||
if (rootUrlPathPrefix.slice(0, 1) !== '/') {
|
||||
rootUrlPathPrefix = '/' + rootUrlPathPrefix;
|
||||
}
|
||||
if (rootUrlPathPrefix.slice(-1) === '/') {
|
||||
rootUrlPathPrefix = rootUrlPathPrefix.slice(0, -1);
|
||||
}
|
||||
}
|
||||
|
||||
// prepend ROOT_URL when isCordova
|
||||
if (Meteor.isCordova) {
|
||||
rootUrlPathPrefix = Meteor.absoluteUrl(rootUrlPathPrefix.replace(/^\/+/, '')).replace(/\/+$/, '');
|
||||
}
|
||||
|
||||
baseUrl = '/cfs';
|
||||
FS.HTTP = FS.HTTP || {};
|
||||
|
||||
// Note the upload URL so that client uploader packages know what it is
|
||||
FS.HTTP.uploadUrl = rootUrlPathPrefix + baseUrl + '/files';
|
||||
|
||||
/**
|
||||
* @method FS.HTTP.setBaseUrl
|
||||
* @public
|
||||
* @param {String} newBaseUrl - Change the base URL for the HTTP GET and DELETE endpoints.
|
||||
* @returns {undefined}
|
||||
*/
|
||||
FS.HTTP.setBaseUrl = function setBaseUrl(newBaseUrl) {
|
||||
|
||||
// Adjust the baseUrl if necessary
|
||||
if (newBaseUrl.slice(0, 1) !== '/') {
|
||||
newBaseUrl = '/' + newBaseUrl;
|
||||
}
|
||||
if (newBaseUrl.slice(-1) === '/') {
|
||||
newBaseUrl = newBaseUrl.slice(0, -1);
|
||||
}
|
||||
|
||||
// Update the base URL
|
||||
baseUrl = newBaseUrl;
|
||||
|
||||
// Change the upload URL so that client uploader packages know what it is
|
||||
FS.HTTP.uploadUrl = rootUrlPathPrefix + baseUrl + '/files';
|
||||
|
||||
// Remount URLs with the new baseUrl, unmounting the old, on the server only.
|
||||
// If existingMountPoints is empty, then we haven't run the server startup
|
||||
// code yet, so this new URL will be used at that point for the initial mount.
|
||||
if (Meteor.isServer && !FS.Utility.isEmpty(_existingMountPoints)) {
|
||||
mountUrls();
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* FS.File extensions
|
||||
*/
|
||||
|
||||
/**
|
||||
* @method FS.File.prototype.urlRelative Construct the file url
|
||||
* @public
|
||||
* @param {Object} [options]
|
||||
* @param {String} [options.store] Name of the store to get from. If not defined, the first store defined in `options.stores` for the collection on the client is used.
|
||||
* @param {Boolean} [options.auth=null] Add authentication token to the URL query string? By default, a token for the current logged in user is added on the client. Set this to `false` to omit the token. Set this to a string to provide your own token. Set this to a number to specify an expiration time for the token in seconds.
|
||||
* @param {Boolean} [options.download=false] Should headers be set to force a download? Typically this means that clicking the link with this URL will download the file to the user's Downloads folder instead of displaying the file in the browser.
|
||||
* @param {Boolean} [options.brokenIsFine=false] Return the URL even if we know it's currently a broken link because the file hasn't been saved in the requested store yet.
|
||||
* @param {Boolean} [options.returnWhenStored=false] Flag relevant only on server, Return the URL only when file has been saved to the requested store.
|
||||
* @param {Boolean} [options.metadata=false] Return the URL for the file metadata access point rather than the file itself.
|
||||
* @param {String} [options.uploading=null] A URL to return while the file is being uploaded.
|
||||
* @param {String} [options.storing=null] A URL to return while the file is being stored.
|
||||
* @param {String} [options.filename=null] Override the filename that should appear at the end of the URL. By default it is the name of the file in the requested store.
|
||||
*
|
||||
* Returns the relative HTTP URL for getting the file or its metadata.
|
||||
*/
|
||||
FS.File.prototype.urlRelative = function(options) {
|
||||
var self = this;
|
||||
options = options || {};
|
||||
options = FS.Utility.extend({
|
||||
store: null,
|
||||
auth: null,
|
||||
download: false,
|
||||
metadata: false,
|
||||
brokenIsFine: false,
|
||||
returnWhenStored: false,
|
||||
uploading: null, // return this URL while uploading
|
||||
storing: null, // return this URL while storing
|
||||
filename: null // override the filename that is shown to the user
|
||||
}, options.hash || options); // check for "hash" prop if called as helper
|
||||
|
||||
// Primarily useful for displaying a temporary image while uploading an image
|
||||
if (options.uploading && !self.isUploaded()) {
|
||||
return options.uploading;
|
||||
}
|
||||
|
||||
if (self.isMounted()) {
|
||||
// See if we've stored in the requested store yet
|
||||
var storeName = options.store || self.collection.primaryStore.name;
|
||||
if (!self.hasStored(storeName)) {
|
||||
if (options.storing) {
|
||||
return options.storing;
|
||||
} else if (!options.brokenIsFine) {
|
||||
// In case we want to get back the url only when he is stored
|
||||
if (Meteor.isServer && options.returnWhenStored) {
|
||||
// Wait till file is stored to storeName
|
||||
self.onStored(storeName);
|
||||
} else {
|
||||
// We want to return null if we know the URL will be a broken
|
||||
// link because then we can avoid rendering broken links, broken
|
||||
// images, etc.
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add filename to end of URL if we can determine one
|
||||
var filename = options.filename || self.name({store: storeName});
|
||||
if (typeof filename === "string" && filename.length) {
|
||||
filename = '/' + filename;
|
||||
} else {
|
||||
filename = '';
|
||||
}
|
||||
|
||||
// TODO: Could we somehow figure out if the collection requires login?
|
||||
var authToken = '';
|
||||
if (Meteor.isClient && typeof Accounts !== "undefined" && typeof Accounts._storedLoginToken === "function") {
|
||||
if (options.auth !== false) {
|
||||
// Add reactive deps on the user
|
||||
Meteor.userId();
|
||||
|
||||
var authObject = {
|
||||
authToken: Accounts._storedLoginToken() || ''
|
||||
};
|
||||
|
||||
// If it's a number, we use that as the expiration time (in seconds)
|
||||
if (options.auth === +options.auth) {
|
||||
authObject.expiration = FS.HTTP.now() + options.auth * 1000;
|
||||
}
|
||||
|
||||
// Set the authToken
|
||||
var authString = JSON.stringify(authObject);
|
||||
authToken = FS.Utility.btoa(authString);
|
||||
}
|
||||
} else if (typeof options.auth === "string") {
|
||||
// If the user supplies auth token the user will be responsible for
|
||||
// updating
|
||||
authToken = options.auth;
|
||||
}
|
||||
|
||||
// Construct query string
|
||||
var params = {};
|
||||
if (authToken !== '') {
|
||||
params.token = authToken;
|
||||
}
|
||||
if (options.download) {
|
||||
params.download = true;
|
||||
}
|
||||
if (options.store) {
|
||||
// We use options.store here instead of storeName because we want to omit the queryString
|
||||
// whenever possible, allowing users to have "clean" URLs if they want. The server will
|
||||
// assume the first store defined on the server, which means that we are assuming that
|
||||
// the first on the client is also the first on the server. If that's not the case, the
|
||||
// store option should be supplied.
|
||||
params.store = options.store;
|
||||
}
|
||||
var queryString = FS.Utility.encodeParams(params);
|
||||
if (queryString.length) {
|
||||
queryString = '?' + queryString;
|
||||
}
|
||||
|
||||
// Determine which URL to use
|
||||
var area;
|
||||
if (options.metadata) {
|
||||
area = '/record';
|
||||
} else {
|
||||
area = '/files';
|
||||
}
|
||||
|
||||
// Construct and return the http method url
|
||||
return baseUrl + area + '/' + self.collection.name + '/' + self._id + filename + queryString;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @method FS.File.prototype.url Construct the file url
|
||||
* @public
|
||||
* @param {Object} [options]
|
||||
* @param {String} [options.store] Name of the store to get from. If not defined, the first store defined in `options.stores` for the collection on the client is used.
|
||||
* @param {Boolean} [options.auth=null] Add authentication token to the URL query string? By default, a token for the current logged in user is added on the client. Set this to `false` to omit the token. Set this to a string to provide your own token. Set this to a number to specify an expiration time for the token in seconds.
|
||||
* @param {Boolean} [options.download=false] Should headers be set to force a download? Typically this means that clicking the link with this URL will download the file to the user's Downloads folder instead of displaying the file in the browser.
|
||||
* @param {Boolean} [options.brokenIsFine=false] Return the URL even if we know it's currently a broken link because the file hasn't been saved in the requested store yet.
|
||||
* @param {Boolean} [options.metadata=false] Return the URL for the file metadata access point rather than the file itself.
|
||||
* @param {String} [options.uploading=null] A URL to return while the file is being uploaded.
|
||||
* @param {String} [options.storing=null] A URL to return while the file is being stored.
|
||||
* @param {String} [options.filename=null] Override the filename that should appear at the end of the URL. By default it is the name of the file in the requested store.
|
||||
*
|
||||
* Returns the HTTP URL for getting the file or its metadata.
|
||||
*/
|
||||
FS.File.prototype.url = function(options) {
|
||||
self = this;
|
||||
return rootUrlPathPrefix + self.urlRelative(options);
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue