access-point-common.js 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. rootUrlPathPrefix = __meteor_runtime_config__.ROOT_URL_PATH_PREFIX || "";
  2. // Adjust the rootUrlPathPrefix if necessary
  3. if (rootUrlPathPrefix.length > 0) {
  4. if (rootUrlPathPrefix.slice(0, 1) !== '/') {
  5. rootUrlPathPrefix = '/' + rootUrlPathPrefix;
  6. }
  7. if (rootUrlPathPrefix.slice(-1) === '/') {
  8. rootUrlPathPrefix = rootUrlPathPrefix.slice(0, -1);
  9. }
  10. }
  11. // prepend ROOT_URL when isCordova
  12. if (Meteor.isCordova) {
  13. rootUrlPathPrefix = Meteor.absoluteUrl(rootUrlPathPrefix.replace(/^\/+/, '')).replace(/\/+$/, '');
  14. }
  15. baseUrl = '/cfs';
  16. FS.HTTP = FS.HTTP || {};
  17. // Note the upload URL so that client uploader packages know what it is
  18. FS.HTTP.uploadUrl = rootUrlPathPrefix + baseUrl + '/files';
  19. /**
  20. * @method FS.HTTP.setBaseUrl
  21. * @public
  22. * @param {String} newBaseUrl - Change the base URL for the HTTP GET and DELETE endpoints.
  23. * @returns {undefined}
  24. */
  25. FS.HTTP.setBaseUrl = function setBaseUrl(newBaseUrl) {
  26. // Adjust the baseUrl if necessary
  27. if (newBaseUrl.slice(0, 1) !== '/') {
  28. newBaseUrl = '/' + newBaseUrl;
  29. }
  30. if (newBaseUrl.slice(-1) === '/') {
  31. newBaseUrl = newBaseUrl.slice(0, -1);
  32. }
  33. // Update the base URL
  34. baseUrl = newBaseUrl;
  35. // Change the upload URL so that client uploader packages know what it is
  36. FS.HTTP.uploadUrl = rootUrlPathPrefix + baseUrl + '/files';
  37. // Remount URLs with the new baseUrl, unmounting the old, on the server only.
  38. // If existingMountPoints is empty, then we haven't run the server startup
  39. // code yet, so this new URL will be used at that point for the initial mount.
  40. if (Meteor.isServer && !FS.Utility.isEmpty(_existingMountPoints)) {
  41. mountUrls();
  42. }
  43. };
  44. /*
  45. * FS.File extensions
  46. */
  47. /**
  48. * @method FS.File.prototype.urlRelative Construct the file url
  49. * @public
  50. * @param {Object} [options]
  51. * @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.
  52. * @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.
  53. * @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.
  54. * @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.
  55. * @param {Boolean} [options.returnWhenStored=false] Flag relevant only on server, Return the URL only when file has been saved to the requested store.
  56. * @param {Boolean} [options.metadata=false] Return the URL for the file metadata access point rather than the file itself.
  57. * @param {String} [options.uploading=null] A URL to return while the file is being uploaded.
  58. * @param {String} [options.storing=null] A URL to return while the file is being stored.
  59. * @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.
  60. *
  61. * Returns the relative HTTP URL for getting the file or its metadata.
  62. */
  63. FS.File.prototype.urlRelative = function(options) {
  64. var self = this;
  65. options = options || {};
  66. options = FS.Utility.extend({
  67. store: null,
  68. auth: null,
  69. download: false,
  70. metadata: false,
  71. brokenIsFine: false,
  72. returnWhenStored: false,
  73. uploading: null, // return this URL while uploading
  74. storing: null, // return this URL while storing
  75. filename: null // override the filename that is shown to the user
  76. }, options.hash || options); // check for "hash" prop if called as helper
  77. // Primarily useful for displaying a temporary image while uploading an image
  78. if (options.uploading && !self.isUploaded()) {
  79. return options.uploading;
  80. }
  81. if (self.isMounted()) {
  82. // See if we've stored in the requested store yet
  83. var storeName = options.store || self.collection.primaryStore.name;
  84. if (!self.hasStored(storeName)) {
  85. if (options.storing) {
  86. return options.storing;
  87. } else if (!options.brokenIsFine) {
  88. // In case we want to get back the url only when he is stored
  89. if (Meteor.isServer && options.returnWhenStored) {
  90. // Wait till file is stored to storeName
  91. self.onStored(storeName);
  92. } else {
  93. // We want to return null if we know the URL will be a broken
  94. // link because then we can avoid rendering broken links, broken
  95. // images, etc.
  96. return null;
  97. }
  98. }
  99. }
  100. // Add filename to end of URL if we can determine one
  101. var filename = options.filename || self.name({store: storeName});
  102. if (typeof filename === "string" && filename.length) {
  103. filename = '/' + filename;
  104. } else {
  105. filename = '';
  106. }
  107. // TODO: Could we somehow figure out if the collection requires login?
  108. var authToken = '';
  109. if (Meteor.isClient && typeof Accounts !== "undefined" && typeof Accounts._storedLoginToken === "function") {
  110. if (options.auth !== false) {
  111. // Add reactive deps on the user
  112. Meteor.userId();
  113. var authObject = {
  114. authToken: Accounts._storedLoginToken() || ''
  115. };
  116. // If it's a number, we use that as the expiration time (in seconds)
  117. if (options.auth === +options.auth) {
  118. authObject.expiration = FS.HTTP.now() + options.auth * 1000;
  119. }
  120. // Set the authToken
  121. var authString = JSON.stringify(authObject);
  122. authToken = FS.Utility.btoa(authString);
  123. }
  124. } else if (typeof options.auth === "string") {
  125. // If the user supplies auth token the user will be responsible for
  126. // updating
  127. authToken = options.auth;
  128. }
  129. // Construct query string
  130. var params = {};
  131. if (authToken !== '') {
  132. params.token = authToken;
  133. }
  134. if (options.download) {
  135. params.download = true;
  136. }
  137. if (options.store) {
  138. // We use options.store here instead of storeName because we want to omit the queryString
  139. // whenever possible, allowing users to have "clean" URLs if they want. The server will
  140. // assume the first store defined on the server, which means that we are assuming that
  141. // the first on the client is also the first on the server. If that's not the case, the
  142. // store option should be supplied.
  143. params.store = options.store;
  144. }
  145. var queryString = FS.Utility.encodeParams(params);
  146. if (queryString.length) {
  147. queryString = '?' + queryString;
  148. }
  149. // Determine which URL to use
  150. var area;
  151. if (options.metadata) {
  152. area = '/record';
  153. } else {
  154. area = '/files';
  155. }
  156. // Construct and return the http method url
  157. return baseUrl + area + '/' + self.collection.name + '/' + self._id + filename + queryString;
  158. }
  159. };
  160. /**
  161. * @method FS.File.prototype.url Construct the file url
  162. * @public
  163. * @param {Object} [options]
  164. * @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.
  165. * @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.
  166. * @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.
  167. * @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.
  168. * @param {Boolean} [options.metadata=false] Return the URL for the file metadata access point rather than the file itself.
  169. * @param {String} [options.uploading=null] A URL to return while the file is being uploaded.
  170. * @param {String} [options.storing=null] A URL to return while the file is being stored.
  171. * @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.
  172. *
  173. * Returns the HTTP URL for getting the file or its metadata.
  174. */
  175. FS.File.prototype.url = function(options) {
  176. self = this;
  177. return rootUrlPathPrefix + self.urlRelative(options);
  178. };