Merge pull request #1942 from ramiresviana/fixes-12
commit
1d66bbe40a
|
@ -322,7 +322,7 @@ func (i *FileInfo) readListing(checker rules.Checker, readHeader bool) error {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
isSymlink := false
|
isSymlink, isInvalidLink := false, false
|
||||||
if IsSymlink(f.Mode()) {
|
if IsSymlink(f.Mode()) {
|
||||||
isSymlink = true
|
isSymlink = true
|
||||||
// It's a symbolic link. We try to follow it. If it doesn't work,
|
// It's a symbolic link. We try to follow it. If it doesn't work,
|
||||||
|
@ -330,6 +330,8 @@ func (i *FileInfo) readListing(checker rules.Checker, readHeader bool) error {
|
||||||
info, err := i.Fs.Stat(fPath)
|
info, err := i.Fs.Stat(fPath)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
f = info
|
f = info
|
||||||
|
} else {
|
||||||
|
isInvalidLink = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -350,9 +352,13 @@ func (i *FileInfo) readListing(checker rules.Checker, readHeader bool) error {
|
||||||
} else {
|
} else {
|
||||||
listing.NumFiles++
|
listing.NumFiles++
|
||||||
|
|
||||||
err := file.detectType(true, false, readHeader)
|
if isInvalidLink {
|
||||||
if err != nil {
|
file.Type = "invalid_link"
|
||||||
return err
|
} else {
|
||||||
|
err := file.detectType(true, false, readHeader)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { fetchURL, removePrefix } from "./utils";
|
import { fetchURL, removePrefix, createURL } from "./utils";
|
||||||
import { baseURL } from "@/utils/constants";
|
import { baseURL } from "@/utils/constants";
|
||||||
import store from "@/store";
|
import store from "@/store";
|
||||||
|
|
||||||
|
@ -7,28 +7,24 @@ export async function fetch(url) {
|
||||||
|
|
||||||
const res = await fetchURL(`/api/resources${url}`, {});
|
const res = await fetchURL(`/api/resources${url}`, {});
|
||||||
|
|
||||||
if (res.status === 200) {
|
let data = await res.json();
|
||||||
let data = await res.json();
|
data.url = `/files${url}`;
|
||||||
data.url = `/files${url}`;
|
|
||||||
|
|
||||||
if (data.isDir) {
|
if (data.isDir) {
|
||||||
if (!data.url.endsWith("/")) data.url += "/";
|
if (!data.url.endsWith("/")) data.url += "/";
|
||||||
data.items = data.items.map((item, index) => {
|
data.items = data.items.map((item, index) => {
|
||||||
item.index = index;
|
item.index = index;
|
||||||
item.url = `${data.url}${encodeURIComponent(item.name)}`;
|
item.url = `${data.url}${encodeURIComponent(item.name)}`;
|
||||||
|
|
||||||
if (item.isDir) {
|
if (item.isDir) {
|
||||||
item.url += "/";
|
item.url += "/";
|
||||||
}
|
}
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
return data;
|
|
||||||
} else {
|
|
||||||
throw new Error(res.status);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function resourceAction(url, method, content) {
|
async function resourceAction(url, method, content) {
|
||||||
|
@ -42,11 +38,7 @@ async function resourceAction(url, method, content) {
|
||||||
|
|
||||||
const res = await fetchURL(`/api/resources${url}`, opts);
|
const res = await fetchURL(`/api/resources${url}`, opts);
|
||||||
|
|
||||||
if (res.status !== 200) {
|
return res;
|
||||||
throw new Error(await res.text());
|
|
||||||
} else {
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function remove(url) {
|
export async function remove(url) {
|
||||||
|
@ -119,8 +111,8 @@ export async function post(url, content = "", overwrite = false, onupload) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
request.onerror = (error) => {
|
request.onerror = () => {
|
||||||
reject(error);
|
reject(new Error("001 Connection aborted"));
|
||||||
};
|
};
|
||||||
|
|
||||||
request.send(bufferContent || content);
|
request.send(bufferContent || content);
|
||||||
|
@ -154,3 +146,33 @@ export async function checksum(url, algo) {
|
||||||
const data = await resourceAction(`${url}?checksum=${algo}`, "GET");
|
const data = await resourceAction(`${url}?checksum=${algo}`, "GET");
|
||||||
return (await data.json()).checksums[algo];
|
return (await data.json()).checksums[algo];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getDownloadURL(file, inline) {
|
||||||
|
const params = {
|
||||||
|
...(inline && { inline: "true" }),
|
||||||
|
};
|
||||||
|
|
||||||
|
return createURL("api/raw" + file.path, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getPreviewURL(file, size) {
|
||||||
|
const params = {
|
||||||
|
inline: "true",
|
||||||
|
key: Date.parse(file.modified),
|
||||||
|
};
|
||||||
|
|
||||||
|
return createURL("api/preview/" + size + file.path, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getSubtitlesURL(file) {
|
||||||
|
const params = {
|
||||||
|
inline: "true",
|
||||||
|
};
|
||||||
|
|
||||||
|
const subtitles = [];
|
||||||
|
for (const sub of file.subtitles) {
|
||||||
|
subtitles.push(createURL("api/raw" + sub, params));
|
||||||
|
}
|
||||||
|
|
||||||
|
return subtitles;
|
||||||
|
}
|
||||||
|
|
|
@ -1,35 +1,35 @@
|
||||||
import { fetchURL, removePrefix } from "./utils";
|
import { fetchURL, removePrefix, createURL } from "./utils";
|
||||||
import { baseURL } from "@/utils/constants";
|
import { baseURL } from "@/utils/constants";
|
||||||
|
|
||||||
export async function fetch(url, password = "") {
|
export async function fetch(url, password = "") {
|
||||||
url = removePrefix(url);
|
url = removePrefix(url);
|
||||||
|
|
||||||
const res = await fetchURL(`/api/public/share${url}`, {
|
const res = await fetchURL(
|
||||||
headers: { "X-SHARE-PASSWORD": encodeURIComponent(password) },
|
`/api/public/share${url}`,
|
||||||
});
|
{
|
||||||
|
headers: { "X-SHARE-PASSWORD": encodeURIComponent(password) },
|
||||||
|
},
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
if (res.status === 200) {
|
let data = await res.json();
|
||||||
let data = await res.json();
|
data.url = `/share${url}`;
|
||||||
data.url = `/share${url}`;
|
|
||||||
|
|
||||||
if (data.isDir) {
|
if (data.isDir) {
|
||||||
if (!data.url.endsWith("/")) data.url += "/";
|
if (!data.url.endsWith("/")) data.url += "/";
|
||||||
data.items = data.items.map((item, index) => {
|
data.items = data.items.map((item, index) => {
|
||||||
item.index = index;
|
item.index = index;
|
||||||
item.url = `${data.url}${encodeURIComponent(item.name)}`;
|
item.url = `${data.url}${encodeURIComponent(item.name)}`;
|
||||||
|
|
||||||
if (item.isDir) {
|
if (item.isDir) {
|
||||||
item.url += "/";
|
item.url += "/";
|
||||||
}
|
}
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
return data;
|
|
||||||
} else {
|
|
||||||
throw new Error(res.status);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function download(format, hash, token, ...files) {
|
export function download(format, hash, token, ...files) {
|
||||||
|
@ -59,3 +59,12 @@ export function download(format, hash, token, ...files) {
|
||||||
|
|
||||||
window.open(url);
|
window.open(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getDownloadURL(share, inline = false) {
|
||||||
|
const params = {
|
||||||
|
...(inline && { inline: "true" }),
|
||||||
|
...(share.token && { token: share.token }),
|
||||||
|
};
|
||||||
|
|
||||||
|
return createURL("api/public/dl/" + share.hash + share.path, params, false);
|
||||||
|
}
|
||||||
|
|
|
@ -11,21 +11,17 @@ export default async function search(base, query) {
|
||||||
|
|
||||||
let res = await fetchURL(`/api/search${base}?query=${query}`, {});
|
let res = await fetchURL(`/api/search${base}?query=${query}`, {});
|
||||||
|
|
||||||
if (res.status === 200) {
|
let data = await res.json();
|
||||||
let data = await res.json();
|
|
||||||
|
|
||||||
data = data.map((item) => {
|
data = data.map((item) => {
|
||||||
item.url = `/files${base}` + url.encodePath(item.path);
|
item.url = `/files${base}` + url.encodePath(item.path);
|
||||||
|
|
||||||
if (item.dir) {
|
if (item.dir) {
|
||||||
item.url += "/";
|
item.url += "/";
|
||||||
}
|
}
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
});
|
});
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
} else {
|
|
||||||
throw Error(res.status);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,12 +5,8 @@ export function get() {
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function update(settings) {
|
export async function update(settings) {
|
||||||
const res = await fetchURL(`/api/settings`, {
|
await fetchURL(`/api/settings`, {
|
||||||
method: "PUT",
|
method: "PUT",
|
||||||
body: JSON.stringify(settings),
|
body: JSON.stringify(settings),
|
||||||
});
|
});
|
||||||
|
|
||||||
if (res.status !== 200) {
|
|
||||||
throw new Error(res.status);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { fetchURL, fetchJSON, removePrefix } from "./utils";
|
import { fetchURL, fetchJSON, removePrefix, createURL } from "./utils";
|
||||||
|
|
||||||
export async function list() {
|
export async function list() {
|
||||||
return fetchJSON("/api/shares");
|
return fetchJSON("/api/shares");
|
||||||
|
@ -10,13 +10,9 @@ export async function get(url) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function remove(hash) {
|
export async function remove(hash) {
|
||||||
const res = await fetchURL(`/api/share/${hash}`, {
|
await fetchURL(`/api/share/${hash}`, {
|
||||||
method: "DELETE",
|
method: "DELETE",
|
||||||
});
|
});
|
||||||
|
|
||||||
if (res.status !== 200) {
|
|
||||||
throw new Error(res.status);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function create(url, password = "", expires = "", unit = "hours") {
|
export async function create(url, password = "", expires = "", unit = "hours") {
|
||||||
|
@ -34,3 +30,7 @@ export async function create(url, password = "", expires = "", unit = "hours") {
|
||||||
body: body,
|
body: body,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getShareURL(share) {
|
||||||
|
return createURL("share/" + share.hash, {}, false);
|
||||||
|
}
|
||||||
|
|
|
@ -20,13 +20,11 @@ export async function create(user) {
|
||||||
|
|
||||||
if (res.status === 201) {
|
if (res.status === 201) {
|
||||||
return res.headers.get("Location");
|
return res.headers.get("Location");
|
||||||
} else {
|
|
||||||
throw new Error(res.status);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function update(user, which = ["all"]) {
|
export async function update(user, which = ["all"]) {
|
||||||
const res = await fetchURL(`/api/users/${user.id}`, {
|
await fetchURL(`/api/users/${user.id}`, {
|
||||||
method: "PUT",
|
method: "PUT",
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
what: "user",
|
what: "user",
|
||||||
|
@ -34,18 +32,10 @@ export async function update(user, which = ["all"]) {
|
||||||
data: user,
|
data: user,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
if (res.status !== 200) {
|
|
||||||
throw new Error(res.status);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function remove(id) {
|
export async function remove(id) {
|
||||||
const res = await fetchURL(`/api/users/${id}`, {
|
await fetchURL(`/api/users/${id}`, {
|
||||||
method: "DELETE",
|
method: "DELETE",
|
||||||
});
|
});
|
||||||
|
|
||||||
if (res.status !== 200) {
|
|
||||||
throw new Error(res.status);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import store from "@/store";
|
import store from "@/store";
|
||||||
import { renew } from "@/utils/auth";
|
import { renew, logout } from "@/utils/auth";
|
||||||
import { baseURL } from "@/utils/constants";
|
import { baseURL } from "@/utils/constants";
|
||||||
|
import { encodePath } from "@/utils/url";
|
||||||
|
|
||||||
export async function fetchURL(url, opts) {
|
export async function fetchURL(url, opts, auth = true) {
|
||||||
opts = opts || {};
|
opts = opts || {};
|
||||||
opts.headers = opts.headers || {};
|
opts.headers = opts.headers || {};
|
||||||
|
|
||||||
|
@ -17,14 +18,28 @@ export async function fetchURL(url, opts) {
|
||||||
},
|
},
|
||||||
...rest,
|
...rest,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch {
|
||||||
return { status: 0 };
|
const error = new Error("000 No connection");
|
||||||
|
error.status = 0;
|
||||||
|
|
||||||
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res.headers.get("X-Renew-Token") === "true") {
|
if (auth && res.headers.get("X-Renew-Token") === "true") {
|
||||||
await renew(store.state.jwt);
|
await renew(store.state.jwt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (res.status < 200 || res.status > 299) {
|
||||||
|
const error = new Error(await res.text());
|
||||||
|
error.status = res.status;
|
||||||
|
|
||||||
|
if (auth && res.status == 401) {
|
||||||
|
logout();
|
||||||
|
}
|
||||||
|
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,3 +60,18 @@ export function removePrefix(url) {
|
||||||
if (url[0] !== "/") url = "/" + url;
|
if (url[0] !== "/") url = "/" + url;
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function createURL(endpoint, params = {}, auth = true) {
|
||||||
|
const url = new URL(encodePath(endpoint), origin + baseURL);
|
||||||
|
|
||||||
|
const searchParams = {
|
||||||
|
...(auth && { auth: store.state.jwt }),
|
||||||
|
...params,
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const key in searchParams) {
|
||||||
|
url.searchParams.set(key, searchParams[key]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return url.toString();
|
||||||
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { baseURL, enableThumbs } from "@/utils/constants";
|
import { enableThumbs } from "@/utils/constants";
|
||||||
import { mapMutations, mapGetters, mapState } from "vuex";
|
import { mapMutations, mapGetters, mapState } from "vuex";
|
||||||
import filesize from "filesize";
|
import filesize from "filesize";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
|
@ -58,6 +58,7 @@ export default {
|
||||||
"modified",
|
"modified",
|
||||||
"index",
|
"index",
|
||||||
"readOnly",
|
"readOnly",
|
||||||
|
"path",
|
||||||
],
|
],
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(["user", "selected", "req", "jwt"]),
|
...mapState(["user", "selected", "req", "jwt"]),
|
||||||
|
@ -83,12 +84,12 @@ export default {
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
thumbnailUrl() {
|
thumbnailUrl() {
|
||||||
const path = this.url.replace(/^\/files\//, "");
|
const file = {
|
||||||
|
path: this.path,
|
||||||
|
modified: this.modified,
|
||||||
|
};
|
||||||
|
|
||||||
// reload the image when the file is replaced
|
return api.getPreviewURL(file, "thumb");
|
||||||
const key = Date.parse(this.modified);
|
|
||||||
|
|
||||||
return `${baseURL}/api/preview/thumb/${path}?k=${key}&inline=true`;
|
|
||||||
},
|
},
|
||||||
isThumbsEnabled() {
|
isThumbsEnabled() {
|
||||||
return enableThumbs;
|
return enableThumbs;
|
||||||
|
@ -97,7 +98,7 @@ export default {
|
||||||
methods: {
|
methods: {
|
||||||
...mapMutations(["addSelected", "removeSelected", "resetSelected"]),
|
...mapMutations(["addSelected", "removeSelected", "resetSelected"]),
|
||||||
humanSize: function () {
|
humanSize: function () {
|
||||||
return filesize(this.size);
|
return this.type == "invalid_link" ? "invalid link" : filesize(this.size);
|
||||||
},
|
},
|
||||||
humanTime: function () {
|
humanTime: function () {
|
||||||
if (this.readOnly == undefined && this.user.dateFormat) {
|
if (this.readOnly == undefined && this.user.dateFormat) {
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
<td class="small">
|
<td class="small">
|
||||||
<button
|
<button
|
||||||
class="action copy-clipboard"
|
class="action copy-clipboard"
|
||||||
:data-clipboard-text="buildLink(link.hash)"
|
:data-clipboard-text="buildLink(link)"
|
||||||
:aria-label="$t('buttons.copyToClipboard')"
|
:aria-label="$t('buttons.copyToClipboard')"
|
||||||
:title="$t('buttons.copyToClipboard')"
|
:title="$t('buttons.copyToClipboard')"
|
||||||
>
|
>
|
||||||
|
@ -118,7 +118,6 @@
|
||||||
<script>
|
<script>
|
||||||
import { mapState, mapGetters } from "vuex";
|
import { mapState, mapGetters } from "vuex";
|
||||||
import { share as api } from "@/api";
|
import { share as api } from "@/api";
|
||||||
import { baseURL } from "@/utils/constants";
|
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import Clipboard from "clipboard";
|
import Clipboard from "clipboard";
|
||||||
|
|
||||||
|
@ -213,8 +212,8 @@ export default {
|
||||||
humanTime(time) {
|
humanTime(time) {
|
||||||
return moment(time * 1000).fromNow();
|
return moment(time * 1000).fromNow();
|
||||||
},
|
},
|
||||||
buildLink(hash) {
|
buildLink(share) {
|
||||||
return `${window.location.origin}${baseURL}/share/${hash}`;
|
return api.getShareURL(share);
|
||||||
},
|
},
|
||||||
sort() {
|
sort() {
|
||||||
this.links = this.links.sort((a, b) => {
|
this.links = this.links.sort((a, b) => {
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
class="file"
|
class="file"
|
||||||
v-for="file in filesInUpload"
|
v-for="file in filesInUpload"
|
||||||
:key="file.id"
|
:key="file.id"
|
||||||
|
:data-dir="file.isDir"
|
||||||
:data-type="file.type"
|
:data-type="file.type"
|
||||||
:aria-label="file.name"
|
:aria-label="file.name"
|
||||||
>
|
>
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
.file-icons [data-type=pdf] i::before { content: 'description' }
|
.file-icons [data-type=pdf] i::before { content: 'description' }
|
||||||
.file-icons [data-type=text] i::before { content: 'description' }
|
.file-icons [data-type=text] i::before { content: 'description' }
|
||||||
.file-icons [data-type=video] i::before { content: 'movie' }
|
.file-icons [data-type=video] i::before { content: 'movie' }
|
||||||
|
.file-icons [data-type=invalid_link] i::before { content: 'link_off' }
|
||||||
|
|
||||||
/* #f90 - Image */
|
/* #f90 - Image */
|
||||||
|
|
||||||
|
@ -125,6 +126,7 @@
|
||||||
.file-icons [data-type=audio] i { color: var(--icon-yellow) }
|
.file-icons [data-type=audio] i { color: var(--icon-yellow) }
|
||||||
.file-icons [data-type=image] i { color: var(--icon-orange) }
|
.file-icons [data-type=image] i { color: var(--icon-orange) }
|
||||||
.file-icons [data-type=video] i { color: var(--icon-violet) }
|
.file-icons [data-type=video] i { color: var(--icon-violet) }
|
||||||
|
.file-icons [data-type=invalid_link] i { color: var(--icon-red) }
|
||||||
|
|
||||||
/* #f00 - Adobe/Oracle */
|
/* #f00 - Adobe/Oracle */
|
||||||
|
|
||||||
|
|
|
@ -13,9 +13,25 @@ import Shares from "@/views/settings/Shares";
|
||||||
import Errors from "@/views/Errors";
|
import Errors from "@/views/Errors";
|
||||||
import store from "@/store";
|
import store from "@/store";
|
||||||
import { baseURL, name } from "@/utils/constants";
|
import { baseURL, name } from "@/utils/constants";
|
||||||
|
import i18n from "@/i18n";
|
||||||
|
|
||||||
Vue.use(Router);
|
Vue.use(Router);
|
||||||
|
|
||||||
|
const titles = {
|
||||||
|
Login: "sidebar.login",
|
||||||
|
Share: "buttons.share",
|
||||||
|
Files: "files.files",
|
||||||
|
Settings: "sidebar.settings",
|
||||||
|
ProfileSettings: "settings.profileSettings",
|
||||||
|
Shares: "settings.shareManagement",
|
||||||
|
GlobalSettings: "settings.globalSettings",
|
||||||
|
Users: "settings.users",
|
||||||
|
User: "settings.user",
|
||||||
|
Forbidden: "errors.forbidden",
|
||||||
|
NotFound: "errors.notFound",
|
||||||
|
InternalServerError: "errors.internal",
|
||||||
|
};
|
||||||
|
|
||||||
const router = new Router({
|
const router = new Router({
|
||||||
base: baseURL,
|
base: baseURL,
|
||||||
mode: "history",
|
mode: "history",
|
||||||
|
@ -29,7 +45,6 @@ const router = new Router({
|
||||||
return next({ path: "/files" });
|
return next({ path: "/files" });
|
||||||
}
|
}
|
||||||
|
|
||||||
document.title = "Login - " + name;
|
|
||||||
next();
|
next();
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -63,7 +78,7 @@ const router = new Router({
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: "/settings/profile",
|
path: "/settings/profile",
|
||||||
name: "Profile Settings",
|
name: "ProfileSettings",
|
||||||
component: ProfileSettings,
|
component: ProfileSettings,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -73,7 +88,7 @@ const router = new Router({
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/settings/global",
|
path: "/settings/global",
|
||||||
name: "Global Settings",
|
name: "GlobalSettings",
|
||||||
component: GlobalSettings,
|
component: GlobalSettings,
|
||||||
meta: {
|
meta: {
|
||||||
requiresAdmin: true,
|
requiresAdmin: true,
|
||||||
|
@ -108,7 +123,7 @@ const router = new Router({
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/404",
|
path: "/404",
|
||||||
name: "Not Found",
|
name: "NotFound",
|
||||||
component: Errors,
|
component: Errors,
|
||||||
props: {
|
props: {
|
||||||
errorCode: 404,
|
errorCode: 404,
|
||||||
|
@ -117,7 +132,7 @@ const router = new Router({
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/500",
|
path: "/500",
|
||||||
name: "Internal Server Error",
|
name: "InternalServerError",
|
||||||
component: Errors,
|
component: Errors,
|
||||||
props: {
|
props: {
|
||||||
errorCode: 500,
|
errorCode: 500,
|
||||||
|
@ -140,7 +155,8 @@ const router = new Router({
|
||||||
});
|
});
|
||||||
|
|
||||||
router.beforeEach((to, from, next) => {
|
router.beforeEach((to, from, next) => {
|
||||||
document.title = to.name + " - " + name;
|
const title = i18n.t(titles[to.name]);
|
||||||
|
document.title = title + " - " + name;
|
||||||
|
|
||||||
if (to.matched.some((record) => record.meta.requiresAuth)) {
|
if (to.matched.some((record) => record.meta.requiresAuth)) {
|
||||||
if (!store.getters.isLogged) {
|
if (!store.getters.isLogged) {
|
||||||
|
|
|
@ -25,15 +25,19 @@ const getters = {
|
||||||
let upload = state.upload.uploads[index];
|
let upload = state.upload.uploads[index];
|
||||||
let id = upload.id;
|
let id = upload.id;
|
||||||
let type = upload.type;
|
let type = upload.type;
|
||||||
let name = decodeURIComponent(upload.path.replace(/^.*[\\/]/, ""));
|
let name = upload.file.name;
|
||||||
let progress = state.upload.progress[id];
|
|
||||||
let size = state.upload.sizes[id];
|
let size = state.upload.sizes[id];
|
||||||
|
let isDir = upload.file.isDir;
|
||||||
|
let progress = isDir
|
||||||
|
? 100
|
||||||
|
: Math.ceil((state.upload.progress[id] / size) * 100);
|
||||||
|
|
||||||
files.push({
|
files.push({
|
||||||
id,
|
id,
|
||||||
name,
|
name,
|
||||||
progress: Math.ceil((progress / size) * 100),
|
progress,
|
||||||
type,
|
type,
|
||||||
|
isDir,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ const theme = window.FileBrowser.Theme;
|
||||||
const enableThumbs = window.FileBrowser.EnableThumbs;
|
const enableThumbs = window.FileBrowser.EnableThumbs;
|
||||||
const resizePreview = window.FileBrowser.ResizePreview;
|
const resizePreview = window.FileBrowser.ResizePreview;
|
||||||
const enableExec = window.FileBrowser.EnableExec;
|
const enableExec = window.FileBrowser.EnableExec;
|
||||||
|
const origin = window.location.origin;
|
||||||
|
|
||||||
export {
|
export {
|
||||||
name,
|
name,
|
||||||
|
@ -31,4 +32,5 @@ export {
|
||||||
enableThumbs,
|
enableThumbs,
|
||||||
resizePreview,
|
resizePreview,
|
||||||
enableExec,
|
enableExec,
|
||||||
|
origin,
|
||||||
};
|
};
|
||||||
|
|
|
@ -70,6 +70,7 @@ export function scanFiles(dt) {
|
||||||
isDir: true,
|
isDir: true,
|
||||||
size: 0,
|
size: 0,
|
||||||
fullPath: `${directory}${entry.name}`,
|
fullPath: `${directory}${entry.name}`,
|
||||||
|
name: entry.name,
|
||||||
};
|
};
|
||||||
|
|
||||||
contents.push(dir);
|
contents.push(dir);
|
||||||
|
@ -129,7 +130,7 @@ export function handleFiles(files, base, overwrite = false) {
|
||||||
path,
|
path,
|
||||||
file,
|
file,
|
||||||
overwrite,
|
overwrite,
|
||||||
type: detectType(file.type),
|
...(!file.isDir && { type: detectType(file.type) }),
|
||||||
};
|
};
|
||||||
|
|
||||||
store.dispatch("upload/upload", item);
|
store.dispatch("upload/upload", item);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
function removeLastDir(url) {
|
export function removeLastDir(url) {
|
||||||
var arr = url.split("/");
|
var arr = url.split("/");
|
||||||
if (arr.pop() === "") {
|
if (arr.pop() === "") {
|
||||||
arr.pop();
|
arr.pop();
|
||||||
|
@ -9,7 +9,7 @@ function removeLastDir(url) {
|
||||||
|
|
||||||
// this code borrow from mozilla
|
// this code borrow from mozilla
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent#Examples
|
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent#Examples
|
||||||
function encodeRFC5987ValueChars(str) {
|
export function encodeRFC5987ValueChars(str) {
|
||||||
return (
|
return (
|
||||||
encodeURIComponent(str)
|
encodeURIComponent(str)
|
||||||
// Note that although RFC3986 reserves "!", RFC5987 does not,
|
// Note that although RFC3986 reserves "!", RFC5987 does not,
|
||||||
|
@ -22,7 +22,7 @@ function encodeRFC5987ValueChars(str) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function encodePath(str) {
|
export function encodePath(str) {
|
||||||
return str
|
return str
|
||||||
.split("/")
|
.split("/")
|
||||||
.map((v) => encodeURIComponent(v))
|
.map((v) => encodeURIComponent(v))
|
||||||
|
@ -30,7 +30,7 @@ function encodePath(str) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
encodeRFC5987ValueChars: encodeRFC5987ValueChars,
|
encodeRFC5987ValueChars,
|
||||||
removeLastDir: removeLastDir,
|
removeLastDir,
|
||||||
encodePath: encodePath,
|
encodePath,
|
||||||
};
|
};
|
||||||
|
|
|
@ -38,15 +38,8 @@ export default {
|
||||||
},
|
},
|
||||||
props: ["errorCode", "showHeader"],
|
props: ["errorCode", "showHeader"],
|
||||||
computed: {
|
computed: {
|
||||||
code() {
|
|
||||||
return this.errorCode === "0" ||
|
|
||||||
this.errorCode === "404" ||
|
|
||||||
this.errorCode === "403"
|
|
||||||
? parseInt(this.errorCode)
|
|
||||||
: 500;
|
|
||||||
},
|
|
||||||
info() {
|
info() {
|
||||||
return errors[this.code];
|
return errors[this.errorCode] ? errors[this.errorCode] : errors[500];
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
<breadcrumbs base="/files" />
|
<breadcrumbs base="/files" />
|
||||||
|
|
||||||
<errors v-if="error" :errorCode="error.message" />
|
<errors v-if="error" :errorCode="error.status" />
|
||||||
<component v-else-if="currentView" :is="currentView"></component>
|
<component v-else-if="currentView" :is="currentView"></component>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<h2 class="message delayed">
|
<h2 class="message delayed">
|
||||||
|
@ -28,7 +28,6 @@ import Breadcrumbs from "@/components/Breadcrumbs";
|
||||||
import Errors from "@/views/Errors";
|
import Errors from "@/views/Errors";
|
||||||
import Preview from "@/views/files/Preview";
|
import Preview from "@/views/files/Preview";
|
||||||
import Listing from "@/views/files/Listing";
|
import Listing from "@/views/files/Listing";
|
||||||
import { name } from "@/utils/constants";
|
|
||||||
|
|
||||||
function clean(path) {
|
function clean(path) {
|
||||||
return path.endsWith("/") ? path.slice(0, -1) : path;
|
return path.endsWith("/") ? path.slice(0, -1) : path;
|
||||||
|
@ -52,7 +51,6 @@ export default {
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(["req", "reload", "loading", "show"]),
|
...mapState(["req", "reload", "loading", "show"]),
|
||||||
name: () => name,
|
|
||||||
currentView() {
|
currentView() {
|
||||||
if (this.req.type == undefined) {
|
if (this.req.type == undefined) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -118,7 +116,7 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$store.commit("updateRequest", res);
|
this.$store.commit("updateRequest", res);
|
||||||
document.title = `${res.name} - ${this.$route.name} - ${this.name}`;
|
document.title = `${res.name} - ${document.title}`;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.error = e;
|
this.error = e;
|
||||||
} finally {
|
} finally {
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="error">
|
<div v-else-if="error">
|
||||||
<div v-if="error.message === '401'">
|
<div v-if="error.status === 401">
|
||||||
<div class="card floating" id="password">
|
<div class="card floating" id="password">
|
||||||
<div v-if="attemptedPasswordLogin" class="share__wrong__password">
|
<div v-if="attemptedPasswordLogin" class="share__wrong__password">
|
||||||
{{ $t("login.wrongCredentials") }}
|
{{ $t("login.wrongCredentials") }}
|
||||||
|
@ -60,7 +60,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<errors v-else :errorCode="error.message" />
|
<errors v-else :errorCode="error.status" />
|
||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<div class="share">
|
<div class="share">
|
||||||
|
@ -104,7 +104,7 @@
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="share__box__element share__box__center">
|
<div class="share__box__element share__box__center">
|
||||||
<qrcode-vue :value="fullLink" size="200" level="M"></qrcode-vue>
|
<qrcode-vue :value="link" size="200" level="M"></qrcode-vue>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
@ -173,7 +173,6 @@
|
||||||
<script>
|
<script>
|
||||||
import { mapState, mapMutations, mapGetters } from "vuex";
|
import { mapState, mapMutations, mapGetters } from "vuex";
|
||||||
import { pub as api } from "@/api";
|
import { pub as api } from "@/api";
|
||||||
import { baseURL } from "@/utils/constants";
|
|
||||||
import filesize from "filesize";
|
import filesize from "filesize";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
|
|
||||||
|
@ -231,21 +230,10 @@ export default {
|
||||||
return "insert_drive_file";
|
return "insert_drive_file";
|
||||||
},
|
},
|
||||||
link: function () {
|
link: function () {
|
||||||
let queryArg = "";
|
return api.getDownloadURL(this.req);
|
||||||
if (this.token !== "") {
|
|
||||||
queryArg = `?token=${this.token}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
const path = this.$route.path.split("/").splice(2).join("/");
|
|
||||||
return `${baseURL}/api/public/dl/${path}${queryArg}`;
|
|
||||||
},
|
},
|
||||||
inlineLink: function () {
|
inlineLink: function () {
|
||||||
let url = new URL(this.fullLink);
|
return api.getDownloadURL(this.req, true);
|
||||||
url.searchParams.set("inline", "true");
|
|
||||||
return url.href;
|
|
||||||
},
|
|
||||||
fullLink: function () {
|
|
||||||
return window.location.origin + this.link;
|
|
||||||
},
|
},
|
||||||
humanSize: function () {
|
humanSize: function () {
|
||||||
if (this.req.isDir) {
|
if (this.req.isDir) {
|
||||||
|
@ -287,11 +275,12 @@ export default {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let file = await api.fetch(url, this.password);
|
let file = await api.fetch(url, this.password);
|
||||||
|
file.hash = this.hash;
|
||||||
|
|
||||||
this.token = file.token || "";
|
this.token = file.token || "";
|
||||||
|
|
||||||
this.updateRequest(file);
|
this.updateRequest(file);
|
||||||
document.title = `${file.name} - ${this.$route.name}`;
|
document.title = `${file.name} - ${document.title}`;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.error = e;
|
this.error = e;
|
||||||
} finally {
|
} finally {
|
||||||
|
|
|
@ -209,6 +209,7 @@
|
||||||
v-bind:modified="item.modified"
|
v-bind:modified="item.modified"
|
||||||
v-bind:type="item.type"
|
v-bind:type="item.type"
|
||||||
v-bind:size="item.size"
|
v-bind:size="item.size"
|
||||||
|
v-bind:path="item.path"
|
||||||
>
|
>
|
||||||
</item>
|
</item>
|
||||||
</div>
|
</div>
|
||||||
|
@ -225,6 +226,7 @@
|
||||||
v-bind:modified="item.modified"
|
v-bind:modified="item.modified"
|
||||||
v-bind:type="item.type"
|
v-bind:type="item.type"
|
||||||
v-bind:size="item.size"
|
v-bind:size="item.size"
|
||||||
|
v-bind:path="item.path"
|
||||||
>
|
>
|
||||||
</item>
|
</item>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -103,7 +103,7 @@
|
||||||
</a>
|
</a>
|
||||||
<a
|
<a
|
||||||
target="_blank"
|
target="_blank"
|
||||||
:href="downloadUrl + '&inline=true'"
|
:href="raw"
|
||||||
class="button button--flat"
|
class="button button--flat"
|
||||||
v-if="!req.isDir"
|
v-if="!req.isDir"
|
||||||
>
|
>
|
||||||
|
@ -145,7 +145,7 @@
|
||||||
<script>
|
<script>
|
||||||
import { mapState } from "vuex";
|
import { mapState } from "vuex";
|
||||||
import { files as api } from "@/api";
|
import { files as api } from "@/api";
|
||||||
import { baseURL, resizePreview } from "@/utils/constants";
|
import { resizePreview } from "@/utils/constants";
|
||||||
import url from "@/utils/url";
|
import url from "@/utils/url";
|
||||||
import throttle from "lodash.throttle";
|
import throttle from "lodash.throttle";
|
||||||
import HeaderBar from "@/components/header/HeaderBar";
|
import HeaderBar from "@/components/header/HeaderBar";
|
||||||
|
@ -186,23 +186,14 @@ export default {
|
||||||
return this.nextLink !== "";
|
return this.nextLink !== "";
|
||||||
},
|
},
|
||||||
downloadUrl() {
|
downloadUrl() {
|
||||||
return `${baseURL}/api/raw${url.encodePath(this.req.path)}?auth=${
|
return api.getDownloadURL(this.req);
|
||||||
this.jwt
|
|
||||||
}`;
|
|
||||||
},
|
|
||||||
previewUrl() {
|
|
||||||
// reload the image when the file is replaced
|
|
||||||
const key = Date.parse(this.req.modified);
|
|
||||||
|
|
||||||
if (this.req.type === "image" && !this.fullSize) {
|
|
||||||
return `${baseURL}/api/preview/big${url.encodePath(
|
|
||||||
this.req.path
|
|
||||||
)}?k=${key}`;
|
|
||||||
}
|
|
||||||
return `${baseURL}/api/raw${url.encodePath(this.req.path)}?k=${key}`;
|
|
||||||
},
|
},
|
||||||
raw() {
|
raw() {
|
||||||
return `${this.previewUrl}&inline=true`;
|
if (this.req.type === "image" && !this.fullSize) {
|
||||||
|
return api.getPreviewURL(this.req, "big");
|
||||||
|
}
|
||||||
|
|
||||||
|
return api.getDownloadURL(this.req, true);
|
||||||
},
|
},
|
||||||
showMore() {
|
showMore() {
|
||||||
return this.$store.state.show === "more";
|
return this.$store.state.show === "more";
|
||||||
|
@ -276,9 +267,7 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.req.subtitles) {
|
if (this.req.subtitles) {
|
||||||
this.subtitles = this.req.subtitles.map(
|
this.subtitles = api.getSubtitlesURL(this.req);
|
||||||
(sub) => `${baseURL}/api/raw${sub}?inline=true`
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let dirs = this.$route.fullPath.split("/");
|
let dirs = this.$route.fullPath.split("/");
|
||||||
|
@ -320,15 +309,14 @@ export default {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
prefetchUrl: function (item) {
|
prefetchUrl(item) {
|
||||||
const key = Date.parse(item.modified);
|
if (item.type !== "image") {
|
||||||
if (item.type === "image" && !this.fullSize) {
|
|
||||||
return `${baseURL}/api/preview/big${item.path}?k=${key}&inline=true`;
|
|
||||||
} else if (item.type === "image") {
|
|
||||||
return `${baseURL}/api/raw${item.path}?k=${key}&inline=true`;
|
|
||||||
} else {
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return this.fullSize
|
||||||
|
? api.getDownloadURL(item, true)
|
||||||
|
: api.getPreviewURL(item, "big");
|
||||||
},
|
},
|
||||||
openMore() {
|
openMore() {
|
||||||
this.$store.commit("showHover", "more");
|
this.$store.commit("showHover", "more");
|
||||||
|
@ -358,7 +346,7 @@ export default {
|
||||||
this.$router.push({ path: uri });
|
this.$router.push({ path: uri });
|
||||||
},
|
},
|
||||||
download() {
|
download() {
|
||||||
api.download(null, this.$route.path);
|
window.open(this.downloadUrl);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<errors v-if="error" :errorCode="error.message" />
|
<errors v-if="error" :errorCode="error.status" />
|
||||||
<div class="row" v-else-if="!loading">
|
<div class="row" v-else-if="!loading">
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<form class="card" @submit.prevent="save">
|
<form class="card" @submit.prevent="save">
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<errors v-if="error" :errorCode="error.message" />
|
<errors v-if="error" :errorCode="error.status" />
|
||||||
<div class="row" v-else-if="!loading">
|
<div class="row" v-else-if="!loading">
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
|
@ -19,9 +19,7 @@
|
||||||
|
|
||||||
<tr v-for="link in links" :key="link.hash">
|
<tr v-for="link in links" :key="link.hash">
|
||||||
<td>
|
<td>
|
||||||
<a :href="buildLink(link.hash)" target="_blank">{{
|
<a :href="buildLink(link)" target="_blank">{{ link.path }}</a>
|
||||||
link.path
|
|
||||||
}}</a>
|
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<template v-if="link.expire !== 0">{{
|
<template v-if="link.expire !== 0">{{
|
||||||
|
@ -43,7 +41,7 @@
|
||||||
<td class="small">
|
<td class="small">
|
||||||
<button
|
<button
|
||||||
class="action copy-clipboard"
|
class="action copy-clipboard"
|
||||||
:data-clipboard-text="buildLink(link.hash)"
|
:data-clipboard-text="buildLink(link)"
|
||||||
:aria-label="$t('buttons.copyToClipboard')"
|
:aria-label="$t('buttons.copyToClipboard')"
|
||||||
:title="$t('buttons.copyToClipboard')"
|
:title="$t('buttons.copyToClipboard')"
|
||||||
>
|
>
|
||||||
|
@ -64,7 +62,6 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { share as api, users } from "@/api";
|
import { share as api, users } from "@/api";
|
||||||
import { baseURL } from "@/utils/constants";
|
|
||||||
import { mapState, mapMutations } from "vuex";
|
import { mapState, mapMutations } from "vuex";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import Clipboard from "clipboard";
|
import Clipboard from "clipboard";
|
||||||
|
@ -136,8 +133,8 @@ export default {
|
||||||
humanTime(time) {
|
humanTime(time) {
|
||||||
return moment(time * 1000).fromNow();
|
return moment(time * 1000).fromNow();
|
||||||
},
|
},
|
||||||
buildLink(hash) {
|
buildLink(share) {
|
||||||
return `${window.location.origin}${baseURL}/share/${hash}`;
|
return api.getShareURL(share);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<errors v-if="error" :errorCode="error.message" />
|
<errors v-if="error" :errorCode="error.status" />
|
||||||
<div class="row" v-else-if="!loading">
|
<div class="row" v-else-if="!loading">
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<form @submit="save" class="card">
|
<form @submit="save" class="card">
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<errors v-if="error" :errorCode="error.message" />
|
<errors v-if="error" :errorCode="error.status" />
|
||||||
<div class="row" v-else-if="!loading">
|
<div class="row" v-else-if="!loading">
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
|
|
|
@ -71,7 +71,7 @@ func withUser(fn handleFunc) handleFunc {
|
||||||
token, err := request.ParseFromRequest(r, &extractor{}, keyFunc, request.WithClaims(&tk))
|
token, err := request.ParseFromRequest(r, &extractor{}, keyFunc, request.WithClaims(&tk))
|
||||||
|
|
||||||
if err != nil || !token.Valid {
|
if err != nil || !token.Valid {
|
||||||
return http.StatusForbidden, nil
|
return http.StatusUnauthorized, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
expired := !tk.VerifyExpiresAt(time.Now().Add(time.Hour).Unix(), true)
|
expired := !tk.VerifyExpiresAt(time.Now().Add(time.Hour).Unix(), true)
|
||||||
|
|
|
@ -27,7 +27,7 @@ func NewHandler(
|
||||||
r := mux.NewRouter()
|
r := mux.NewRouter()
|
||||||
r.Use(func(next http.Handler) http.Handler {
|
r.Use(func(next http.Handler) http.Handler {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
w.Header().Set("Content-Security-Policy", `default-src 'self'`)
|
w.Header().Set("Content-Security-Policy", `default-src 'self'; style-src 'unsafe-inline';`)
|
||||||
next.ServeHTTP(w, r)
|
next.ServeHTTP(w, r)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue