|
@@ -30,6 +30,7 @@ import content_type_to_icon from './helpers/content_type_to_icon.js';
|
|
|
import truncate_filename from './helpers/truncate_filename.js';
|
|
|
import UIWindowProgress from './UI/UIWindowProgress.js';
|
|
|
import launch_app from "./helpers/launch_app.js";
|
|
|
+import globToRegExp from "./helpers/globToRegExp.js";
|
|
|
|
|
|
window.is_auth = ()=>{
|
|
|
if(localStorage.getItem("auth_token") === null || window.auth_token === null)
|
|
@@ -162,203 +163,6 @@ window.scrollParentToChild = (parent, child)=>{
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-window.getItem = async function(options){
|
|
|
- return $.ajax({
|
|
|
- url: window.api_origin + "/getItem",
|
|
|
- type: 'POST',
|
|
|
- data: JSON.stringify({
|
|
|
- key: options.key,
|
|
|
- app: options.app_uid,
|
|
|
- }),
|
|
|
- async: true,
|
|
|
- contentType: "application/json",
|
|
|
- headers: {
|
|
|
- "Authorization": "Bearer "+window.auth_token
|
|
|
- },
|
|
|
- statusCode: {
|
|
|
- 401: function () {
|
|
|
- window.logout();
|
|
|
- },
|
|
|
- },
|
|
|
- success: function (result){
|
|
|
- if(options.success && typeof(options.success) === "function")
|
|
|
- options.success(result);
|
|
|
- }
|
|
|
- })
|
|
|
-}
|
|
|
-
|
|
|
-window.setItem = async function(options){
|
|
|
- return $.ajax({
|
|
|
- url: window.api_origin + "/setItem",
|
|
|
- type: 'POST',
|
|
|
- data: JSON.stringify({
|
|
|
- app: options.app_uid,
|
|
|
- key: options.key,
|
|
|
- value: options.value,
|
|
|
- }),
|
|
|
- async: true,
|
|
|
- contentType: "application/json",
|
|
|
- headers: {
|
|
|
- "Authorization": "Bearer "+window.auth_token
|
|
|
- },
|
|
|
- statusCode: {
|
|
|
- 401: function () {
|
|
|
- window.logout();
|
|
|
- },
|
|
|
- },
|
|
|
- success: function (fsentry){
|
|
|
- if(options.success && typeof(options.success) === "function")
|
|
|
- options.success(fsentry)
|
|
|
- }
|
|
|
- })
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- * Converts a glob pattern to a regular expression, with optional extended or globstar matching.
|
|
|
- *
|
|
|
- * @param {string} glob - The glob pattern to convert.
|
|
|
- * @param {Object} [opts] - Optional options for the conversion.
|
|
|
- * @param {boolean} [opts.extended=false] - If true, enables extended matching with single character matching, character ranges, group matching, etc.
|
|
|
- * @param {boolean} [opts.globstar=false] - If true, uses globstar matching, where '*' matches zero or more path segments.
|
|
|
- * @param {string} [opts.flags] - Regular expression flags to include (e.g., 'i' for case-insensitive).
|
|
|
- * @returns {RegExp} The generated regular expression.
|
|
|
- * @throws {TypeError} If the provided glob pattern is not a string.
|
|
|
- */
|
|
|
-window.globToRegExp = function (glob, opts) {
|
|
|
- if (typeof glob !== 'string') {
|
|
|
- throw new TypeError('Expected a string');
|
|
|
- }
|
|
|
-
|
|
|
- var str = String(glob);
|
|
|
-
|
|
|
- // The regexp we are building, as a string.
|
|
|
- var reStr = "";
|
|
|
-
|
|
|
- // Whether we are matching so called "extended" globs (like bash) and should
|
|
|
- // support single character matching, matching ranges of characters, group
|
|
|
- // matching, etc.
|
|
|
- var extended = opts ? !!opts.extended : false;
|
|
|
-
|
|
|
- // When globstar is _false_ (default), '/foo/*' is translated a regexp like
|
|
|
- // '^\/foo\/.*$' which will match any string beginning with '/foo/'
|
|
|
- // When globstar is _true_, '/foo/*' is translated to regexp like
|
|
|
- // '^\/foo\/[^/]*$' which will match any string beginning with '/foo/' BUT
|
|
|
- // which does not have a '/' to the right of it.
|
|
|
- // E.g. with '/foo/*' these will match: '/foo/bar', '/foo/bar.txt' but
|
|
|
- // these will not '/foo/bar/baz', '/foo/bar/baz.txt'
|
|
|
- // Lastely, when globstar is _true_, '/foo/**' is equivelant to '/foo/*' when
|
|
|
- // globstar is _false_
|
|
|
- var globstar = opts ? !!opts.globstar : false;
|
|
|
-
|
|
|
- // If we are doing extended matching, this boolean is true when we are inside
|
|
|
- // a group (eg {*.html,*.js}), and false otherwise.
|
|
|
- var inGroup = false;
|
|
|
-
|
|
|
- // RegExp flags (eg "i" ) to pass in to RegExp constructor.
|
|
|
- var flags = opts && typeof (opts.flags) === "string" ? opts.flags : "";
|
|
|
-
|
|
|
- var c;
|
|
|
- for (var i = 0, len = str.length; i < len; i++) {
|
|
|
- c = str[i];
|
|
|
-
|
|
|
- switch (c) {
|
|
|
- case "/":
|
|
|
- case "$":
|
|
|
- case "^":
|
|
|
- case "+":
|
|
|
- case ".":
|
|
|
- case "(":
|
|
|
- case ")":
|
|
|
- case "=":
|
|
|
- case "!":
|
|
|
- case "|":
|
|
|
- reStr += "\\" + c;
|
|
|
- break;
|
|
|
-
|
|
|
- case "?":
|
|
|
- if (extended) {
|
|
|
- reStr += ".";
|
|
|
- break;
|
|
|
- }
|
|
|
- // fallthrough
|
|
|
-
|
|
|
- case "[":
|
|
|
- case "]":
|
|
|
- if (extended) {
|
|
|
- reStr += c;
|
|
|
- break;
|
|
|
- }
|
|
|
- // fallthrough
|
|
|
-
|
|
|
- case "{":
|
|
|
- if (extended) {
|
|
|
- inGroup = true;
|
|
|
- reStr += "(";
|
|
|
- break;
|
|
|
- }
|
|
|
- // fallthrough
|
|
|
-
|
|
|
- case "}":
|
|
|
- if (extended) {
|
|
|
- inGroup = false;
|
|
|
- reStr += ")";
|
|
|
- break;
|
|
|
- }
|
|
|
- // fallthrough
|
|
|
-
|
|
|
- case ",":
|
|
|
- if (inGroup) {
|
|
|
- reStr += "|";
|
|
|
- break;
|
|
|
- }
|
|
|
- reStr += "\\" + c;
|
|
|
- break;
|
|
|
-
|
|
|
- case "*":
|
|
|
- // Move over all consecutive "*"'s.
|
|
|
- // Also store the previous and next characters
|
|
|
- var prevChar = str[i - 1];
|
|
|
- var starCount = 1;
|
|
|
- while (str[i + 1] === "*") {
|
|
|
- starCount++;
|
|
|
- i++;
|
|
|
- }
|
|
|
- var nextChar = str[i + 1];
|
|
|
-
|
|
|
- if (!globstar) {
|
|
|
- // globstar is disabled, so treat any number of "*" as one
|
|
|
- reStr += ".*";
|
|
|
- } else {
|
|
|
- // globstar is enabled, so determine if this is a globstar segment
|
|
|
- var isGlobstar = starCount > 1 // multiple "*"'s
|
|
|
- && (prevChar === "/" || prevChar === undefined) // from the start of the segment
|
|
|
- && (nextChar === "/" || nextChar === undefined) // to the end of the segment
|
|
|
-
|
|
|
- if (isGlobstar) {
|
|
|
- // it's a globstar, so match zero or more path segments
|
|
|
- reStr += "((?:[^/]*(?:/|$))*)";
|
|
|
- i++; // move over the "/"
|
|
|
- } else {
|
|
|
- // it's not a globstar, so only match one path segment
|
|
|
- reStr += "([^/]*)";
|
|
|
- }
|
|
|
- }
|
|
|
- break;
|
|
|
-
|
|
|
- default:
|
|
|
- reStr += c;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // When regexp 'g' flag is specified don't
|
|
|
- // constrain the regular expression with ^ & $
|
|
|
- if (!flags || !~flags.indexOf('g')) {
|
|
|
- reStr = "^" + reStr + "$";
|
|
|
- }
|
|
|
-
|
|
|
- return new RegExp(reStr, flags);
|
|
|
-};
|
|
|
-
|
|
|
/**
|
|
|
* Validates the provided file system entry name.
|
|
|
*
|
|
@@ -488,7 +292,7 @@ window.check_fsentry_against_allowed_file_types_string =function (fsentry, allow
|
|
|
}
|
|
|
|
|
|
// MIME types (e.g. text/plain)
|
|
|
- else if(window.globToRegExp(allowed_file_type).test(fsentry.type?.toLowerCase())){
|
|
|
+ else if(globToRegExp(allowed_file_type).test(fsentry.type?.toLowerCase())){
|
|
|
passes_allowed_file_type_filter = true;
|
|
|
break;
|
|
|
}
|
|
@@ -1014,64 +818,65 @@ window.item_icon = async (fsentry)=>{
|
|
|
*/
|
|
|
|
|
|
window.show_save_account_notice_if_needed = function(message){
|
|
|
- window.getItem({
|
|
|
+ puter.kv.get({
|
|
|
key: "save_account_notice_shown",
|
|
|
- success: async function(value){
|
|
|
- if(!value && window.user?.is_temp){
|
|
|
- window.setItem({key: "save_account_notice_shown", value: true});
|
|
|
+ }).then(async function(value){
|
|
|
+ if(!value && window.user?.is_temp){
|
|
|
+ puter.kv.set({
|
|
|
+ key: "save_account_notice_shown",
|
|
|
+ value: true,
|
|
|
+ });
|
|
|
+ // Show the notice
|
|
|
+ setTimeout(async () => {
|
|
|
+ const alert_resp = await UIAlert({
|
|
|
+ message: message ?? `<strong>Congrats on storing data!</strong><p>Don't forget to save your session! You are in a temporary session. Save session to avoid accidentally losing your work.</p>`,
|
|
|
+ body_icon: window.icons['reminder.svg'],
|
|
|
+ buttons:[
|
|
|
+ {
|
|
|
+ label: i18n('save_session'),
|
|
|
+ value: 'save-session',
|
|
|
+ type: 'primary',
|
|
|
+ },
|
|
|
+ // {
|
|
|
+ // label: 'Log into an existing account',
|
|
|
+ // value: 'login',
|
|
|
+ // },
|
|
|
+ {
|
|
|
+ label: `I'll do it later`,
|
|
|
+ value: 'remind-later',
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ window_options: {
|
|
|
+ backdrop: true,
|
|
|
+ close_on_backdrop_click: false,
|
|
|
+ }
|
|
|
+
|
|
|
+ })
|
|
|
+
|
|
|
+ if(alert_resp === 'remind-later'){
|
|
|
+ // TODO
|
|
|
+ }
|
|
|
+ if(alert_resp === 'save-session'){
|
|
|
+ let saved = await UIWindowSaveAccount({
|
|
|
+ send_confirmation_code: false,
|
|
|
+ });
|
|
|
|
|
|
- // Show the notice
|
|
|
- setTimeout(async () => {
|
|
|
- const alert_resp = await UIAlert({
|
|
|
- message: message ?? `<strong>Congrats on storing data!</strong><p>Don't forget to save your session! You are in a temporary session. Save session to avoid accidentally losing your work.</p>`,
|
|
|
- body_icon: window.icons['reminder.svg'],
|
|
|
- buttons:[
|
|
|
- {
|
|
|
- label: i18n('save_session'),
|
|
|
- value: 'save-session',
|
|
|
- type: 'primary',
|
|
|
- },
|
|
|
- // {
|
|
|
- // label: 'Log into an existing account',
|
|
|
- // value: 'login',
|
|
|
- // },
|
|
|
- {
|
|
|
- label: `I'll do it later`,
|
|
|
- value: 'remind-later',
|
|
|
- },
|
|
|
- ],
|
|
|
+ }else if (alert_resp === 'login'){
|
|
|
+ let login_result = await UIWindowLogin({
|
|
|
+ show_signup_button: false,
|
|
|
+ reload_on_success: true,
|
|
|
+ send_confirmation_code: false,
|
|
|
window_options: {
|
|
|
+ show_in_taskbar: false,
|
|
|
backdrop: true,
|
|
|
close_on_backdrop_click: false,
|
|
|
}
|
|
|
-
|
|
|
- })
|
|
|
-
|
|
|
- if(alert_resp === 'remind-later'){
|
|
|
- // TODO
|
|
|
- }
|
|
|
- if(alert_resp === 'save-session'){
|
|
|
- let saved = await UIWindowSaveAccount({
|
|
|
- send_confirmation_code: false,
|
|
|
- });
|
|
|
-
|
|
|
- }else if (alert_resp === 'login'){
|
|
|
- let login_result = await UIWindowLogin({
|
|
|
- show_signup_button: false,
|
|
|
- reload_on_success: true,
|
|
|
- send_confirmation_code: false,
|
|
|
- window_options: {
|
|
|
- show_in_taskbar: false,
|
|
|
- backdrop: true,
|
|
|
- close_on_backdrop_click: false,
|
|
|
- }
|
|
|
- });
|
|
|
- // FIXME: Report login error.
|
|
|
- }
|
|
|
- }, window.desktop_loading_fade_delay + 1000);
|
|
|
- }
|
|
|
+ });
|
|
|
+ // FIXME: Report login error.
|
|
|
+ }
|
|
|
+ }, window.desktop_loading_fade_delay + 1000);
|
|
|
}
|
|
|
- })
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
window.onpopstate = (event) => {
|