Optional password protection for the web server
This commit is contained in:
@@ -71,7 +71,7 @@ server {
|
||||
client_max_body_size 5M;
|
||||
|
||||
location / {
|
||||
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
|
||||
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
|
||||
proxy_pass http://127.0.0.1:6693;
|
||||
}
|
||||
}
|
||||
|
@@ -141,6 +141,7 @@ function defineEchoHandler() {
|
||||
console.log("OOYE has its own web server. It needs to be accessible on the public internet.")
|
||||
console.log("You need to enter a public URL where you will be able to host this web server.")
|
||||
console.log("OOYE listens on localhost:6693, so you will probably have to set up a reverse proxy.")
|
||||
console.log("Examples: https://gitdab.com/cadence/out-of-your-element/src/branch/main/docs/get-started.md#appendix")
|
||||
console.log("Now listening on port 6693. Feel free to send some test requests.")
|
||||
/** @type {{bridge_origin: string}} */
|
||||
const bridgeOriginResponse = await prompt({
|
||||
@@ -207,6 +208,15 @@ function defineEchoHandler() {
|
||||
})
|
||||
}
|
||||
|
||||
console.log("Would you like to require a password to add your bot to servers? This will discourage others from using your bridge.")
|
||||
console.log("Important: To make it truly private, you MUST ALSO disable Public Bot in the Discord bot configuration page.")
|
||||
/** @type {{web_password: string}} */
|
||||
const passwordResponse = await prompt({
|
||||
type: "text",
|
||||
name: "web_password",
|
||||
message: "Choose a simple password (optional)"
|
||||
})
|
||||
|
||||
console.log("What is your Discord client secret?")
|
||||
console.log(`You can find it in the application's OAuth2 section: https://discord.com/developers/applications/${client.id}/oauth2`)
|
||||
/** @type {{discord_client_secret: string}} */
|
||||
@@ -244,7 +254,8 @@ function defineEchoHandler() {
|
||||
...bridgeOriginResponse,
|
||||
server_origin: serverOrigin,
|
||||
...discordTokenResponse,
|
||||
...clientSecretResponse
|
||||
...clientSecretResponse,
|
||||
...passwordResponse
|
||||
}
|
||||
}
|
||||
registration.reg = reg
|
||||
|
3
src/types.d.ts
vendored
3
src/types.d.ts
vendored
@@ -29,7 +29,8 @@ export type AppServiceRegistrationConfig = {
|
||||
include_user_id_in_mxid: boolean
|
||||
invite: string[]
|
||||
discord_origin?: string
|
||||
discord_cdn_origin?: string
|
||||
discord_cdn_origin?: string,
|
||||
web_password: string
|
||||
}
|
||||
old_bridge?: {
|
||||
as_token: string
|
||||
|
@@ -23,7 +23,7 @@ async function getManagedGuilds(event) {
|
||||
|
||||
/**
|
||||
* @param {h3.H3Event} event
|
||||
* @returns {ReturnType<typeof h3.useSession<{userID?: string, mxid?: string, managedGuilds?: string[], state?: string, selfService?: boolean}>>}
|
||||
* @returns {ReturnType<typeof h3.useSession<{userID?: string, mxid?: string, managedGuilds?: string[], state?: string, selfService?: boolean, password?: string}>>}
|
||||
*/
|
||||
function useSession(event) {
|
||||
return h3.useSession(event, {password: reg.as_token})
|
||||
|
@@ -1,24 +1,56 @@
|
||||
extends includes/template.pug
|
||||
|
||||
block body
|
||||
.s-page-title.mb24
|
||||
h1.s-page-title--header Bridge a Discord server
|
||||
- let locked = reg.ooye.web_password && reg.ooye.web_password !== session.data.password
|
||||
|
||||
.d-grid.g24.grid__2(class="sm:grid__1")
|
||||
.s-card.bs-md.d-flex.fd-column
|
||||
h2 Easy mode
|
||||
p Add the bot to your Discord server.
|
||||
p It will automatically create new Matrix rooms for you.
|
||||
.fl-grow1
|
||||
a.s-btn.s-btn__filled.s-btn__icon(href=rel("/oauth?action=add"))
|
||||
!= icons.Icons.IconPlus
|
||||
= ` Add to server`
|
||||
.s-card.bs-md.d-flex.fd-column
|
||||
h2 Self-service
|
||||
p OOYE will link an existing Discord server and Matrix space together.
|
||||
p Choose this option if you already have a community set up on Matrix.
|
||||
p Or, choose this if you're migrating from a different bridge.
|
||||
.fl-grow1
|
||||
a.s-btn.s-btn__outlined.s-btn__icon(href=rel("/oauth?action=add-self-service"))
|
||||
!= icons.Icons.IconUnorderedList
|
||||
= ` Set up self-service`
|
||||
if locked
|
||||
aside.s-notice.s-notice__warning.p8
|
||||
.d-flex.flex__center.jc-space-between.s-banner--container.g8(class="md:fw-wrap")
|
||||
.d-flex.ai-center.g8
|
||||
.flex--item!= icons.Icons.IconLock
|
||||
p.m0 <strong>Private instance.</strong> You need the password to use this instance of Out Of Your Element.
|
||||
form(method="post" action="/api/password")
|
||||
input.s-input(placeholder="Enter password" name="password")
|
||||
|
||||
.h32
|
||||
|
||||
.s-page-title.mb24
|
||||
h1.s-page-title--header Out Of Your Element
|
||||
|
||||
else
|
||||
.s-page-title.mb24
|
||||
h1.s-page-title--header Bridge a Discord server
|
||||
|
||||
.d-grid.g24.grid__2.mb24(class="sm:grid__1")
|
||||
.s-card.bs-md.d-flex.fd-column
|
||||
h2 Easy mode
|
||||
p Add the bot to your Discord server.
|
||||
p It will automatically create new Matrix rooms for you.
|
||||
.fl-grow1
|
||||
a.s-btn.s-btn__filled.s-btn__icon(href=rel("/oauth?action=add"))
|
||||
!= icons.Icons.IconPlus
|
||||
= ` Add to server`
|
||||
.s-card.bs-md.d-flex.fd-column
|
||||
h2 Self-service
|
||||
p OOYE will link an existing Discord server and Matrix space together.
|
||||
p Choose this option if you already have a community set up on Matrix.
|
||||
p Or, choose this if you're migrating from a different bridge.
|
||||
.fl-grow1
|
||||
a.s-btn.s-btn__outlined.s-btn__icon(href=rel("/oauth?action=add-self-service"))
|
||||
!= icons.Icons.IconUnorderedList
|
||||
= ` Set up self-service`
|
||||
|
||||
.s-prose
|
||||
h2 What is this?
|
||||
p #[a(href="https://gitdab.com/cadence/out-of-your-element") Out Of Your Element] is a bridge between the Discord and Matrix chat apps. It lets people on both platforms chat with each other without needing to get everyone on the same app.
|
||||
p Just chat like usual, and the bridge will forward messages back and forth between the two platforms, so everyone sees the whole conversation.
|
||||
p All kinds of content are supported, including pictures, threads, emojis, and @mentions.
|
||||
p It's really easy to set up, even if you only have Discord. Just add the bot to your server, and it'll make everything available on Matrix automatically.
|
||||
|
||||
if locked
|
||||
h2 This is a private instance
|
||||
p Anybody can run their own instance of the Out Of Your Element software. The person running this instance has made it private, so you can't add it to your server just yet. If you know the people in charge of #{reg.ooye.server_name}, ask them for the password.
|
||||
|
||||
h2 Run your own instance
|
||||
p You can still use Out Of Your Element by running your own copy of the software, but this requires some technical skill.
|
||||
p To get started, #[a(href="https://gitdab.com/cadence/out-of-your-element/src/branch/main/docs/get-started.md") check the installation instructions.]
|
||||
|
@@ -61,6 +61,9 @@ html(lang="en")
|
||||
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 80%22><text y=%22.83em%22 font-size=%2283%22>💬</text></svg>">
|
||||
meta(name="htmx-config" content='{"requestClass":"is-loading"}')
|
||||
style.
|
||||
.s-prose a {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.themed {
|
||||
--theme-base-primary-color-h: 266;
|
||||
--theme-base-primary-color-s: 53%;
|
||||
|
@@ -37,13 +37,15 @@ as.router.get("/oauth", defineEventHandler(async event => {
|
||||
const session = await auth.useSession(event)
|
||||
let scope = "guilds"
|
||||
|
||||
const parsedFirstQuery = await getValidatedQuery(event, schema.first.safeParse)
|
||||
if (parsedFirstQuery.data?.action === "add") {
|
||||
scope = "bot+guilds"
|
||||
await session.update({selfService: false})
|
||||
} else if (parsedFirstQuery.data?.action === "add-self-service") {
|
||||
scope = "bot+guilds"
|
||||
await session.update({selfService: true})
|
||||
if (!reg.ooye.web_password || reg.ooye.web_password === session.data.password) {
|
||||
const parsedFirstQuery = await getValidatedQuery(event, schema.first.safeParse)
|
||||
if (parsedFirstQuery.data?.action === "add") {
|
||||
scope = "bot+guilds"
|
||||
await session.update({selfService: false})
|
||||
} else if (parsedFirstQuery.data?.action === "add-self-service") {
|
||||
scope = "bot+guilds"
|
||||
await session.update({selfService: true})
|
||||
}
|
||||
}
|
||||
|
||||
async function tryAgain() {
|
||||
|
21
src/web/routes/password.js
Normal file
21
src/web/routes/password.js
Normal file
@@ -0,0 +1,21 @@
|
||||
// @ts-check
|
||||
|
||||
const {z} = require("zod")
|
||||
const {defineEventHandler, readValidatedBody, sendRedirect} = require("h3")
|
||||
const {as, sync} = require("../../passthrough")
|
||||
|
||||
/** @type {import("../auth")} */
|
||||
const auth = sync.require("../auth")
|
||||
|
||||
const schema = {
|
||||
password: z.object({
|
||||
password: z.string()
|
||||
})
|
||||
}
|
||||
|
||||
as.router.post("/api/password", defineEventHandler(async event => {
|
||||
const {password} = await readValidatedBody(event, schema.password.parse)
|
||||
const session = await auth.useSession(event)
|
||||
await session.update({password})
|
||||
return sendRedirect(event, "../")
|
||||
}))
|
@@ -30,8 +30,9 @@ sync.require("./routes/download-discord")
|
||||
sync.require("./routes/guild-settings")
|
||||
sync.require("./routes/guild")
|
||||
sync.require("./routes/link")
|
||||
sync.require("./routes/oauth")
|
||||
sync.require("./routes/log-in-with-matrix")
|
||||
sync.require("./routes/oauth")
|
||||
sync.require("./routes/password")
|
||||
|
||||
// Files
|
||||
|
||||
|
Reference in New Issue
Block a user