Hotfix: Fix url link issues (#246)
This commit is contained in:
parent
15e8b4602f
commit
f5450b06e8
|
@ -90,7 +90,6 @@ func FileInfoFaster(opts FileOptions) (ExtendedFileInfo, error) {
|
||||||
return response, err
|
return response, err
|
||||||
}
|
}
|
||||||
opts.IsDir = isDir
|
opts.IsDir = isDir
|
||||||
|
|
||||||
// TODO : whats the best way to save trips to disk here?
|
// TODO : whats the best way to save trips to disk here?
|
||||||
// disabled using cache because its not clear if this is helping or hurting
|
// disabled using cache because its not clear if this is helping or hurting
|
||||||
// check if the file exists in the index
|
// check if the file exists in the index
|
||||||
|
|
|
@ -164,7 +164,7 @@ func (si *Index) makeIndexPath(subPath string) string {
|
||||||
if strings.HasPrefix(subPath, "./") {
|
if strings.HasPrefix(subPath, "./") {
|
||||||
subPath = strings.TrimPrefix(subPath, ".")
|
subPath = strings.TrimPrefix(subPath, ".")
|
||||||
}
|
}
|
||||||
if strings.HasPrefix(subPath, ".") || si.Root == subPath {
|
if si.Root == subPath || subPath == "." {
|
||||||
return "/"
|
return "/"
|
||||||
}
|
}
|
||||||
// clean path
|
// clean path
|
||||||
|
|
|
@ -110,3 +110,31 @@ func TestGetIndex(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestMakeIndexPath(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
subPath string
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
|
{"Root path returns slash", "/", "/"},
|
||||||
|
{"Dot-prefixed returns slash", ".", "/"},
|
||||||
|
{"Double-dot prefix ignored", "./", "/"},
|
||||||
|
{"Dot prefix followed by text", "./test", "/test"},
|
||||||
|
{"Dot prefix followed by text", ".test", "/.test"},
|
||||||
|
{"Hidden file at root", "/.test", "/.test"},
|
||||||
|
{"Trailing slash removed", "/test/", "/test"},
|
||||||
|
{"Subpath without root prefix", "/other/test", "/other/test"},
|
||||||
|
{"Complex nested paths", "/nested/path", "/nested/path"},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
si := &Index{Root: "/"}
|
||||||
|
result := si.makeIndexPath(tt.subPath)
|
||||||
|
if result != tt.expected {
|
||||||
|
t.Errorf("makeIndexPath(%q) = %q; want %q", tt.name, result, tt.expected)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { createURL, fetchURL, adjustedData } from "./utils";
|
import { fetchURL, adjustedData } from "./utils";
|
||||||
import { removePrefix, getApiPath } from "@/utils/url.js";
|
import { removePrefix, getApiPath } from "@/utils/url.js";
|
||||||
import { state } from "@/store";
|
import { state } from "@/store";
|
||||||
import { notify } from "@/notify";
|
import { notify } from "@/notify";
|
||||||
|
@ -64,7 +64,7 @@ export function download(format, ...files) {
|
||||||
fileargs = fileargs.substring(0, fileargs.length - 1);
|
fileargs = fileargs.substring(0, fileargs.length - 1);
|
||||||
}
|
}
|
||||||
const apiPath = getApiPath("api/raw", { path: path, files: fileargs, algo: format });
|
const apiPath = getApiPath("api/raw", { path: path, files: fileargs, algo: format });
|
||||||
const url = createURL(`${apiPath}`);
|
const url = window.origin+apiPath
|
||||||
window.open(url);
|
window.open(url);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
notify.showError(err.message || "Error downloading files");
|
notify.showError(err.message || "Error downloading files");
|
||||||
|
@ -153,13 +153,14 @@ export async function checksum(url, algo) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getDownloadURL(path, inline) {
|
export function getDownloadURL(path, inline) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const params = {
|
const params = {
|
||||||
path: removePrefix(path,"files"),
|
path: removePrefix(path,"files"),
|
||||||
...(inline && { inline: "true" }),
|
...(inline && { inline: "true" }),
|
||||||
};
|
};
|
||||||
const apiPath = getApiPath("api/raw", params);
|
const apiPath = getApiPath("api/raw", params);
|
||||||
return createURL(apiPath);
|
return window.origin+apiPath
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
notify.showError(err.message || "Error getting download URL");
|
notify.showError(err.message || "Error getting download URL");
|
||||||
throw err;
|
throw err;
|
||||||
|
@ -175,7 +176,7 @@ export function getPreviewURL(path, size, modified) {
|
||||||
inline: "true",
|
inline: "true",
|
||||||
};
|
};
|
||||||
const apiPath = getApiPath("api/preview", params);
|
const apiPath = getApiPath("api/preview", params);
|
||||||
return createURL(apiPath);
|
return window.origin+apiPath
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
notify.showError(err.message || "Error getting preview URL");
|
notify.showError(err.message || "Error getting preview URL");
|
||||||
throw err;
|
throw err;
|
||||||
|
@ -191,7 +192,7 @@ export function getSubtitlesURL(file) {
|
||||||
path: sub
|
path: sub
|
||||||
};
|
};
|
||||||
const apiPath = getApiPath("api/raw", params);
|
const apiPath = getApiPath("api/raw", params);
|
||||||
return createURL(apiPath);
|
return window.origin+apiPath
|
||||||
}
|
}
|
||||||
|
|
||||||
return subtitles;
|
return subtitles;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { createURL, adjustedData } from "./utils";
|
import { adjustedData } from "./utils";
|
||||||
import { getApiPath, removePrefix } from "@/utils/url.js";
|
import { getApiPath, removePrefix } from "@/utils/url.js";
|
||||||
import { notify } from "@/notify";
|
import { notify } from "@/notify";
|
||||||
|
|
||||||
|
@ -37,8 +37,7 @@ export function download(share, ...files) {
|
||||||
"files": fileInfo,
|
"files": fileInfo,
|
||||||
};
|
};
|
||||||
const apiPath = getApiPath("api/public/dl", params);
|
const apiPath = getApiPath("api/public/dl", params);
|
||||||
const url = createURL(apiPath);
|
window.open(window.origin+apiPath)
|
||||||
window.open(url);
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
notify.showError(err.message || "Error downloading files");
|
notify.showError(err.message || "Error downloading files");
|
||||||
throw err;
|
throw err;
|
||||||
|
@ -60,6 +59,5 @@ export async function getPublicUser() {
|
||||||
// Generate a download URL
|
// Generate a download URL
|
||||||
export function getDownloadURL(share) {
|
export function getDownloadURL(share) {
|
||||||
const apiPath = getApiPath("api/public/dl", share);
|
const apiPath = getApiPath("api/public/dl", share);
|
||||||
const url = createURL(apiPath)
|
return window.origin+apiPath
|
||||||
return url
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { fetchURL, fetchJSON, createURL, adjustedData } from "./utils";
|
import { fetchURL, fetchJSON, adjustedData } from "./utils";
|
||||||
import { notify } from "@/notify";
|
import { notify } from "@/notify";
|
||||||
import { getApiPath } from "@/utils/url.js";
|
import { getApiPath } from "@/utils/url.js";
|
||||||
|
|
||||||
|
@ -41,5 +41,5 @@ export async function create(path, password = "", expires = "", unit = "hours")
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getShareURL(share) {
|
export function getShareURL(share) {
|
||||||
return createURL("share/"+share.hash, {}, false);
|
return window.origin+getApiPath(`share/${share.hash}`);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import { state } from "@/store";
|
import { state } from "@/store";
|
||||||
import { renew, logout } from "@/utils/auth";
|
import { renew, logout } from "@/utils/auth";
|
||||||
import { baseURL } from "@/utils/constants";
|
|
||||||
import { notify } from "@/notify";
|
import { notify } from "@/notify";
|
||||||
|
|
||||||
export async function fetchURL(url, opts, auth = true) {
|
export async function fetchURL(url, opts, auth = true) {
|
||||||
|
@ -60,24 +59,6 @@ export async function fetchJSON(url, opts) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createURL(endpoint) {
|
|
||||||
let prefix = baseURL;
|
|
||||||
|
|
||||||
// Ensure prefix ends with a single slash
|
|
||||||
if (!prefix.endsWith("/")) {
|
|
||||||
prefix += "/";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove leading slash from endpoint to avoid duplicate slashes
|
|
||||||
if (endpoint.startsWith("/")) {
|
|
||||||
endpoint = endpoint.substring(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
const url = new URL(prefix + endpoint, window.location.origin);
|
|
||||||
|
|
||||||
return url.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
export function adjustedData(data, url) {
|
export function adjustedData(data, url) {
|
||||||
data.url = url;
|
data.url = url;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { describe, it, expect, vi } from 'vitest';
|
import { describe, it, expect, vi } from 'vitest';
|
||||||
import { adjustedData, createURL } from './utils.js';
|
import { adjustedData } from './utils.js';
|
||||||
|
|
||||||
describe('adjustedData', () => {
|
describe('adjustedData', () => {
|
||||||
it('should append the URL and process directory data correctly', () => {
|
it('should append the URL and process directory data correctly', () => {
|
||||||
|
@ -87,25 +87,6 @@ describe('adjustedData', () => {
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
describe('createURL', () => {
|
|
||||||
it('createURL', () => {
|
|
||||||
const url = "base";
|
|
||||||
const expected = "http://localhost:3000/unit-testing/base"
|
|
||||||
expect(createURL(url)).toEqual(expected);
|
|
||||||
});
|
|
||||||
it('createURL with slash', () => {
|
|
||||||
const url = "/base";
|
|
||||||
const expected = "http://localhost:3000/unit-testing/base"
|
|
||||||
expect(createURL(url)).toEqual(expected);
|
|
||||||
});
|
|
||||||
it('createURL with slash', () => {
|
|
||||||
const url = "/base";
|
|
||||||
const expected = "http://localhost:3000/unit-testing/base"
|
|
||||||
expect(createURL(url)).toEqual(expected);
|
|
||||||
});
|
|
||||||
})
|
|
||||||
|
|
||||||
vi.mock('@/utils/constants', () => {
|
vi.mock('@/utils/constants', () => {
|
||||||
return {
|
return {
|
||||||
baseURL: "unit-testing",
|
baseURL: "unit-testing",
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
<!-- List of search results -->
|
<!-- List of search results -->
|
||||||
<ul v-show="results.length > 0">
|
<ul v-show="results.length > 0">
|
||||||
<li v-for="(s, k) in results" :key="k" class="search-entry">
|
<li v-for="(s, k) in results" :key="k" class="search-entry">
|
||||||
<router-link :to="s.path">
|
<router-link :to="createPath(s.path)">
|
||||||
<i v-if="s.type == 'directory'" class="material-icons folder-icons">
|
<i v-if="s.type == 'directory'" class="material-icons folder-icons">
|
||||||
folder
|
folder
|
||||||
</i>
|
</i>
|
||||||
|
@ -181,7 +181,7 @@
|
||||||
<!-- List of search results -->
|
<!-- List of search results -->
|
||||||
<ul v-show="results.length > 0">
|
<ul v-show="results.length > 0">
|
||||||
<li v-for="(s, k) in results" :key="k" class="search-entry">
|
<li v-for="(s, k) in results" :key="k" class="search-entry">
|
||||||
<router-link :to="s.path">
|
<router-link :to="createPath(s.path)">
|
||||||
<i v-if="s.type == 'directory'" class="material-icons folder-icons">
|
<i v-if="s.type == 'directory'" class="material-icons folder-icons">
|
||||||
folder
|
folder
|
||||||
</i>
|
</i>
|
||||||
|
@ -209,11 +209,13 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import ButtonGroup from "./ButtonGroup.vue";
|
import ButtonGroup from "./ButtonGroup.vue";
|
||||||
import { search } from "@/api";
|
import { search } from "@/api";
|
||||||
import { getters, mutations, state } from "@/store";
|
import { getters, mutations, state } from "@/store";
|
||||||
import { getHumanReadableFilesize } from "@/utils/filesizes";
|
import { getHumanReadableFilesize } from "@/utils/filesizes";
|
||||||
|
import { getApiPath } from "@/utils/url";
|
||||||
|
|
||||||
var boxes = {
|
var boxes = {
|
||||||
folder: { label: "folders", icon: "folder" },
|
folder: { label: "folders", icon: "folder" },
|
||||||
|
@ -337,6 +339,9 @@ export default {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
createPath(path) {
|
||||||
|
return getApiPath(`files/${path}`)
|
||||||
|
},
|
||||||
humanSize(size) {
|
humanSize(size) {
|
||||||
return getHumanReadableFilesize(size);
|
return getHumanReadableFilesize(size);
|
||||||
},
|
},
|
||||||
|
|
|
@ -47,6 +47,9 @@ export default {
|
||||||
};
|
};
|
||||||
|
|
||||||
export function removePrefix(path, prefix) {
|
export function removePrefix(path, prefix) {
|
||||||
|
if (path === undefined) {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
if (prefix != "") {
|
if (prefix != "") {
|
||||||
prefix = "/" + trimSlashes(prefix)
|
prefix = "/" + trimSlashes(prefix)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue