mirror of
https://github.com/louislam/uptime-kuma.git
synced 2024-11-26 11:26:17 +03:00
Render <StatusPage> if domain matched
This commit is contained in:
parent
fee88b32e3
commit
c4e74c9943
6 changed files with 91 additions and 16 deletions
|
@ -3,6 +3,20 @@ const { R } = require("redbean-node");
|
|||
|
||||
class StatusPage extends BeanModel {
|
||||
|
||||
static domainMappingList = { };
|
||||
|
||||
/**
|
||||
* Return object like this: { "test-uptime.kuma.pet": "default" }
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
static async loadDomainMappingList() {
|
||||
this.domainMappingList = await R.getAssoc(`
|
||||
SELECT domain, slug
|
||||
FROM status_page, status_page_cname
|
||||
WHERE status_page.id = status_page_cname.status_page_id
|
||||
`);
|
||||
}
|
||||
|
||||
static async sendStatusPageList(io, socket) {
|
||||
let result = {};
|
||||
|
||||
|
@ -16,6 +30,18 @@ class StatusPage extends BeanModel {
|
|||
return list;
|
||||
}
|
||||
|
||||
getDomainList() {
|
||||
let domainList = [];
|
||||
for (let domain in StatusPage.domainMappingList) {
|
||||
let s = StatusPage.domainMappingList[domain];
|
||||
|
||||
if (this.slug === s) {
|
||||
domainList.push(domain);
|
||||
}
|
||||
}
|
||||
return domainList;
|
||||
}
|
||||
|
||||
async toJSON() {
|
||||
return {
|
||||
id: this.id,
|
||||
|
@ -26,6 +52,7 @@ class StatusPage extends BeanModel {
|
|||
theme: this.theme,
|
||||
published: !!this.published,
|
||||
showTags: !!this.show_tags,
|
||||
domainList: this.getDomainList(),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -12,9 +12,19 @@ let router = express.Router();
|
|||
let cache = apicache.middleware;
|
||||
let io = server.io;
|
||||
|
||||
router.get("/api/entry-page", async (_, response) => {
|
||||
router.get("/api/entry-page", async (request, response) => {
|
||||
allowDevAllOrigin(response);
|
||||
response.json(server.entryPage);
|
||||
|
||||
let result = { };
|
||||
|
||||
if (request.hostname in StatusPage.domainMappingList) {
|
||||
result.type = "statusPageMatchedDomain";
|
||||
result.statusPageSlug = StatusPage.domainMappingList[request.hostname];
|
||||
} else {
|
||||
result.type = "entryPage";
|
||||
result.entryPage = server.entryPage;
|
||||
}
|
||||
response.json(result);
|
||||
});
|
||||
|
||||
router.get("/api/push/:pushToken", async (request, response) => {
|
||||
|
|
|
@ -197,6 +197,7 @@ exports.entryPage = "dashboard";
|
|||
await initDatabase(testMode);
|
||||
|
||||
exports.entryPage = await setting("entryPage");
|
||||
await StatusPage.loadDomainMappingList();
|
||||
|
||||
console.log("Adding route");
|
||||
|
||||
|
@ -205,8 +206,13 @@ exports.entryPage = "dashboard";
|
|||
// ***************************
|
||||
|
||||
// Entry Page
|
||||
app.get("/", async (_request, response) => {
|
||||
if (exports.entryPage && exports.entryPage.startsWith("statusPage-")) {
|
||||
app.get("/", async (request, response) => {
|
||||
debug(`Request Domain: ${request.hostname}`);
|
||||
|
||||
if (request.hostname in StatusPage.domainMappingList) {
|
||||
debug("This is a status page domain");
|
||||
response.send(indexHTML);
|
||||
} else if (exports.entryPage && exports.entryPage.startsWith("statusPage-")) {
|
||||
response.redirect("/status/" + exports.entryPage.replace("statusPage-", ""));
|
||||
} else {
|
||||
response.redirect("/dashboard");
|
||||
|
|
|
@ -37,6 +37,7 @@ import {
|
|||
faPen,
|
||||
faExternalLinkSquareAlt,
|
||||
faSpinner,
|
||||
faUndo,
|
||||
} from "@fortawesome/free-solid-svg-icons";
|
||||
|
||||
library.add(
|
||||
|
@ -73,6 +74,7 @@ library.add(
|
|||
faPen,
|
||||
faExternalLinkSquareAlt,
|
||||
faSpinner,
|
||||
faUndo,
|
||||
);
|
||||
|
||||
export { FontAwesomeIcon };
|
||||
|
|
|
@ -1,23 +1,44 @@
|
|||
<template>
|
||||
<div>
|
||||
<!--
|
||||
TODO: If the domain name matched, directly render the <StatusPage> component.
|
||||
-->
|
||||
<StatusPage v-if="statusPageSlug" override-slug="statusPageSlug" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import axios from "axios";
|
||||
import StatusPage from "./StatusPage.vue";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
StatusPage,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
statusPageSlug: null,
|
||||
};
|
||||
},
|
||||
async mounted() {
|
||||
let entryPage = (await axios.get("/api/entry-page")).data;
|
||||
|
||||
if (entryPage === "statusPage") {
|
||||
this.$router.push("/status");
|
||||
// There are only 2 cases that could come in here.
|
||||
// 1. Matched status Page domain name
|
||||
// 2. Vue Frontend Dev
|
||||
let res = (await axios.get("/api/entry-page")).data;
|
||||
|
||||
if (res.type === "statusPageMatchedDomain") {
|
||||
this.statusPageSlug = res.statusPageSlug;
|
||||
|
||||
} else if (res.type === "entryPage") { // Dev only
|
||||
const entryPage = res.entryPage;
|
||||
|
||||
if (entryPage === "statusPage") {
|
||||
this.$router.push("/status");
|
||||
} else {
|
||||
this.$router.push("/dashboard");
|
||||
}
|
||||
} else {
|
||||
this.$router.push("/dashboard");
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
};
|
||||
|
|
|
@ -35,9 +35,9 @@
|
|||
<input id="password" v-model="config.password" disabled type="password" autocomplete="new-password" class="form-control">
|
||||
</div>
|
||||
|
||||
<div v-if="false" class="my-3">
|
||||
<label for="cname" class="form-label">Domain Names <sup>Coming Soon</sup></label>
|
||||
<textarea id="cname" v-model="config.domanNames" rows="3" disabled class="form-control" :placeholder="domainNamesPlaceholder"></textarea>
|
||||
<div class="my-3">
|
||||
<label for="cname" class="form-label">Domain Names</label>
|
||||
<textarea id="cname" v-model="config.domanNames" rows="3" class="form-control" :placeholder="domainNamesPlaceholder"></textarea>
|
||||
</div>
|
||||
|
||||
<div class="danger-zone">
|
||||
|
@ -55,7 +55,7 @@
|
|||
</button>
|
||||
|
||||
<button class="btn btn-danger me-2" @click="discard">
|
||||
<font-awesome-icon icon="save" />
|
||||
<font-awesome-icon icon="undo" />
|
||||
{{ $t("Discard") }}
|
||||
</button>
|
||||
</div>
|
||||
|
@ -259,6 +259,7 @@ const favicon = new Favico({
|
|||
});
|
||||
|
||||
export default {
|
||||
|
||||
components: {
|
||||
PublicGroupList,
|
||||
ImageCropUpload,
|
||||
|
@ -278,6 +279,14 @@ export default {
|
|||
next();
|
||||
},
|
||||
|
||||
props: {
|
||||
overrideSlug: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: null,
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
slug: null,
|
||||
|
@ -294,7 +303,7 @@ export default {
|
|||
loadedData: false,
|
||||
baseURL: "",
|
||||
clickedEditButton: false,
|
||||
domainNamesPlaceholder: "domain1.com\ndomain2.com\n..."
|
||||
domainNamesPlaceholder: "example1.com\nexample2.com\n..."
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
@ -449,7 +458,7 @@ export default {
|
|||
this.baseURL = getResBaseURL();
|
||||
},
|
||||
async mounted() {
|
||||
this.slug = this.$route.params.slug;
|
||||
this.slug = this.overrideSlug || this.$route.params.slug;
|
||||
|
||||
if (!this.slug) {
|
||||
this.slug = "default";
|
||||
|
|
Loading…
Reference in a new issue