Merge branch 'master' into feat/local-image-proxy
@ -1,76 +1,87 @@
|
|||||||
<!DOCTYPE html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<meta http-equiv="Content-Type" content="text/html charset=UTF-8" />
|
||||||
|
<title>Verify {instanceName} Login from New Location</title>
|
||||||
|
|
||||||
<head>
|
<style>
|
||||||
<meta charset="UTF-8" />
|
* {
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
font-size: 16px;
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
line-height: 24px;
|
||||||
<meta http-equiv="Content-Type" content="text/html charset=UTF-8" />
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
<title>Verify {instanceName} Login from New Location</title>
|
}
|
||||||
|
|
||||||
<style>
|
p {
|
||||||
* {
|
color: white;
|
||||||
font-size: 16px;
|
}
|
||||||
line-height: 24px;
|
|
||||||
font-family: Arial, Helvetica, sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
.ExternalClass {
|
||||||
color: white;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
.ExternalClass {
|
<body>
|
||||||
width: 100%;
|
<div style="background-color: #202225">
|
||||||
}
|
<img
|
||||||
</style>
|
src="https://raw.githubusercontent.com/spacebarchat/spacebarchat/master/branding/svg/Spacebar__Logo-Blue.svg"
|
||||||
</head>
|
alt="Branding"
|
||||||
|
style="
|
||||||
<body>
|
|
||||||
<div style="background-color: #202225;">
|
|
||||||
<img src="https://raw.githubusercontent.com/spacebarchat/spacebarchat/master/branding/svg/Spacebar__Logo-Blue.svg"
|
|
||||||
alt="Branding" style="
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 200px;
|
max-width: 200px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
display: block;
|
display: block;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
" />
|
"
|
||||||
<div style="
|
/>
|
||||||
|
<div
|
||||||
|
style="
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 500px;
|
max-width: 500px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
padding: 40px 50px;
|
padding: 40px 50px;
|
||||||
background-color: #32353b;
|
background-color: #32353b;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
">
|
"
|
||||||
<p style="
|
>
|
||||||
|
<p
|
||||||
|
style="
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
letter-spacing: 0.27px;
|
letter-spacing: 0.27px;
|
||||||
line-height: 24px;
|
line-height: 24px;
|
||||||
">
|
"
|
||||||
Hey {userUsername},
|
>
|
||||||
</p>
|
Hey {userUsername},
|
||||||
<p>
|
</p>
|
||||||
It looks like someone tried to log into your {instanceName}
|
<p>
|
||||||
account from a new location. If this is you, follow the link
|
It looks like someone tried to log into your {instanceName}
|
||||||
below to authorize logging in from this location on your
|
account from a new location. If this is you, follow the link
|
||||||
account. If this isn't you, we suggest changing your
|
below to authorize logging in from this location on your
|
||||||
password as soon as possible.
|
account. If this isn't you, we suggest changing your
|
||||||
</p>
|
password as soon as possible.
|
||||||
<p>
|
</p>
|
||||||
<strong>IP Address:</strong> {ipAddress}
|
<p>
|
||||||
<br />
|
<strong>IP Address:</strong> {ipAddress}
|
||||||
<strong>Location:</strong> {locationCity}, {locationRegion},
|
<br />
|
||||||
{locationCountryName}
|
<strong>Location:</strong> {locationCity}, {locationRegion},
|
||||||
</p>
|
{locationCountryName}
|
||||||
<div>
|
</p>
|
||||||
<div style="
|
<div>
|
||||||
|
<div
|
||||||
|
style="
|
||||||
text-align: center;
|
text-align: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
padding-bottom: 10px;
|
padding-bottom: 10px;
|
||||||
">
|
"
|
||||||
<a href="{actionUrl}" target="_blank" style="
|
>
|
||||||
|
<a
|
||||||
|
href="{actionUrl}"
|
||||||
|
target="_blank"
|
||||||
|
style="
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
border: none;
|
border: none;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
@ -79,23 +90,31 @@
|
|||||||
padding: 15px 19px;
|
padding: 15px 19px;
|
||||||
background-color: #0185ff;
|
background-color: #0185ff;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
">Verify Login</a>
|
"
|
||||||
</div>
|
>Verify Login</a
|
||||||
<hr />
|
>
|
||||||
<div style="
|
</div>
|
||||||
|
<hr />
|
||||||
|
<div
|
||||||
|
style="
|
||||||
text-align: center;
|
text-align: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
padding-bottom: 10px;
|
padding-bottom: 10px;
|
||||||
">
|
"
|
||||||
<p>
|
>
|
||||||
Alternatively, you can directly paste this link into
|
<p>
|
||||||
your browser:
|
Alternatively, you can directly paste this link into
|
||||||
</p>
|
your browser:
|
||||||
<a href="{actionUrl}" target="_blank" style="word-wrap: break-word;">{actionUrl}</a>
|
</p>
|
||||||
|
<a
|
||||||
|
href="{actionUrl}"
|
||||||
|
target="_blank"
|
||||||
|
style="word-wrap: break-word"
|
||||||
|
>{actionUrl}</a
|
||||||
|
>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</body>
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<!DOCTYPE html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
@ -22,7 +22,7 @@
|
|||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div style="background-color: #202225;">
|
<div style="background-color: #202225">
|
||||||
<img
|
<img
|
||||||
src="https://raw.githubusercontent.com/spacebarchat/spacebarchat/master/branding/svg/Spacebar__Logo-Blue.svg"
|
src="https://raw.githubusercontent.com/spacebarchat/spacebarchat/master/branding/svg/Spacebar__Logo-Blue.svg"
|
||||||
alt="Branding"
|
alt="Branding"
|
||||||
|
@ -1,68 +1,79 @@
|
|||||||
<!DOCTYPE html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<meta http-equiv="Content-Type" content="text/html charset=UTF-8" />
|
||||||
|
<title>Password Reset Request for {instanceName}</title>
|
||||||
|
|
||||||
<head>
|
<style>
|
||||||
<meta charset="UTF-8" />
|
* {
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
font-size: 16px;
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
line-height: 24px;
|
||||||
<meta http-equiv="Content-Type" content="text/html charset=UTF-8" />
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
<title>Password Reset Request for {instanceName}</title>
|
}
|
||||||
|
|
||||||
<style>
|
p {
|
||||||
* {
|
color: white;
|
||||||
font-size: 16px;
|
}
|
||||||
line-height: 24px;
|
|
||||||
font-family: Arial, Helvetica, sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
.ExternalClass {
|
||||||
color: white;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
.ExternalClass {
|
<body>
|
||||||
width: 100%;
|
<div style="background-color: #202225">
|
||||||
}
|
<img
|
||||||
</style>
|
src="https://raw.githubusercontent.com/spacebarchat/spacebarchat/master/branding/svg/Spacebar__Logo-Blue.svg"
|
||||||
</head>
|
alt="Branding"
|
||||||
|
style="
|
||||||
<body>
|
|
||||||
<div style="background-color: #202225;">
|
|
||||||
<img src="https://raw.githubusercontent.com/spacebarchat/spacebarchat/master/branding/svg/Spacebar__Logo-Blue.svg"
|
|
||||||
alt="Branding" style="
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 200px;
|
max-width: 200px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
display: block;
|
display: block;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
" />
|
"
|
||||||
<div style="
|
/>
|
||||||
|
<div
|
||||||
|
style="
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 500px;
|
max-width: 500px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
padding: 40px 50px;
|
padding: 40px 50px;
|
||||||
background-color: #32353b;
|
background-color: #32353b;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
">
|
"
|
||||||
<p style="
|
>
|
||||||
|
<p
|
||||||
|
style="
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
letter-spacing: 0.27px;
|
letter-spacing: 0.27px;
|
||||||
line-height: 24px;
|
line-height: 24px;
|
||||||
">
|
"
|
||||||
Hey {userUsername},
|
>
|
||||||
</p>
|
Hey {userUsername},
|
||||||
<p>
|
</p>
|
||||||
Your {instanceName} password can be reset by clicking the
|
<p>
|
||||||
button below. If you did not request a new password, please
|
Your {instanceName} password can be reset by clicking the
|
||||||
ignore this email.
|
button below. If you did not request a new password, please
|
||||||
</p>
|
ignore this email.
|
||||||
<div>
|
</p>
|
||||||
<div style="
|
<div>
|
||||||
|
<div
|
||||||
|
style="
|
||||||
text-align: center;
|
text-align: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
padding-bottom: 10px;
|
padding-bottom: 10px;
|
||||||
">
|
"
|
||||||
<a href="{actionUrl}" target="_blank" style="
|
>
|
||||||
|
<a
|
||||||
|
href="{actionUrl}"
|
||||||
|
target="_blank"
|
||||||
|
style="
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
border: none;
|
border: none;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
@ -71,19 +82,25 @@
|
|||||||
padding: 15px 19px;
|
padding: 15px 19px;
|
||||||
background-color: #ff5f00;
|
background-color: #ff5f00;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
">Reset Password</a>
|
"
|
||||||
</div>
|
>Reset Password</a
|
||||||
<hr />
|
>
|
||||||
<div style="text-align: center">
|
</div>
|
||||||
<p>
|
<hr />
|
||||||
Alternatively, you can directly paste this link into
|
<div style="text-align: center">
|
||||||
your browser:
|
<p>
|
||||||
</p>
|
Alternatively, you can directly paste this link into
|
||||||
<a href="{actionUrl}" target="_blank" style="word-wrap: break-word;">{actionUrl}</a>
|
your browser:
|
||||||
|
</p>
|
||||||
|
<a
|
||||||
|
href="{actionUrl}"
|
||||||
|
target="_blank"
|
||||||
|
style="word-wrap: break-word"
|
||||||
|
>{actionUrl}</a
|
||||||
|
>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</body>
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<!DOCTYPE html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
@ -22,7 +22,7 @@
|
|||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div style="background-color: #202225;">
|
<div style="background-color: #202225">
|
||||||
<img
|
<img
|
||||||
src="https://raw.githubusercontent.com/spacebarchat/spacebarchat/master/branding/svg/Spacebar__Logo-Blue.svg"
|
src="https://raw.githubusercontent.com/spacebarchat/spacebarchat/master/branding/svg/Spacebar__Logo-Blue.svg"
|
||||||
alt="Branding"
|
alt="Branding"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<!DOCTYPE html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
@ -22,7 +22,7 @@
|
|||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div style="background-color: #202225;">
|
<div style="background-color: #202225">
|
||||||
<img
|
<img
|
||||||
src="https://raw.githubusercontent.com/spacebarchat/spacebarchat/master/branding/svg/Spacebar__Logo-Blue.svg"
|
src="https://raw.githubusercontent.com/spacebarchat/spacebarchat/master/branding/svg/Spacebar__Logo-Blue.svg"
|
||||||
alt="Branding"
|
alt="Branding"
|
||||||
@ -69,7 +69,7 @@
|
|||||||
>
|
>
|
||||||
<a
|
<a
|
||||||
class="btn"
|
class="btn"
|
||||||
href="{emailVerificationUrl}"
|
href="{actionUrl}"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
style="
|
style="
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
@ -90,8 +90,11 @@
|
|||||||
Alternatively, you can directly paste this link into
|
Alternatively, you can directly paste this link into
|
||||||
your browser:
|
your browser:
|
||||||
</p>
|
</p>
|
||||||
<a href="{emailVerificationUrl}" target="_blank" style="word-wrap: break-word;"
|
<a
|
||||||
>{emailVerificationUrl}</a
|
href="{actionUrl}"
|
||||||
|
target="_blank"
|
||||||
|
style="word-wrap: break-word"
|
||||||
|
>{actionUrl}</a
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -734,6 +734,114 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"MessageComponent": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"style": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"label": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"emoji": {
|
||||||
|
"$ref": "#/components/schemas/PartialEmoji"
|
||||||
|
},
|
||||||
|
"custom_id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"sku_id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"url": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"disabled": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/components/schemas/MessageComponent"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"components",
|
||||||
|
"type"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"PartialEmoji": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"animated": {
|
||||||
|
"type": "boolean"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"name"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"PollCreationSchema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"question": {
|
||||||
|
"$ref": "#/components/schemas/PollMedia"
|
||||||
|
},
|
||||||
|
"answers": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/components/schemas/PollAnswer"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"duration": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"allow_multiselect": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"layout_type": {
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"answers",
|
||||||
|
"question"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"PollMedia": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"text": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"emoji": {
|
||||||
|
"$ref": "#/components/schemas/PartialEmoji"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"PollAnswer": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"answer_id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"poll_media": {
|
||||||
|
"$ref": "#/components/schemas/PollMedia"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"poll_media"
|
||||||
|
]
|
||||||
|
},
|
||||||
"ChannelOverride": {
|
"ChannelOverride": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@ -1193,7 +1301,8 @@
|
|||||||
"$ref": "#/components/schemas/Guild"
|
"$ref": "#/components/schemas/Guild"
|
||||||
},
|
},
|
||||||
"parent_id": {
|
"parent_id": {
|
||||||
"type": "string"
|
"type": "string",
|
||||||
|
"nullable": true
|
||||||
},
|
},
|
||||||
"parent": {
|
"parent": {
|
||||||
"$ref": "#/components/schemas/Channel"
|
"$ref": "#/components/schemas/Channel"
|
||||||
@ -1802,6 +1911,10 @@
|
|||||||
"type": "integer",
|
"type": "integer",
|
||||||
"default": 0
|
"default": 0
|
||||||
},
|
},
|
||||||
|
"friend_discovery_flags": {
|
||||||
|
"type": "integer",
|
||||||
|
"default": 0
|
||||||
|
},
|
||||||
"friend_source_flags": {
|
"friend_source_flags": {
|
||||||
"$ref": "#/components/schemas/FriendSourceFlags"
|
"$ref": "#/components/schemas/FriendSourceFlags"
|
||||||
},
|
},
|
||||||
@ -1892,6 +2005,10 @@
|
|||||||
"timezone_offset": {
|
"timezone_offset": {
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"default": 0
|
"default": 0
|
||||||
|
},
|
||||||
|
"view_nsfw_guilds": {
|
||||||
|
"type": "boolean",
|
||||||
|
"default": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": [
|
"required": [
|
||||||
@ -1908,6 +2025,7 @@
|
|||||||
"disable_games_tab",
|
"disable_games_tab",
|
||||||
"enable_tts_command",
|
"enable_tts_command",
|
||||||
"explicit_content_filter",
|
"explicit_content_filter",
|
||||||
|
"friend_discovery_flags",
|
||||||
"friend_source_flags",
|
"friend_source_flags",
|
||||||
"gateway_connected",
|
"gateway_connected",
|
||||||
"gif_auto_play",
|
"gif_auto_play",
|
||||||
@ -1926,7 +2044,8 @@
|
|||||||
"status",
|
"status",
|
||||||
"stream_notifications_enabled",
|
"stream_notifications_enabled",
|
||||||
"theme",
|
"theme",
|
||||||
"timezone_offset"
|
"timezone_offset",
|
||||||
|
"view_nsfw_guilds"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"SecurityKey": {
|
"SecurityKey": {
|
||||||
@ -2240,6 +2359,9 @@
|
|||||||
"$ref": "#/components/schemas/MessageComponent"
|
"$ref": "#/components/schemas/MessageComponent"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"poll": {
|
||||||
|
"$ref": "#/components/schemas/Poll"
|
||||||
|
},
|
||||||
"id": {
|
"id": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
@ -2963,23 +3085,6 @@
|
|||||||
"user_ids"
|
"user_ids"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"PartialEmoji": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"id": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"name": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"animated": {
|
|
||||||
"type": "boolean"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"name"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"MessageType": {
|
"MessageType": {
|
||||||
"enum": [
|
"enum": [
|
||||||
0,
|
0,
|
||||||
@ -3018,40 +3123,71 @@
|
|||||||
],
|
],
|
||||||
"type": "number"
|
"type": "number"
|
||||||
},
|
},
|
||||||
"MessageComponent": {
|
"Poll": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"type": {
|
"question": {
|
||||||
"type": "integer"
|
"$ref": "#/components/schemas/PollMedia"
|
||||||
},
|
},
|
||||||
"style": {
|
"answers": {
|
||||||
"type": "integer"
|
|
||||||
},
|
|
||||||
"label": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"emoji": {
|
|
||||||
"$ref": "#/components/schemas/PartialEmoji"
|
|
||||||
},
|
|
||||||
"custom_id": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"url": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"disabled": {
|
|
||||||
"type": "boolean"
|
|
||||||
},
|
|
||||||
"components": {
|
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"$ref": "#/components/schemas/MessageComponent"
|
"$ref": "#/components/schemas/PollAnswer"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"expiry": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "date-time"
|
||||||
|
},
|
||||||
|
"allow_multiselect": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"results": {
|
||||||
|
"$ref": "#/components/schemas/PollResult"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"allow_multiselect",
|
||||||
|
"answers",
|
||||||
|
"expiry",
|
||||||
|
"question"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"PollResult": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"is_finalized": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"answer_counts": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/components/schemas/PollAnswerCount"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": [
|
"required": [
|
||||||
"components",
|
"answer_counts",
|
||||||
"type"
|
"is_finalized"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"PollAnswerCount": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"count": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"me_voted": {
|
||||||
|
"type": "boolean"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"count",
|
||||||
|
"id",
|
||||||
|
"me_voted"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"VoiceState": {
|
"VoiceState": {
|
||||||
@ -3444,7 +3580,12 @@
|
|||||||
},
|
},
|
||||||
"components": {
|
"components": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {}
|
"items": {
|
||||||
|
"$ref": "#/components/schemas/MessageComponent"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"poll": {
|
||||||
|
"$ref": "#/components/schemas/Poll"
|
||||||
},
|
},
|
||||||
"hit": {
|
"hit": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
@ -3466,6 +3607,7 @@
|
|||||||
"mention_roles",
|
"mention_roles",
|
||||||
"mentions",
|
"mentions",
|
||||||
"pinned",
|
"pinned",
|
||||||
|
"poll",
|
||||||
"timestamp",
|
"timestamp",
|
||||||
"tts",
|
"tts",
|
||||||
"type"
|
"type"
|
||||||
@ -5212,7 +5354,27 @@
|
|||||||
},
|
},
|
||||||
"components": {
|
"components": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {}
|
"items": {
|
||||||
|
"$ref": "#/components/schemas/MessageComponent"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"poll": {
|
||||||
|
"$ref": "#/components/schemas/PollCreationSchema"
|
||||||
|
},
|
||||||
|
"enforce_nonce": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"applied_tags": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"thread_name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"avatar_url": {
|
||||||
|
"type": "string"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -5338,7 +5500,27 @@
|
|||||||
},
|
},
|
||||||
"components": {
|
"components": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {}
|
"items": {
|
||||||
|
"$ref": "#/components/schemas/MessageComponent"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"poll": {
|
||||||
|
"$ref": "#/components/schemas/PollCreationSchema"
|
||||||
|
},
|
||||||
|
"enforce_nonce": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"applied_tags": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"thread_name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"avatar_url": {
|
||||||
|
"type": "string"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -5919,6 +6101,9 @@
|
|||||||
"explicit_content_filter": {
|
"explicit_content_filter": {
|
||||||
"type": "integer"
|
"type": "integer"
|
||||||
},
|
},
|
||||||
|
"friend_discovery_flags": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
"friend_source_flags": {
|
"friend_source_flags": {
|
||||||
"$ref": "#/components/schemas/FriendSourceFlags"
|
"$ref": "#/components/schemas/FriendSourceFlags"
|
||||||
},
|
},
|
||||||
@ -5982,6 +6167,9 @@
|
|||||||
},
|
},
|
||||||
"timezone_offset": {
|
"timezone_offset": {
|
||||||
"type": "integer"
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"view_nsfw_guilds": {
|
||||||
|
"type": "boolean"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -7660,6 +7848,9 @@
|
|||||||
"$ref": "#/components/schemas/StickerPack"
|
"$ref": "#/components/schemas/StickerPack"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"APIConnectionsConfiguration": {
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
"UpdatesResponse": {
|
"UpdatesResponse": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@ -7917,6 +8108,23 @@
|
|||||||
"user"
|
"user"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"BulkBanSchema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"user_ids": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"delete_message_seconds": {
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"user_ids"
|
||||||
|
]
|
||||||
|
},
|
||||||
"BulkDeleteSchema": {
|
"BulkDeleteSchema": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@ -13729,12 +13937,25 @@
|
|||||||
},
|
},
|
||||||
"/guilds/{guild_id}/bulk-ban/": {
|
"/guilds/{guild_id}/bulk-ban/": {
|
||||||
"post": {
|
"post": {
|
||||||
"x-permission-required": "BAN_MEMBERS",
|
"x-permission-required": [
|
||||||
|
"BAN_MEMBERS",
|
||||||
|
"MANAGE_GUILD"
|
||||||
|
],
|
||||||
"security": [
|
"security": [
|
||||||
{
|
{
|
||||||
"bearer": []
|
"bearer": []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"requestBody": {
|
||||||
|
"required": true,
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/BulkBanSchema"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
"description": "",
|
"description": "",
|
||||||
@ -14322,6 +14543,30 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/connections/": {
|
||||||
|
"get": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"bearer": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/APIConnectionsConfiguration"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tags": [
|
||||||
|
"connections"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
"/connections/{connection_name}/callback/": {
|
"/connections/{connection_name}/callback/": {
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
|
Before Width: | Height: | Size: 4.5 KiB |
BIN
assets/public/22341bdb500c7b63a93bbce957d1601e.png
Normal file
After Width: | Height: | Size: 4.4 KiB |
BIN
assets/public/4a8562cf00887030c416d3ec2d46385a.png
Normal file
After Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 4.4 KiB |
BIN
assets/public/7213ab6677377974697dfdfbaf5f6a6f.png
Normal file
After Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 4.3 KiB |
BIN
assets/public/9b0bb198936784c45c72833cc426cc55.png
Normal file
After Width: | Height: | Size: 4.1 KiB |
BIN
assets/public/9d6ddb4e4d899a533a8cc617011351c9.png
Normal file
After Width: | Height: | Size: 4.4 KiB |
Before Width: | Height: | Size: 4.4 KiB |
Before Width: | Height: | Size: 4.2 KiB |
BIN
assets/public/d9977836b82058bf2f74eebd50edc095.png
Normal file
After Width: | Height: | Size: 4.4 KiB |
Before Width: | Height: | Size: 4.1 KiB |
147
assets/public/verify.html
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>Spacebar Server</title>
|
||||||
|
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||||
|
<link
|
||||||
|
href="https://fonts.googleapis.com/css2?family=Montserrat&display=swap"
|
||||||
|
rel="stylesheet"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: "Montserrat", sans-serif;
|
||||||
|
background-color: rgb(10, 10, 10);
|
||||||
|
color: white;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#wordmark {
|
||||||
|
width: min(200px, 50%);
|
||||||
|
margin: 20px;
|
||||||
|
position: absolute;
|
||||||
|
top: 20px;
|
||||||
|
left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subtitle {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box {
|
||||||
|
width: 22vw;
|
||||||
|
padding: 32px;
|
||||||
|
border-radius: 8px;
|
||||||
|
background-color: rgb(32, 32, 32);
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<img
|
||||||
|
alt="Spacebar Logo"
|
||||||
|
id="wordmark"
|
||||||
|
src="https://raw.githubusercontent.com/spacebarchat/spacebarchat/master/branding/svg/Spacebar__Logo-Blue.svg"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div class="box">
|
||||||
|
<p id="title" class="title">Verifying your email</p>
|
||||||
|
<p id="subtitle" class="subtitle">Please wait...</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
window.onload = verify;
|
||||||
|
|
||||||
|
function verify() {
|
||||||
|
const title = document.getElementById("title");
|
||||||
|
const subtitle = document.getElementById("subtitle");
|
||||||
|
|
||||||
|
// if no fragment identifier in URL, error
|
||||||
|
if (!window.location.hash) {
|
||||||
|
title.innerText = "Invalid Link";
|
||||||
|
subtitle.innerText = "Please check the link and try again.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert fragment to a key-value pair
|
||||||
|
const fragment = window.location.hash.substring(1);
|
||||||
|
const pairs = fragment.split("&");
|
||||||
|
const values = {};
|
||||||
|
pairs.forEach((pair) => {
|
||||||
|
const [key, value] = pair.split("=");
|
||||||
|
values[key] = value;
|
||||||
|
});
|
||||||
|
|
||||||
|
// ensure token key is present
|
||||||
|
if (!values.token) {
|
||||||
|
title.innerText = "Invalid Link";
|
||||||
|
subtitle.innerText = "Please check the link and try again.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// make request to server
|
||||||
|
const token = values.token;
|
||||||
|
fetch("/api/auth/verify", {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
token,
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
.then((response) => response.json())
|
||||||
|
.then((data) => {
|
||||||
|
// check for an error response
|
||||||
|
if ("message" in data) {
|
||||||
|
title.innerText = "Email Verification Link Expired";
|
||||||
|
subtitle.innerText =
|
||||||
|
"Please request a new verification link.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
title.innerText = "Email Verified";
|
||||||
|
subtitle.innerText = "You can now login.";
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
title.innerText = "Email Verification Failed";
|
||||||
|
subtitle.innerText = error;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
46276
assets/schemas.json
@ -18,15 +18,15 @@
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
Config,
|
Config,
|
||||||
Email,
|
|
||||||
initDatabase,
|
|
||||||
initEvent,
|
|
||||||
JSONReplacer,
|
|
||||||
registerRoutes,
|
|
||||||
Sentry,
|
|
||||||
WebAuthn,
|
|
||||||
ConnectionConfig,
|
ConnectionConfig,
|
||||||
ConnectionLoader,
|
ConnectionLoader,
|
||||||
|
Email,
|
||||||
|
JSONReplacer,
|
||||||
|
Sentry,
|
||||||
|
WebAuthn,
|
||||||
|
initDatabase,
|
||||||
|
initEvent,
|
||||||
|
registerRoutes,
|
||||||
} from "@spacebar/util";
|
} from "@spacebar/util";
|
||||||
import { Request, Response, Router } from "express";
|
import { Request, Response, Router } from "express";
|
||||||
import { Server, ServerOptions } from "lambert-server";
|
import { Server, ServerOptions } from "lambert-server";
|
||||||
@ -143,6 +143,10 @@ export class SpacebarServer extends Server {
|
|||||||
res.sendFile(path.join(PUBLIC_ASSETS_FOLDER, "index.html")),
|
res.sendFile(path.join(PUBLIC_ASSETS_FOLDER, "index.html")),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
app.get("/verify", (req, res) =>
|
||||||
|
res.sendFile(path.join(PUBLIC_ASSETS_FOLDER, "verify.html")),
|
||||||
|
);
|
||||||
|
|
||||||
this.app.use(ErrorHandler);
|
this.app.use(ErrorHandler);
|
||||||
|
|
||||||
Sentry.errorHandler(this.app);
|
Sentry.errorHandler(this.app);
|
||||||
|
@ -85,7 +85,7 @@ router.post(
|
|||||||
user = userTokenData.user;
|
user = userTokenData.user;
|
||||||
} catch {
|
} catch {
|
||||||
throw FieldErrors({
|
throw FieldErrors({
|
||||||
password: {
|
token: {
|
||||||
message: req.t("auth:password_reset.INVALID_TOKEN"),
|
message: req.t("auth:password_reset.INVALID_TOKEN"),
|
||||||
code: "INVALID_TOKEN",
|
code: "INVALID_TOKEN",
|
||||||
},
|
},
|
||||||
|
@ -50,7 +50,13 @@ router.get(
|
|||||||
const channel = await Channel.findOneOrFail({
|
const channel = await Channel.findOneOrFail({
|
||||||
where: { id: channel_id },
|
where: { id: channel_id },
|
||||||
});
|
});
|
||||||
|
if (!channel.guild_id) return res.send(channel);
|
||||||
|
|
||||||
|
channel.position = await Channel.calculatePosition(
|
||||||
|
channel_id,
|
||||||
|
channel.guild_id,
|
||||||
|
channel.guild,
|
||||||
|
);
|
||||||
return res.send(channel);
|
return res.send(channel);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
/*
|
/*
|
||||||
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
||||||
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU Affero General Public License as published
|
it under the terms of the GNU Affero General Public License as published
|
||||||
by the Free Software Foundation, either version 3 of the License, or
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU Affero General Public License for more details.
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU Affero General Public License
|
You should have received a copy of the GNU Affero General Public License
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
@ -56,6 +56,7 @@ router.post(
|
|||||||
edited_timestamp: null,
|
edited_timestamp: null,
|
||||||
flags: 1,
|
flags: 1,
|
||||||
components: [],
|
components: [],
|
||||||
|
poll: {},
|
||||||
}).status(200);
|
}).status(200);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
/*
|
/*
|
||||||
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
||||||
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU Affero General Public License as published
|
it under the terms of the GNU Affero General Public License as published
|
||||||
by the Free Software Foundation, either version 3 of the License, or
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU Affero General Public License for more details.
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU Affero General Public License
|
You should have received a copy of the GNU Affero General Public License
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
@ -91,11 +91,10 @@ router.patch(
|
|||||||
}
|
}
|
||||||
} else rights.hasThrow("SELF_EDIT_MESSAGES");
|
} else rights.hasThrow("SELF_EDIT_MESSAGES");
|
||||||
|
|
||||||
|
// @ts-expect-error Something is wrong with message_reference here, TS complains since "channel_id" is optional in MessageCreateSchema
|
||||||
const new_message = await handleMessage({
|
const new_message = await handleMessage({
|
||||||
...message,
|
...message,
|
||||||
// TODO: should message_reference be overridable?
|
// TODO: should message_reference be overridable?
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
||||||
// @ts-ignore
|
|
||||||
message_reference: message.message_reference,
|
message_reference: message.message_reference,
|
||||||
...body,
|
...body,
|
||||||
author_id: message.author_id,
|
author_id: message.author_id,
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
/*
|
/*
|
||||||
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
||||||
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU Affero General Public License as published
|
it under the terms of the GNU Affero General Public License as published
|
||||||
by the Free Software Foundation, either version 3 of the License, or
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU Affero General Public License for more details.
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU Affero General Public License
|
You should have received a copy of the GNU Affero General Public License
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
@ -183,9 +183,17 @@ router.get(
|
|||||||
const uri = y.proxy_url.startsWith("http")
|
const uri = y.proxy_url.startsWith("http")
|
||||||
? y.proxy_url
|
? y.proxy_url
|
||||||
: `https://example.org${y.proxy_url}`;
|
: `https://example.org${y.proxy_url}`;
|
||||||
y.proxy_url = `${endpoint == null ? "" : endpoint}${
|
|
||||||
new URL(uri).pathname
|
let pathname = new URL(uri).pathname;
|
||||||
}`;
|
while (
|
||||||
|
pathname.split("/")[0] != "attachments" &&
|
||||||
|
pathname.length > 30
|
||||||
|
) {
|
||||||
|
pathname = pathname.split("/").slice(1).join("/");
|
||||||
|
}
|
||||||
|
if (!endpoint?.endsWith("/")) pathname = "/" + pathname;
|
||||||
|
|
||||||
|
y.proxy_url = `${endpoint == null ? "" : endpoint}${pathname}`;
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
/*
|
/*
|
||||||
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
||||||
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU Affero General Public License as published
|
it under the terms of the GNU Affero General Public License as published
|
||||||
by the Free Software Foundation, either version 3 of the License, or
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU Affero General Public License for more details.
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU Affero General Public License
|
You should have received a copy of the GNU Affero General Public License
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
@ -53,6 +53,11 @@ router.put(
|
|||||||
where: { id: channel_id },
|
where: { id: channel_id },
|
||||||
});
|
});
|
||||||
if (!channel.guild_id) throw new HTTPError("Channel not found", 404);
|
if (!channel.guild_id) throw new HTTPError("Channel not found", 404);
|
||||||
|
channel.position = await Channel.calculatePosition(
|
||||||
|
channel_id,
|
||||||
|
channel.guild_id,
|
||||||
|
channel.guild,
|
||||||
|
);
|
||||||
|
|
||||||
if (body.type === 0) {
|
if (body.type === 0) {
|
||||||
if (!(await Role.count({ where: { id: overwrite_id } })))
|
if (!(await Role.count({ where: { id: overwrite_id } })))
|
||||||
|
45
src/api/routes/connections/index.ts
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
||||||
|
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as published
|
||||||
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { route } from "@spacebar/api";
|
||||||
|
import { ConnectionConfig } from "@spacebar/util";
|
||||||
|
import { Request, Response, Router } from "express";
|
||||||
|
const router = Router();
|
||||||
|
|
||||||
|
router.get(
|
||||||
|
"/",
|
||||||
|
route({
|
||||||
|
responses: {
|
||||||
|
200: {
|
||||||
|
body: "APIConnectionsConfiguration",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
async (req: Request, res: Response) => {
|
||||||
|
const config = ConnectionConfig.get();
|
||||||
|
|
||||||
|
Object.keys(config).forEach((key) => {
|
||||||
|
delete config[key].clientId;
|
||||||
|
delete config[key].clientSecret;
|
||||||
|
});
|
||||||
|
|
||||||
|
res.json(config);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
export default router;
|
@ -1,17 +1,17 @@
|
|||||||
/*
|
/*
|
||||||
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
||||||
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU Affero General Public License as published
|
it under the terms of the GNU Affero General Public License as published
|
||||||
by the Free Software Foundation, either version 3 of the License, or
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU Affero General Public License for more details.
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU Affero General Public License
|
You should have received a copy of the GNU Affero General Public License
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
@ -41,6 +41,15 @@ router.get(
|
|||||||
const { guild_id } = req.params;
|
const { guild_id } = req.params;
|
||||||
const channels = await Channel.find({ where: { guild_id } });
|
const channels = await Channel.find({ where: { guild_id } });
|
||||||
|
|
||||||
|
for await (const channel of channels) {
|
||||||
|
channel.position = await Channel.calculatePosition(
|
||||||
|
channel.id,
|
||||||
|
guild_id,
|
||||||
|
channel.guild,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
channels.sort((a, b) => a.position - b.position);
|
||||||
|
|
||||||
res.json(channels);
|
res.json(channels);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -71,6 +80,11 @@ router.post(
|
|||||||
{ ...body, guild_id },
|
{ ...body, guild_id },
|
||||||
req.user_id,
|
req.user_id,
|
||||||
);
|
);
|
||||||
|
channel.position = await Channel.calculatePosition(
|
||||||
|
channel.id,
|
||||||
|
guild_id,
|
||||||
|
channel.guild,
|
||||||
|
);
|
||||||
|
|
||||||
res.status(201).json(channel);
|
res.status(201).json(channel);
|
||||||
},
|
},
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
/*
|
/*
|
||||||
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
||||||
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU Affero General Public License as published
|
it under the terms of the GNU Affero General Public License as published
|
||||||
by the Free Software Foundation, either version 3 of the License, or
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU Affero General Public License for more details.
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU Affero General Public License
|
You should have received a copy of the GNU Affero General Public License
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
@ -125,6 +125,7 @@ router.post(
|
|||||||
const user = await User.findOneOrFail({ where: { id: req.user_id } });
|
const user = await User.findOneOrFail({ where: { id: req.user_id } });
|
||||||
body.image = (await handleFile(`/emojis/${id}`, body.image)) as string;
|
body.image = (await handleFile(`/emojis/${id}`, body.image)) as string;
|
||||||
|
|
||||||
|
const mimeType = body.image.split(":")[1].split(";")[0];
|
||||||
const emoji = await Emoji.create({
|
const emoji = await Emoji.create({
|
||||||
id: id,
|
id: id,
|
||||||
guild_id: guild_id,
|
guild_id: guild_id,
|
||||||
@ -132,7 +133,10 @@ router.post(
|
|||||||
require_colons: body.require_colons ?? undefined, // schema allows nulls, db does not
|
require_colons: body.require_colons ?? undefined, // schema allows nulls, db does not
|
||||||
user: user,
|
user: user,
|
||||||
managed: false,
|
managed: false,
|
||||||
animated: false, // TODO: Add support animated emojis
|
animated:
|
||||||
|
mimeType == "image/gif" ||
|
||||||
|
mimeType == "image/apng" ||
|
||||||
|
mimeType == "video/webm",
|
||||||
available: true,
|
available: true,
|
||||||
roles: [],
|
roles: [],
|
||||||
}).save();
|
}).save();
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
/*
|
/*
|
||||||
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
||||||
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU Affero General Public License as published
|
it under the terms of the GNU Affero General Public License as published
|
||||||
by the Free Software Foundation, either version 3 of the License, or
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU Affero General Public License for more details.
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU Affero General Public License
|
You should have received a copy of the GNU Affero General Public License
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
@ -162,6 +162,7 @@ router.get(
|
|||||||
edited_timestamp: x.edited_timestamp,
|
edited_timestamp: x.edited_timestamp,
|
||||||
flags: x.flags,
|
flags: x.flags,
|
||||||
components: x.components,
|
components: x.components,
|
||||||
|
poll: x.poll,
|
||||||
hit: true,
|
hit: true,
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
import { route } from "@spacebar/api";
|
import { route } from "@spacebar/api";
|
||||||
import {
|
import {
|
||||||
|
Badge,
|
||||||
Member,
|
Member,
|
||||||
PrivateUserProjection,
|
PrivateUserProjection,
|
||||||
User,
|
User,
|
||||||
@ -98,6 +99,9 @@ router.get(
|
|||||||
bio: guild_member?.bio || "",
|
bio: guild_member?.bio || "",
|
||||||
guild_id,
|
guild_id,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const badges = await Badge.find();
|
||||||
|
|
||||||
res.json({
|
res.json({
|
||||||
connected_accounts: user.connected_accounts.filter(
|
connected_accounts: user.connected_accounts.filter(
|
||||||
(x) => x.visibility != 0,
|
(x) => x.visibility != 0,
|
||||||
@ -111,6 +115,7 @@ router.get(
|
|||||||
user_profile: userProfile,
|
user_profile: userProfile,
|
||||||
guild_member: guild_member?.toPublicMember(),
|
guild_member: guild_member?.toPublicMember(),
|
||||||
guild_member_profile: guild_id && guildMemberProfile,
|
guild_member_profile: guild_id && guildMemberProfile,
|
||||||
|
badges: badges.filter((x) => user.badge_ids?.includes(x.id)),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -1,57 +1,57 @@
|
|||||||
/*
|
/*
|
||||||
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
||||||
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU Affero General Public License as published
|
it under the terms of the GNU Affero General Public License as published
|
||||||
by the Free Software Foundation, either version 3 of the License, or
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU Affero General Public License for more details.
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU Affero General Public License
|
You should have received a copy of the GNU Affero General Public License
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import * as Sentry from "@sentry/node";
|
||||||
|
import { EmbedHandlers } from "@spacebar/api";
|
||||||
import {
|
import {
|
||||||
|
Application,
|
||||||
|
Attachment,
|
||||||
Channel,
|
Channel,
|
||||||
|
Config,
|
||||||
Embed,
|
Embed,
|
||||||
|
EmbedCache,
|
||||||
emitEvent,
|
emitEvent,
|
||||||
Guild,
|
EVERYONE_MENTION,
|
||||||
Message,
|
|
||||||
MessageCreateEvent,
|
|
||||||
MessageUpdateEvent,
|
|
||||||
getPermission,
|
getPermission,
|
||||||
getRights,
|
getRights,
|
||||||
|
Guild,
|
||||||
|
HERE_MENTION,
|
||||||
|
Message,
|
||||||
|
MessageCreateEvent,
|
||||||
|
MessageCreateSchema,
|
||||||
|
MessageType,
|
||||||
|
MessageUpdateEvent,
|
||||||
|
Role,
|
||||||
|
ROLE_MENTION,
|
||||||
|
Sticker,
|
||||||
|
User,
|
||||||
//CHANNEL_MENTION,
|
//CHANNEL_MENTION,
|
||||||
USER_MENTION,
|
USER_MENTION,
|
||||||
ROLE_MENTION,
|
|
||||||
Role,
|
|
||||||
EVERYONE_MENTION,
|
|
||||||
HERE_MENTION,
|
|
||||||
MessageType,
|
|
||||||
User,
|
|
||||||
Application,
|
|
||||||
Webhook,
|
Webhook,
|
||||||
Attachment,
|
|
||||||
Config,
|
|
||||||
Sticker,
|
|
||||||
MessageCreateSchema,
|
|
||||||
EmbedCache,
|
|
||||||
} from "@spacebar/util";
|
} from "@spacebar/util";
|
||||||
import { HTTPError } from "lambert-server";
|
import { HTTPError } from "lambert-server";
|
||||||
import { In } from "typeorm";
|
import { In } from "typeorm";
|
||||||
import { EmbedHandlers } from "@spacebar/api";
|
|
||||||
import * as Sentry from "@sentry/node";
|
|
||||||
const allow_empty = false;
|
const allow_empty = false;
|
||||||
// TODO: check webhook, application, system author, stickers
|
// TODO: check webhook, application, system author, stickers
|
||||||
// TODO: embed gifs/videos/images
|
// TODO: embed gifs/videos/images
|
||||||
|
|
||||||
const LINK_REGEX =
|
const LINK_REGEX =
|
||||||
/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)/g;
|
/<?https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)>?/g;
|
||||||
|
|
||||||
export async function handleMessage(opts: MessageOptions): Promise<Message> {
|
export async function handleMessage(opts: MessageOptions): Promise<Message> {
|
||||||
const channel = await Channel.findOneOrFail({
|
const channel = await Channel.findOneOrFail({
|
||||||
@ -66,6 +66,7 @@ export async function handleMessage(opts: MessageOptions): Promise<Message> {
|
|||||||
: undefined;
|
: undefined;
|
||||||
const message = Message.create({
|
const message = Message.create({
|
||||||
...opts,
|
...opts,
|
||||||
|
poll: opts.poll,
|
||||||
sticker_items: stickers,
|
sticker_items: stickers,
|
||||||
guild_id: channel.guild_id,
|
guild_id: channel.guild_id,
|
||||||
channel_id: opts.channel_id,
|
channel_id: opts.channel_id,
|
||||||
@ -116,6 +117,12 @@ export async function handleMessage(opts: MessageOptions): Promise<Message> {
|
|||||||
const guild = await Guild.findOneOrFail({
|
const guild = await Guild.findOneOrFail({
|
||||||
where: { id: channel.guild_id },
|
where: { id: channel.guild_id },
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (!opts.message_reference.guild_id)
|
||||||
|
opts.message_reference.guild_id = channel.guild_id;
|
||||||
|
if (!opts.message_reference.channel_id)
|
||||||
|
opts.message_reference.channel_id = opts.channel_id;
|
||||||
|
|
||||||
if (!guild.features.includes("CROSS_CHANNEL_REPLIES")) {
|
if (!guild.features.includes("CROSS_CHANNEL_REPLIES")) {
|
||||||
if (opts.message_reference.guild_id !== channel.guild_id)
|
if (opts.message_reference.guild_id !== channel.guild_id)
|
||||||
throw new HTTPError(
|
throw new HTTPError(
|
||||||
@ -126,6 +133,8 @@ export async function handleMessage(opts: MessageOptions): Promise<Message> {
|
|||||||
"You can only reference messages from this channel",
|
"You can only reference messages from this channel",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message.message_reference = opts.message_reference;
|
||||||
}
|
}
|
||||||
/** Q: should be checked if the referenced message exists? ANSWER: NO
|
/** Q: should be checked if the referenced message exists? ANSWER: NO
|
||||||
otherwise backfilling won't work **/
|
otherwise backfilling won't work **/
|
||||||
@ -138,7 +147,9 @@ export async function handleMessage(opts: MessageOptions): Promise<Message> {
|
|||||||
!opts.content &&
|
!opts.content &&
|
||||||
!opts.embeds?.length &&
|
!opts.embeds?.length &&
|
||||||
!opts.attachments?.length &&
|
!opts.attachments?.length &&
|
||||||
!opts.sticker_ids?.length
|
!opts.sticker_ids?.length &&
|
||||||
|
!opts.poll &&
|
||||||
|
!opts.components?.length
|
||||||
) {
|
) {
|
||||||
throw new HTTPError("Empty messages are not allowed", 50006);
|
throw new HTTPError("Empty messages are not allowed", 50006);
|
||||||
}
|
}
|
||||||
@ -213,6 +224,9 @@ export async function postHandleMessage(message: Message) {
|
|||||||
const cachePromises = [];
|
const cachePromises = [];
|
||||||
|
|
||||||
for (const link of links) {
|
for (const link of links) {
|
||||||
|
// Don't embed links in <>
|
||||||
|
if (link.startsWith("<") && link.endsWith(">")) continue;
|
||||||
|
|
||||||
const url = new URL(link);
|
const url = new URL(link);
|
||||||
|
|
||||||
const cached = await EmbedCache.findOne({ where: { url: link } });
|
const cached = await EmbedCache.findOne({ where: { url: link } });
|
||||||
|
40
src/cdn/routes/badge-icons.ts
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
||||||
|
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as published
|
||||||
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Router, Response, Request } from "express";
|
||||||
|
import { storage } from "../util/Storage";
|
||||||
|
import FileType from "file-type";
|
||||||
|
import { HTTPError } from "lambert-server";
|
||||||
|
|
||||||
|
const router = Router();
|
||||||
|
|
||||||
|
router.get("/:badge_id", async (req: Request, res: Response) => {
|
||||||
|
const { badge_id } = req.params;
|
||||||
|
const path = `badge-icons/${badge_id}`;
|
||||||
|
|
||||||
|
const file = await storage.get(path);
|
||||||
|
if (!file) throw new HTTPError("not found", 404);
|
||||||
|
const type = await FileType.fromBuffer(file);
|
||||||
|
|
||||||
|
res.set("Content-Type", type?.mime);
|
||||||
|
res.set("Cache-Control", "public, max-age=31536000, must-revalidate");
|
||||||
|
|
||||||
|
return res.send(file);
|
||||||
|
});
|
||||||
|
|
||||||
|
export default router;
|
@ -23,12 +23,12 @@ import { HTTPError } from "lambert-server";
|
|||||||
import { join } from "path";
|
import { join } from "path";
|
||||||
|
|
||||||
const defaultAvatarHashMap = new Map([
|
const defaultAvatarHashMap = new Map([
|
||||||
["0", "823a3de61c4dc2415cc4dbc38fca4299"],
|
["0", "4a8562cf00887030c416d3ec2d46385a"],
|
||||||
["1", "e56a89224be0b2b1f7c04eca975be468"],
|
["1", "9b0bb198936784c45c72833cc426cc55"],
|
||||||
["2", "0c8138dcc0dfe2689cdd73f7952c2475"],
|
["2", "22341bdb500c7b63a93bbce957d1601e"],
|
||||||
["3", "5ac2728593bb455250d11b848a0c36c6"],
|
["3", "d9977836b82058bf2f74eebd50edc095"],
|
||||||
["4", "addd2f3268df46459e1d6012ad8e75bd"],
|
["4", "9d6ddb4e4d899a533a8cc617011351c9"],
|
||||||
["5", "c4e0c8300fa491d94acfd2a1fb26cea8"],
|
["5", "7213ab6677377974697dfdfbaf5f6a6f"],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const defaultGroupDMAvatarHashMap = new Map([
|
const defaultGroupDMAvatarHashMap = new Map([
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
/*
|
/*
|
||||||
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
||||||
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU Affero General Public License as published
|
it under the terms of the GNU Affero General Public License as published
|
||||||
by the Free Software Foundation, either version 3 of the License, or
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU Affero General Public License for more details.
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU Affero General Public License
|
You should have received a copy of the GNU Affero General Public License
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
@ -47,13 +47,15 @@ export default class BattleNetConnection extends Connection {
|
|||||||
settings: BattleNetSettings = new BattleNetSettings();
|
settings: BattleNetSettings = new BattleNetSettings();
|
||||||
|
|
||||||
init(): void {
|
init(): void {
|
||||||
const settings =
|
this.settings = ConnectionLoader.getConnectionConfig<BattleNetSettings>(
|
||||||
ConnectionLoader.getConnectionConfig<BattleNetSettings>(
|
this.id,
|
||||||
this.id,
|
this.settings,
|
||||||
this.settings,
|
);
|
||||||
);
|
|
||||||
|
|
||||||
if (settings.enabled && (!settings.clientId || !settings.clientSecret))
|
if (
|
||||||
|
this.settings.enabled &&
|
||||||
|
(!this.settings.clientId || !this.settings.clientSecret)
|
||||||
|
)
|
||||||
throw new Error(`Invalid settings for connection ${this.id}`);
|
throw new Error(`Invalid settings for connection ${this.id}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
/*
|
/*
|
||||||
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
||||||
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU Affero General Public License as published
|
it under the terms of the GNU Affero General Public License as published
|
||||||
by the Free Software Foundation, either version 3 of the License, or
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU Affero General Public License for more details.
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU Affero General Public License
|
You should have received a copy of the GNU Affero General Public License
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
@ -43,12 +43,15 @@ export default class DiscordConnection extends Connection {
|
|||||||
settings: DiscordSettings = new DiscordSettings();
|
settings: DiscordSettings = new DiscordSettings();
|
||||||
|
|
||||||
init(): void {
|
init(): void {
|
||||||
const settings = ConnectionLoader.getConnectionConfig<DiscordSettings>(
|
this.settings = ConnectionLoader.getConnectionConfig<DiscordSettings>(
|
||||||
this.id,
|
this.id,
|
||||||
this.settings,
|
this.settings,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (settings.enabled && (!settings.clientId || !settings.clientSecret))
|
if (
|
||||||
|
this.settings.enabled &&
|
||||||
|
(!this.settings.clientId || !this.settings.clientSecret)
|
||||||
|
)
|
||||||
throw new Error(`Invalid settings for connection ${this.id}`);
|
throw new Error(`Invalid settings for connection ${this.id}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
/*
|
/*
|
||||||
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
||||||
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU Affero General Public License as published
|
it under the terms of the GNU Affero General Public License as published
|
||||||
by the Free Software Foundation, either version 3 of the License, or
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU Affero General Public License for more details.
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU Affero General Public License
|
You should have received a copy of the GNU Affero General Public License
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
@ -53,13 +53,15 @@ export default class EpicGamesConnection extends Connection {
|
|||||||
settings: EpicGamesSettings = new EpicGamesSettings();
|
settings: EpicGamesSettings = new EpicGamesSettings();
|
||||||
|
|
||||||
init(): void {
|
init(): void {
|
||||||
const settings =
|
this.settings = ConnectionLoader.getConnectionConfig<EpicGamesSettings>(
|
||||||
ConnectionLoader.getConnectionConfig<EpicGamesSettings>(
|
this.id,
|
||||||
this.id,
|
this.settings,
|
||||||
this.settings,
|
);
|
||||||
);
|
|
||||||
|
|
||||||
if (settings.enabled && (!settings.clientId || !settings.clientSecret))
|
if (
|
||||||
|
this.settings.enabled &&
|
||||||
|
(!this.settings.clientId || !this.settings.clientSecret)
|
||||||
|
)
|
||||||
throw new Error(`Invalid settings for connection ${this.id}`);
|
throw new Error(`Invalid settings for connection ${this.id}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
/*
|
/*
|
||||||
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
||||||
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU Affero General Public License as published
|
it under the terms of the GNU Affero General Public License as published
|
||||||
by the Free Software Foundation, either version 3 of the License, or
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU Affero General Public License for more details.
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU Affero General Public License
|
You should have received a copy of the GNU Affero General Public License
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
@ -52,12 +52,15 @@ export default class FacebookConnection extends Connection {
|
|||||||
settings: FacebookSettings = new FacebookSettings();
|
settings: FacebookSettings = new FacebookSettings();
|
||||||
|
|
||||||
init(): void {
|
init(): void {
|
||||||
const settings = ConnectionLoader.getConnectionConfig<FacebookSettings>(
|
this.settings = ConnectionLoader.getConnectionConfig<FacebookSettings>(
|
||||||
this.id,
|
this.id,
|
||||||
this.settings,
|
this.settings,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (settings.enabled && (!settings.clientId || !settings.clientSecret))
|
if (
|
||||||
|
this.settings.enabled &&
|
||||||
|
(!this.settings.clientId || !this.settings.clientSecret)
|
||||||
|
)
|
||||||
throw new Error(`Invalid settings for connection ${this.id}`);
|
throw new Error(`Invalid settings for connection ${this.id}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
/*
|
/*
|
||||||
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
||||||
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU Affero General Public License as published
|
it under the terms of the GNU Affero General Public License as published
|
||||||
by the Free Software Foundation, either version 3 of the License, or
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU Affero General Public License for more details.
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU Affero General Public License
|
You should have received a copy of the GNU Affero General Public License
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
@ -42,12 +42,15 @@ export default class GitHubConnection extends Connection {
|
|||||||
settings: GitHubSettings = new GitHubSettings();
|
settings: GitHubSettings = new GitHubSettings();
|
||||||
|
|
||||||
init(): void {
|
init(): void {
|
||||||
const settings = ConnectionLoader.getConnectionConfig<GitHubSettings>(
|
this.settings = ConnectionLoader.getConnectionConfig<GitHubSettings>(
|
||||||
this.id,
|
this.id,
|
||||||
this.settings,
|
this.settings,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (settings.enabled && (!settings.clientId || !settings.clientSecret))
|
if (
|
||||||
|
this.settings.enabled &&
|
||||||
|
(!this.settings.clientId || !this.settings.clientSecret)
|
||||||
|
)
|
||||||
throw new Error(`Invalid settings for connection ${this.id}`);
|
throw new Error(`Invalid settings for connection ${this.id}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
/*
|
/*
|
||||||
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
||||||
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU Affero General Public License as published
|
it under the terms of the GNU Affero General Public License as published
|
||||||
by the Free Software Foundation, either version 3 of the License, or
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU Affero General Public License for more details.
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU Affero General Public License
|
You should have received a copy of the GNU Affero General Public License
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
@ -54,12 +54,15 @@ export default class RedditConnection extends Connection {
|
|||||||
settings: RedditSettings = new RedditSettings();
|
settings: RedditSettings = new RedditSettings();
|
||||||
|
|
||||||
init(): void {
|
init(): void {
|
||||||
const settings = ConnectionLoader.getConnectionConfig<RedditSettings>(
|
this.settings = ConnectionLoader.getConnectionConfig<RedditSettings>(
|
||||||
this.id,
|
this.id,
|
||||||
this.settings,
|
this.settings,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (settings.enabled && (!settings.clientId || !settings.clientSecret))
|
if (
|
||||||
|
this.settings.enabled &&
|
||||||
|
(!this.settings.clientId || !this.settings.clientSecret)
|
||||||
|
)
|
||||||
throw new Error(`Invalid settings for connection ${this.id}`);
|
throw new Error(`Invalid settings for connection ${this.id}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
/*
|
/*
|
||||||
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
||||||
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU Affero General Public License as published
|
it under the terms of the GNU Affero General Public License as published
|
||||||
by the Free Software Foundation, either version 3 of the License, or
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU Affero General Public License for more details.
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU Affero General Public License
|
You should have received a copy of the GNU Affero General Public License
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
@ -63,12 +63,16 @@ export default class SpotifyConnection extends RefreshableConnection {
|
|||||||
* So to prevent spamming the spotify api we disable the ability to refresh.
|
* So to prevent spamming the spotify api we disable the ability to refresh.
|
||||||
*/
|
*/
|
||||||
this.refreshEnabled = false;
|
this.refreshEnabled = false;
|
||||||
const settings = ConnectionLoader.getConnectionConfig<SpotifySettings>(
|
|
||||||
|
this.settings = ConnectionLoader.getConnectionConfig<SpotifySettings>(
|
||||||
this.id,
|
this.id,
|
||||||
this.settings,
|
this.settings,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (settings.enabled && (!settings.clientId || !settings.clientSecret))
|
if (
|
||||||
|
this.settings.enabled &&
|
||||||
|
(!this.settings.clientId || !this.settings.clientSecret)
|
||||||
|
)
|
||||||
throw new Error(`Invalid settings for connection ${this.id}`);
|
throw new Error(`Invalid settings for connection ${this.id}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
/*
|
/*
|
||||||
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
||||||
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU Affero General Public License as published
|
it under the terms of the GNU Affero General Public License as published
|
||||||
by the Free Software Foundation, either version 3 of the License, or
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU Affero General Public License for more details.
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU Affero General Public License
|
You should have received a copy of the GNU Affero General Public License
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
@ -55,12 +55,15 @@ export default class TwitchConnection extends RefreshableConnection {
|
|||||||
settings: TwitchSettings = new TwitchSettings();
|
settings: TwitchSettings = new TwitchSettings();
|
||||||
|
|
||||||
init(): void {
|
init(): void {
|
||||||
const settings = ConnectionLoader.getConnectionConfig<TwitchSettings>(
|
this.settings = ConnectionLoader.getConnectionConfig<TwitchSettings>(
|
||||||
this.id,
|
this.id,
|
||||||
this.settings,
|
this.settings,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (settings.enabled && (!settings.clientId || !settings.clientSecret))
|
if (
|
||||||
|
this.settings.enabled &&
|
||||||
|
(!this.settings.clientId || !this.settings.clientSecret)
|
||||||
|
)
|
||||||
throw new Error(`Invalid settings for connection ${this.id}`);
|
throw new Error(`Invalid settings for connection ${this.id}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
/*
|
/*
|
||||||
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
||||||
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU Affero General Public License as published
|
it under the terms of the GNU Affero General Public License as published
|
||||||
by the Free Software Foundation, either version 3 of the License, or
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU Affero General Public License for more details.
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU Affero General Public License
|
You should have received a copy of the GNU Affero General Public License
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
@ -55,12 +55,15 @@ export default class TwitterConnection extends RefreshableConnection {
|
|||||||
settings: TwitterSettings = new TwitterSettings();
|
settings: TwitterSettings = new TwitterSettings();
|
||||||
|
|
||||||
init(): void {
|
init(): void {
|
||||||
const settings = ConnectionLoader.getConnectionConfig<TwitterSettings>(
|
this.settings = ConnectionLoader.getConnectionConfig<TwitterSettings>(
|
||||||
this.id,
|
this.id,
|
||||||
this.settings,
|
this.settings,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (settings.enabled && (!settings.clientId || !settings.clientSecret))
|
if (
|
||||||
|
this.settings.enabled &&
|
||||||
|
(!this.settings.clientId || !this.settings.clientSecret)
|
||||||
|
)
|
||||||
throw new Error(`Invalid settings for connection ${this.id}`);
|
throw new Error(`Invalid settings for connection ${this.id}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
/*
|
/*
|
||||||
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
||||||
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU Affero General Public License as published
|
it under the terms of the GNU Affero General Public License as published
|
||||||
by the Free Software Foundation, either version 3 of the License, or
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU Affero General Public License for more details.
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU Affero General Public License
|
You should have received a copy of the GNU Affero General Public License
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
@ -62,12 +62,15 @@ export default class XboxConnection extends Connection {
|
|||||||
settings: XboxSettings = new XboxSettings();
|
settings: XboxSettings = new XboxSettings();
|
||||||
|
|
||||||
init(): void {
|
init(): void {
|
||||||
const settings = ConnectionLoader.getConnectionConfig<XboxSettings>(
|
this.settings = ConnectionLoader.getConnectionConfig<XboxSettings>(
|
||||||
this.id,
|
this.id,
|
||||||
this.settings,
|
this.settings,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (settings.enabled && (!settings.clientId || !settings.clientSecret))
|
if (
|
||||||
|
this.settings.enabled &&
|
||||||
|
(!this.settings.clientId || !this.settings.clientSecret)
|
||||||
|
)
|
||||||
throw new Error(`Invalid settings for connection ${this.id}`);
|
throw new Error(`Invalid settings for connection ${this.id}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
/*
|
/*
|
||||||
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
||||||
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU Affero General Public License as published
|
it under the terms of the GNU Affero General Public License as published
|
||||||
by the Free Software Foundation, either version 3 of the License, or
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU Affero General Public License for more details.
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU Affero General Public License
|
You should have received a copy of the GNU Affero General Public License
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
@ -62,12 +62,15 @@ export default class YoutubeConnection extends Connection {
|
|||||||
settings: YoutubeSettings = new YoutubeSettings();
|
settings: YoutubeSettings = new YoutubeSettings();
|
||||||
|
|
||||||
init(): void {
|
init(): void {
|
||||||
const settings = ConnectionLoader.getConnectionConfig<YoutubeSettings>(
|
this.settings = ConnectionLoader.getConnectionConfig<YoutubeSettings>(
|
||||||
this.id,
|
this.id,
|
||||||
this.settings,
|
this.settings,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (settings.enabled && (!settings.clientId || !settings.clientSecret))
|
if (
|
||||||
|
this.settings.enabled &&
|
||||||
|
(!this.settings.clientId || !this.settings.clientSecret)
|
||||||
|
)
|
||||||
throw new Error(`Invalid settings for connection ${this.id}`);
|
throw new Error(`Invalid settings for connection ${this.id}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@ import { SendGridConfiguration } from "./subconfigurations/email/SendGrid";
|
|||||||
|
|
||||||
export class EmailConfiguration {
|
export class EmailConfiguration {
|
||||||
provider: string | null = null;
|
provider: string | null = null;
|
||||||
|
senderAddress: string | null = null;
|
||||||
smtp: SMTPConfiguration = new SMTPConfiguration();
|
smtp: SMTPConfiguration = new SMTPConfiguration();
|
||||||
mailgun: MailGunConfiguration = new MailGunConfiguration();
|
mailgun: MailGunConfiguration = new MailGunConfiguration();
|
||||||
mailjet: MailJetConfiguration = new MailJetConfiguration();
|
mailjet: MailJetConfiguration = new MailJetConfiguration();
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
/*
|
/*
|
||||||
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
||||||
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU Affero General Public License as published
|
it under the terms of the GNU Affero General Public License as published
|
||||||
by the Free Software Foundation, either version 3 of the License, or
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU Affero General Public License for more details.
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU Affero General Public License
|
You should have received a copy of the GNU Affero General Public License
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
@ -43,7 +43,7 @@ export abstract class Connection {
|
|||||||
*/
|
*/
|
||||||
getRedirectUri() {
|
getRedirectUri() {
|
||||||
const endpointPublic =
|
const endpointPublic =
|
||||||
Config.get().api.endpointPublic ?? "http://localhost:3001";
|
Config.get().general.frontPage ?? "http://localhost:3001";
|
||||||
return `${endpointPublic}/connections/${this.id}/callback`;
|
return `${endpointPublic}/connections/${this.id}/callback`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@ export class MinimalPublicUserDTO {
|
|||||||
id: string;
|
id: string;
|
||||||
public_flags: number;
|
public_flags: number;
|
||||||
username: string;
|
username: string;
|
||||||
|
badge_ids?: string[] | null;
|
||||||
|
|
||||||
constructor(user: User) {
|
constructor(user: User) {
|
||||||
this.avatar = user.avatar;
|
this.avatar = user.avatar;
|
||||||
@ -31,5 +32,6 @@ export class MinimalPublicUserDTO {
|
|||||||
this.id = user.id;
|
this.id = user.id;
|
||||||
this.public_flags = user.public_flags;
|
this.public_flags = user.public_flags;
|
||||||
this.username = user.username;
|
this.username = user.username;
|
||||||
|
this.badge_ids = user.badge_ids;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
35
src/util/entities/Badge.ts
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
||||||
|
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as published
|
||||||
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Column, Entity } from "typeorm";
|
||||||
|
import { BaseClassWithoutId } from "./BaseClass";
|
||||||
|
|
||||||
|
@Entity("badges")
|
||||||
|
export class Badge extends BaseClassWithoutId {
|
||||||
|
@Column({ primary: true })
|
||||||
|
id: string;
|
||||||
|
|
||||||
|
@Column()
|
||||||
|
description: string;
|
||||||
|
|
||||||
|
@Column()
|
||||||
|
icon: string;
|
||||||
|
|
||||||
|
@Column({ nullable: true })
|
||||||
|
link?: string;
|
||||||
|
}
|
@ -1,17 +1,17 @@
|
|||||||
/*
|
/*
|
||||||
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
||||||
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU Affero General Public License as published
|
it under the terms of the GNU Affero General Public License as published
|
||||||
by the Free Software Foundation, either version 3 of the License, or
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU Affero General Public License for more details.
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU Affero General Public License
|
You should have received a copy of the GNU Affero General Public License
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
@ -31,7 +31,7 @@ import {
|
|||||||
PrimaryGeneratedColumn,
|
PrimaryGeneratedColumn,
|
||||||
RelationId,
|
RelationId,
|
||||||
} from "typeorm";
|
} from "typeorm";
|
||||||
import { Ban, PublicGuildRelations } from ".";
|
import { Ban, Channel, PublicGuildRelations } from ".";
|
||||||
import { ReadyGuildDTO } from "../dtos";
|
import { ReadyGuildDTO } from "../dtos";
|
||||||
import {
|
import {
|
||||||
GuildCreateEvent,
|
GuildCreateEvent,
|
||||||
@ -330,6 +330,13 @@ export class Member extends BaseClassWithoutId {
|
|||||||
relationLoadStrategy: "query",
|
relationLoadStrategy: "query",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
for await (const channel of guild.channels) {
|
||||||
|
channel.position = await Channel.calculatePosition(
|
||||||
|
channel.id,
|
||||||
|
guild_id,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const memberCount = await Member.count({ where: { guild_id } });
|
const memberCount = await Member.count({ where: { guild_id } });
|
||||||
|
|
||||||
const memberPreview = (
|
const memberPreview = (
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
/*
|
/*
|
||||||
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
||||||
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU Affero General Public License as published
|
it under the terms of the GNU Affero General Public License as published
|
||||||
by the Free Software Foundation, either version 3 of the License, or
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU Affero General Public License for more details.
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU Affero General Public License
|
You should have received a copy of the GNU Affero General Public License
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
@ -218,6 +218,9 @@ export class Message extends BaseClass {
|
|||||||
@Column({ type: "simple-json", nullable: true })
|
@Column({ type: "simple-json", nullable: true })
|
||||||
components?: MessageComponent[];
|
components?: MessageComponent[];
|
||||||
|
|
||||||
|
@Column({ type: "simple-json", nullable: true })
|
||||||
|
poll?: Poll;
|
||||||
|
|
||||||
toJSON(): Message {
|
toJSON(): Message {
|
||||||
return {
|
return {
|
||||||
...this,
|
...this,
|
||||||
@ -238,6 +241,7 @@ export class Message extends BaseClass {
|
|||||||
activity: this.activity ?? undefined,
|
activity: this.activity ?? undefined,
|
||||||
application: this.application ?? undefined,
|
application: this.application ?? undefined,
|
||||||
components: this.components ?? undefined,
|
components: this.components ?? undefined,
|
||||||
|
poll: this.poll ?? undefined,
|
||||||
content: this.content ?? "",
|
content: this.content ?? "",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -249,6 +253,7 @@ export interface MessageComponent {
|
|||||||
label?: string;
|
label?: string;
|
||||||
emoji?: PartialEmoji;
|
emoji?: PartialEmoji;
|
||||||
custom_id?: string;
|
custom_id?: string;
|
||||||
|
sku_id?: string;
|
||||||
url?: string;
|
url?: string;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
components: MessageComponent[];
|
components: MessageComponent[];
|
||||||
@ -327,3 +332,32 @@ export interface AllowedMentions {
|
|||||||
users?: string[];
|
users?: string[];
|
||||||
replied_user?: boolean;
|
replied_user?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface Poll {
|
||||||
|
question: PollMedia;
|
||||||
|
answers: PollAnswer[];
|
||||||
|
expiry: Date;
|
||||||
|
allow_multiselect: boolean;
|
||||||
|
results?: PollResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PollMedia {
|
||||||
|
text?: string;
|
||||||
|
emoji?: PartialEmoji;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PollAnswer {
|
||||||
|
answer_id?: string;
|
||||||
|
poll_media: PollMedia;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PollResult {
|
||||||
|
is_finalized: boolean;
|
||||||
|
answer_counts: PollAnswerCount[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PollAnswerCount {
|
||||||
|
id: string;
|
||||||
|
count: number;
|
||||||
|
me_voted: boolean;
|
||||||
|
}
|
||||||
|
@ -49,6 +49,7 @@ export enum PublicUserEnum {
|
|||||||
premium_type,
|
premium_type,
|
||||||
theme_colors,
|
theme_colors,
|
||||||
pronouns,
|
pronouns,
|
||||||
|
badge_ids,
|
||||||
}
|
}
|
||||||
export type PublicUserKeys = keyof typeof PublicUserEnum;
|
export type PublicUserKeys = keyof typeof PublicUserEnum;
|
||||||
|
|
||||||
@ -231,6 +232,9 @@ export class User extends BaseClass {
|
|||||||
@OneToMany(() => SecurityKey, (key: SecurityKey) => key.user)
|
@OneToMany(() => SecurityKey, (key: SecurityKey) => key.user)
|
||||||
security_keys: SecurityKey[];
|
security_keys: SecurityKey[];
|
||||||
|
|
||||||
|
@Column({ type: "simple-array", nullable: true })
|
||||||
|
badge_ids?: string[];
|
||||||
|
|
||||||
// TODO: I don't like this method?
|
// TODO: I don't like this method?
|
||||||
validate() {
|
validate() {
|
||||||
if (this.discriminator) {
|
if (this.discriminator) {
|
||||||
|
@ -20,6 +20,7 @@ export * from "./Application";
|
|||||||
export * from "./Attachment";
|
export * from "./Attachment";
|
||||||
export * from "./AuditLog";
|
export * from "./AuditLog";
|
||||||
export * from "./BackupCodes";
|
export * from "./BackupCodes";
|
||||||
|
export * from "./Badge";
|
||||||
export * from "./Ban";
|
export * from "./Ban";
|
||||||
export * from "./BaseClass";
|
export * from "./BaseClass";
|
||||||
export * from "./Categories";
|
export * from "./Categories";
|
||||||
|
23
src/util/migration/mariadb/1719776735000-newUserSettings.ts
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||||
|
|
||||||
|
export class NewUserSettings1719776735000 implements MigrationInterface {
|
||||||
|
name = "NewUserSettings1719776735000";
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
"ALTER TABLE `user_settings` ADD friend_discovery_flags integer NULL DEFAULT 0;",
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
"ALTER TABLE `user_settings` ADD view_nsfw_guilds tinyint NULL DEFAULT 1;",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
"ALTER TABLE `user_settings` DROP COLUMN friend_discovery_flags;",
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
"ALTER TABLE `user_settings` DROP COLUMN view_nsfw_guilds;",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||||
|
|
||||||
|
export class MessagePollObject1720157926878 implements MigrationInterface {
|
||||||
|
name = "MessagePollObject1720157926878";
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query("ALTER TABLE `messages` ADD `poll` text NULL");
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query("ALTER TABLE `messages` DROP COLUMN `poll`");
|
||||||
|
}
|
||||||
|
}
|
21
src/util/migration/mariadb/1720628601997-badges.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||||
|
|
||||||
|
export class Badges1720628601997 implements MigrationInterface {
|
||||||
|
name = "Badges1720628601997";
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TABLE \`badges\` (\`id\` varchar(255) NOT NULL, \`description\` varchar(255) NOT NULL, \`icon\` varchar(255) NOT NULL, \`link\` varchar(255) NULL, PRIMARY KEY (\`id\`)) ENGINE=InnoDB`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE \`users\` ADD \`badge_ids\` text NULL`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE \`users\` DROP COLUMN \`badge_ids\``,
|
||||||
|
);
|
||||||
|
await queryRunner.query(`DROP TABLE \`badges\``);
|
||||||
|
}
|
||||||
|
}
|
23
src/util/migration/mysql/1719776735000-newUserSettings.ts
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||||
|
|
||||||
|
export class NewUserSettings1719776735000 implements MigrationInterface {
|
||||||
|
name = "NewUserSettings1719776735000";
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
"ALTER TABLE `user_settings` ADD friend_discovery_flags integer NULL DEFAULT 0;",
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
"ALTER TABLE `user_settings` ADD view_nsfw_guilds tinyint NULL DEFAULT 1;",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
"ALTER TABLE `user_settings` DROP COLUMN friend_discovery_flags;",
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
"ALTER TABLE `user_settings` DROP COLUMN view_nsfw_guilds;",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
13
src/util/migration/mysql/1720157926878-messagePollObject.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||||
|
|
||||||
|
export class MessagePollObject1720157926878 implements MigrationInterface {
|
||||||
|
name = "MessagePollObject1720157926878";
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query("ALTER TABLE `messages` ADD `poll` text NULL");
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query("ALTER TABLE `messages` DROP COLUMN `poll`");
|
||||||
|
}
|
||||||
|
}
|
21
src/util/migration/mysql/1720628601997-badges.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||||
|
|
||||||
|
export class Badges1720628601997 implements MigrationInterface {
|
||||||
|
name = "Badges1720628601997";
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TABLE \`badges\` (\`id\` varchar(255) NOT NULL, \`description\` varchar(255) NOT NULL, \`icon\` varchar(255) NOT NULL, \`link\` varchar(255) NULL, PRIMARY KEY (\`id\`)) ENGINE=InnoDB`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE \`users\` ADD \`badge_ids\` text NULL`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE \`users\` DROP COLUMN \`badge_ids\``,
|
||||||
|
);
|
||||||
|
await queryRunner.query(`DROP TABLE \`badges\``);
|
||||||
|
}
|
||||||
|
}
|
23
src/util/migration/postgres/1719776735000-newUserSettings.ts
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||||
|
|
||||||
|
export class NewUserSettings1719776735000 implements MigrationInterface {
|
||||||
|
name = "NewUserSettings1719776735000";
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
"ALTER TABLE user_settings ADD COLUMN friend_discovery_flags integer DEFAULT 0;",
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
"ALTER TABLE user_settings ADD COLUMN view_nsfw_guilds boolean DEFAULT true;",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
"ALTER TABLE user_settings DROP COLUMN friend_discovery_flags;",
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
"ALTER TABLE user_settings DROP COLUMN view_nsfw_guilds;",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||||
|
|
||||||
|
export class MessagePollObject1720157926878 implements MigrationInterface {
|
||||||
|
name = "MessagePollObject1720157926878";
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query("ALTER TABLE messages ADD poll text NULL");
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query("ALTER TABLE messages DROP COLUMN poll");
|
||||||
|
}
|
||||||
|
}
|
16
src/util/migration/postgres/1720628601997-badges.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||||
|
|
||||||
|
export class Badges1720628601997 implements MigrationInterface {
|
||||||
|
name = "Badges1720628601997";
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TABLE "badges" ("id" character varying NOT NULL, "description" character varying NOT NULL, "icon" character varying NOT NULL, "link" character varying, CONSTRAINT "PK_8a651318b8de577e8e217676466" PRIMARY KEY ("id"))`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(`ALTER TABLE "users" ADD "badge_ids" text`);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(`ALTER TABLE "users" DROP COLUMN "badge_ids"`);
|
||||||
|
}
|
||||||
|
}
|
@ -1,22 +1,22 @@
|
|||||||
/*
|
/*
|
||||||
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
||||||
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU Affero General Public License as published
|
it under the terms of the GNU Affero General Public License as published
|
||||||
by the Free Software Foundation, either version 3 of the License, or
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU Affero General Public License for more details.
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU Affero General Public License
|
You should have received a copy of the GNU Affero General Public License
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Embed } from "@spacebar/util";
|
import { Embed, MessageComponent, PollAnswer, PollMedia } from "@spacebar/util";
|
||||||
|
|
||||||
type Attachment = {
|
type Attachment = {
|
||||||
id: string;
|
id: string;
|
||||||
@ -42,7 +42,7 @@ export interface MessageCreateSchema {
|
|||||||
};
|
};
|
||||||
message_reference?: {
|
message_reference?: {
|
||||||
message_id: string;
|
message_id: string;
|
||||||
channel_id: string;
|
channel_id?: string;
|
||||||
guild_id?: string;
|
guild_id?: string;
|
||||||
fail_if_not_exists?: boolean;
|
fail_if_not_exists?: boolean;
|
||||||
};
|
};
|
||||||
@ -54,6 +54,21 @@ export interface MessageCreateSchema {
|
|||||||
**/
|
**/
|
||||||
attachments?: Attachment[];
|
attachments?: Attachment[];
|
||||||
sticker_ids?: string[];
|
sticker_ids?: string[];
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
components?: MessageComponent[];
|
||||||
components?: any[];
|
// TODO: Fix TypeScript errors in src\api\util\handlers\Message.ts once this is enabled
|
||||||
|
poll?: PollCreationSchema;
|
||||||
|
enforce_nonce?: boolean; // For Discord compatibility, it's the default behavior here
|
||||||
|
applied_tags?: string[]; // Not implemented yet, for webhooks in forums
|
||||||
|
thread_name?: string; // Not implemented yet, for webhooks
|
||||||
|
avatar_url?: string; // Not implemented yet, for webhooks
|
||||||
|
}
|
||||||
|
|
||||||
|
// TypeScript complains once this is used above
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
interface PollCreationSchema {
|
||||||
|
question: PollMedia;
|
||||||
|
answers: PollAnswer[];
|
||||||
|
duration?: number;
|
||||||
|
allow_multiselect?: boolean;
|
||||||
|
layout_type?: number;
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
/*
|
/*
|
||||||
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
||||||
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU Affero General Public License as published
|
it under the terms of the GNU Affero General Public License as published
|
||||||
by the Free Software Foundation, either version 3 of the License, or
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU Affero General Public License for more details.
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU Affero General Public License
|
You should have received a copy of the GNU Affero General Public License
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
@ -19,7 +19,9 @@
|
|||||||
import {
|
import {
|
||||||
Attachment,
|
Attachment,
|
||||||
Embed,
|
Embed,
|
||||||
|
MessageComponent,
|
||||||
MessageType,
|
MessageType,
|
||||||
|
Poll,
|
||||||
PublicUser,
|
PublicUser,
|
||||||
Role,
|
Role,
|
||||||
} from "../../entities";
|
} from "../../entities";
|
||||||
@ -40,7 +42,8 @@ export interface GuildMessagesSearchMessage {
|
|||||||
timestamp: string;
|
timestamp: string;
|
||||||
edited_timestamp: string | null;
|
edited_timestamp: string | null;
|
||||||
flags: number;
|
flags: number;
|
||||||
components: unknown[];
|
components: MessageComponent[];
|
||||||
|
poll: Poll;
|
||||||
hit: true;
|
hit: true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
/*
|
/*
|
||||||
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
||||||
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU Affero General Public License as published
|
it under the terms of the GNU Affero General Public License as published
|
||||||
by the Free Software Foundation, either version 3 of the License, or
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU Affero General Public License for more details.
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU Affero General Public License
|
You should have received a copy of the GNU Affero General Public License
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
@ -104,3 +104,10 @@ export type APIGuildVoiceRegion = GuildVoiceRegion[];
|
|||||||
export type APILimitsConfiguration = LimitsConfiguration;
|
export type APILimitsConfiguration = LimitsConfiguration;
|
||||||
|
|
||||||
export type APIStickerPackArray = StickerPack[];
|
export type APIStickerPackArray = StickerPack[];
|
||||||
|
|
||||||
|
export type APIConnectionsConfiguration = Record<
|
||||||
|
string,
|
||||||
|
{
|
||||||
|
enabled: boolean;
|
||||||
|
}
|
||||||
|
>;
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
Badge,
|
||||||
Member,
|
Member,
|
||||||
PublicConnectedAccount,
|
PublicConnectedAccount,
|
||||||
PublicMember,
|
PublicMember,
|
||||||
@ -52,4 +53,5 @@ export interface UserProfileResponse {
|
|||||||
user_profile: UserProfile;
|
user_profile: UserProfile;
|
||||||
guild_member?: PublicMember;
|
guild_member?: PublicMember;
|
||||||
guild_member_profile?: PublicMemberProfile;
|
guild_member_profile?: PublicMemberProfile;
|
||||||
|
badges: Badge[];
|
||||||
}
|
}
|
||||||
|
@ -141,8 +141,9 @@ export const Email: {
|
|||||||
*/
|
*/
|
||||||
generateLink: async function (type, id, email) {
|
generateLink: async function (type, id, email) {
|
||||||
const token = (await generateToken(id, email)) as string;
|
const token = (await generateToken(id, email)) as string;
|
||||||
|
// puyodead1: this is set to api endpoint because the verification page is on the server since no clients have one, and not all 3rd party clients will have one
|
||||||
const instanceUrl =
|
const instanceUrl =
|
||||||
Config.get().general.frontPage || "http://localhost:3001";
|
Config.get().api.endpointPublic || "http://localhost:3001";
|
||||||
const link = `${instanceUrl}/${type}#token=${token}`;
|
const link = `${instanceUrl}/${type}#token=${token}`;
|
||||||
return link;
|
return link;
|
||||||
},
|
},
|
||||||
@ -187,7 +188,9 @@ export const Email: {
|
|||||||
|
|
||||||
const message = {
|
const message = {
|
||||||
from:
|
from:
|
||||||
Config.get().general.correspondenceEmail || "noreply@localhost",
|
Config.get().email.senderAddress ||
|
||||||
|
Config.get().general.correspondenceEmail ||
|
||||||
|
"noreply@localhost",
|
||||||
to: email,
|
to: email,
|
||||||
subject,
|
subject,
|
||||||
html,
|
html,
|
||||||
|
@ -27,9 +27,12 @@ export default async function () {
|
|||||||
if (!host || !port || secure === null || !username || !password)
|
if (!host || !port || secure === null || !username || !password)
|
||||||
return console.error("[Email] SMTP has not been configured correctly.");
|
return console.error("[Email] SMTP has not been configured correctly.");
|
||||||
|
|
||||||
if (!Config.get().general.correspondenceEmail)
|
if (
|
||||||
|
!Config.get().email.senderAddress &&
|
||||||
|
!Config.get().general.correspondenceEmail
|
||||||
|
)
|
||||||
return console.error(
|
return console.error(
|
||||||
"[Email] Correspondence email has not been configured! This is used as the sender email address.",
|
'[Email] You have to configure either "email_senderAddress" or "general_correspondenceEmail" for emails to work. The configured value is used as the sender address.',
|
||||||
);
|
);
|
||||||
|
|
||||||
// construct the transporter
|
// construct the transporter
|
||||||
|