Compare commits

..

3 Commits

Author SHA1 Message Date
jude
d2d9b8d6d0 Store guild when creating reminders 2023-08-19 21:21:56 +01:00
jude
a050b13127 Correct migration script.
Stub code for routes. Update existing routes to set the reminder's guild
ID.
2023-08-19 19:24:06 +01:00
7e627fee9e In progress 2023-08-12 12:27:15 +01:00
14 changed files with 65 additions and 145 deletions

2
Cargo.lock generated
View File

@ -2217,7 +2217,7 @@ checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78"
[[package]] [[package]]
name = "reminder-rs" name = "reminder-rs"
version = "1.6.38" version = "1.6.36"
dependencies = [ dependencies = [
"base64 0.21.2", "base64 0.21.2",
"chrono", "chrono",

View File

@ -1,6 +1,6 @@
[package] [package]
name = "reminder-rs" name = "reminder-rs"
version = "1.6.38" version = "1.6.36"
authors = ["Jude Southworth <judesouthworth@pm.me>"] authors = ["Jude Southworth <judesouthworth@pm.me>"]
edition = "2021" edition = "2021"
license = "AGPL-3.0 only" license = "AGPL-3.0 only"

View File

@ -169,7 +169,7 @@ impl ComponentDataModel {
let selected_id = component.data.values.join(","); let selected_id = component.data.values.join(",");
sqlx::query!( sqlx::query!(
"UPDATE reminders SET `status` = 'deleted' WHERE FIND_IN_SET(id, ?)", "UPDATE reminders SET `status` = 'pending' WHERE FIND_IN_SET(id, ?)",
selected_id selected_id
) )
.execute(&data.database) .execute(&data.database)

View File

@ -72,14 +72,10 @@ pub async fn initialize(
db_pool: Pool<Database>, db_pool: Pool<Database>,
) -> Result<(), Box<dyn std::error::Error>> { ) -> Result<(), Box<dyn std::error::Error>> {
info!("Checking environment variables..."); info!("Checking environment variables...");
env::var("OAUTH2_CLIENT_ID").expect("`OAUTH2_CLIENT_ID' not supplied");
if env::var("OFFLINE").map_or(true, |v| v != "1") { env::var("OAUTH2_CLIENT_SECRET").expect("`OAUTH2_CLIENT_SECRET' not supplied");
env::var("OAUTH2_CLIENT_ID").expect("`OAUTH2_CLIENT_ID' not supplied"); env::var("OAUTH2_DISCORD_CALLBACK").expect("`OAUTH2_DISCORD_CALLBACK' not supplied");
env::var("OAUTH2_CLIENT_SECRET").expect("`OAUTH2_CLIENT_SECRET' not supplied"); env::var("PATREON_GUILD_ID").expect("`PATREON_GUILD_ID' not supplied");
env::var("OAUTH2_DISCORD_CALLBACK").expect("`OAUTH2_DISCORD_CALLBACK' not supplied");
env::var("PATREON_GUILD_ID").expect("`PATREON_GUILD_ID' not supplied");
}
info!("Done!"); info!("Done!");
let oauth2_client = BasicClient::new( let oauth2_client = BasicClient::new(
@ -190,8 +186,6 @@ pub async fn initialize(
} }
pub async fn check_subscription(cache_http: impl CacheHttp, user_id: impl Into<UserId>) -> bool { pub async fn check_subscription(cache_http: impl CacheHttp, user_id: impl Into<UserId>) -> bool {
offline!(true);
if let Some(subscription_guild) = *CNC_GUILD { if let Some(subscription_guild) = *CNC_GUILD {
let guild_member = GuildId(subscription_guild).member(cache_http, user_id).await; let guild_member = GuildId(subscription_guild).member(cache_http, user_id).await;
@ -213,8 +207,6 @@ pub async fn check_guild_subscription(
cache_http: impl CacheHttp, cache_http: impl CacheHttp,
guild_id: impl Into<GuildId>, guild_id: impl Into<GuildId>,
) -> bool { ) -> bool {
offline!(true);
if let Some(guild) = cache_http.cache().unwrap().guild(guild_id) { if let Some(guild) = cache_http.cache().unwrap().guild(guild_id) {
let owner = guild.owner_id; let owner = guild.owner_id;

View File

@ -1,11 +1,3 @@
macro_rules! offline {
($field:expr) => {
if std::env::var("OFFLINE").map_or(false, |v| v == "1") {
return $field;
}
};
}
macro_rules! check_length { macro_rules! check_length {
($max:ident, $field:expr) => { ($max:ident, $field:expr) => {
if $field.len() > $max { if $field.len() > $max {
@ -60,45 +52,43 @@ macro_rules! check_authorization {
let user_id = $cookies.get_private("userid").map(|c| c.value().parse::<u64>().ok()).flatten(); let user_id = $cookies.get_private("userid").map(|c| c.value().parse::<u64>().ok()).flatten();
if std::env::var("OFFLINE").map_or(true, |v| v != "1") { match user_id {
match user_id { Some(user_id) => {
Some(user_id) => { match GuildId($guild).to_guild_cached($ctx) {
match GuildId($guild).to_guild_cached($ctx) { Some(guild) => {
Some(guild) => { let member_res = guild.member($ctx, UserId(user_id)).await;
let member_res = guild.member($ctx, UserId(user_id)).await;
match member_res { match member_res {
Err(_) => { Err(_) => {
return Err(json!({"error": "User not in guild"})); return Err(json!({"error": "User not in guild"}));
} }
Ok(member) => { Ok(member) => {
let permissions_res = member.permissions($ctx); let permissions_res = member.permissions($ctx);
match permissions_res { match permissions_res {
Err(_) => { Err(_) => {
return Err(json!({"error": "Couldn't fetch permissions"})); return Err(json!({"error": "Couldn't fetch permissions"}));
} }
Ok(permissions) => { Ok(permissions) => {
if !(permissions.manage_messages() || permissions.manage_guild() || permissions.administrator()) { if !(permissions.manage_messages() || permissions.manage_guild() || permissions.administrator()) {
return Err(json!({"error": "Incorrect permissions"})); return Err(json!({"error": "Incorrect permissions"}));
}
} }
} }
} }
} }
} }
}
None => { None => {
return Err(json!({"error": "Bot not in guild"})); return Err(json!({"error": "Bot not in guild"}));
}
} }
} }
}
None => { None => {
return Err(json!({"error": "User not authorized"})); return Err(json!({"error": "User not authorized"}));
}
} }
} }
} }

View File

@ -46,7 +46,6 @@ pub async fn get_guild_patreon(
cookies: &CookieJar<'_>, cookies: &CookieJar<'_>,
ctx: &State<Context>, ctx: &State<Context>,
) -> JsonResult { ) -> JsonResult {
offline!(Ok(json!({ "patreon": true })));
check_authorization!(cookies, ctx.inner(), id); check_authorization!(cookies, ctx.inner(), id);
match GuildId(id).to_guild_cached(ctx.inner()) { match GuildId(id).to_guild_cached(ctx.inner()) {
@ -74,12 +73,6 @@ pub async fn get_guild_channels(
cookies: &CookieJar<'_>, cookies: &CookieJar<'_>,
ctx: &State<Context>, ctx: &State<Context>,
) -> JsonResult { ) -> JsonResult {
offline!(Ok(json!(vec![ChannelInfo {
name: "general".to_string(),
id: "1".to_string(),
webhook_avatar: None,
webhook_name: None,
}])));
check_authorization!(cookies, ctx.inner(), id); check_authorization!(cookies, ctx.inner(), id);
match GuildId(id).to_guild_cached(ctx.inner()) { match GuildId(id).to_guild_cached(ctx.inner()) {
@ -118,7 +111,6 @@ struct RoleInfo {
#[get("/api/guild/<id>/roles")] #[get("/api/guild/<id>/roles")]
pub async fn get_guild_roles(id: u64, cookies: &CookieJar<'_>, ctx: &State<Context>) -> JsonResult { pub async fn get_guild_roles(id: u64, cookies: &CookieJar<'_>, ctx: &State<Context>) -> JsonResult {
offline!(Ok(json!(vec![RoleInfo { name: "@everyone".to_string(), id: "1".to_string() }])));
check_authorization!(cookies, ctx.inner(), id); check_authorization!(cookies, ctx.inner(), id);
let roles_res = ctx.cache.guild_roles(id); let roles_res = ctx.cache.guild_roles(id);

View File

@ -54,8 +54,6 @@ pub async fn get_user_info(
ctx: &State<Context>, ctx: &State<Context>,
pool: &State<Pool<MySql>>, pool: &State<Pool<MySql>>,
) -> JsonValue { ) -> JsonValue {
offline!(json!(UserInfo { name: "Discord".to_string(), patreon: true, timezone: None }));
if let Some(user_id) = if let Some(user_id) =
cookies.get_private("userid").map(|u| u.value().parse::<u64>().ok()).flatten() cookies.get_private("userid").map(|u| u.value().parse::<u64>().ok()).flatten()
{ {
@ -118,8 +116,6 @@ pub async fn update_user_info(
#[get("/api/user/guilds")] #[get("/api/user/guilds")]
pub async fn get_user_guilds(cookies: &CookieJar<'_>, reqwest_client: &State<Client>) -> JsonValue { pub async fn get_user_guilds(cookies: &CookieJar<'_>, reqwest_client: &State<Client>) -> JsonValue {
offline!(json!(vec![GuildInfo { id: "1".to_string(), name: "Guild".to_string() }]));
if let Some(access_token) = cookies.get_private("access_token") { if let Some(access_token) = cookies.get_private("access_token") {
let request_res = reqwest_client let request_res = reqwest_client
.get(format!("{}/users/@me/guilds", DISCORD_API)) .get(format!("{}/users/@me/guilds", DISCORD_API))

View File

@ -249,11 +249,11 @@ div#pageNavbar a {
.navbar-item.pageTitle { .navbar-item.pageTitle {
flex-shrink: 1; flex-shrink: 1;
white-space: nowrap; text-wrap: nowrap;
overflow: hidden; overflow: hidden;
} }
.dashboard-burger, .dashboard-burger:active, .dashboard-burger.is-active { .navbar-burger, .navbar-burger:active, .navbar-burger.is-active {
background-color: #adc99c !important; background-color: #adc99c !important;
border-radius: 14px; border-radius: 14px;
padding: 6px; padding: 6px;
@ -644,11 +644,9 @@ li.highlight {
} }
p.title.pageTitle { p.title.pageTitle {
display: none; visibility: hidden;
} text-wrap: nowrap;
overflow: hidden;
.dashboard-frame {
margin-top: 4rem !important;
} }
} }
@ -667,7 +665,6 @@ li.highlight {
/* loader */ /* loader */
#loader { #loader {
position: fixed; position: fixed;
top: 0;
background-color: rgba(255, 255, 255, 0.8); background-color: rgba(255, 255, 255, 0.8);
width: 100vw; width: 100vw;
z-index: 999; z-index: 999;
@ -722,20 +719,9 @@ a.switch-pane {
.is-locked { .is-locked {
pointer-events: none; pointer-events: none;
}
.is-locked > :not(.patreon-invert) {
opacity: 0.4; opacity: 0.4;
} }
.is-locked .patreon-invert {
display: block;
}
.patreon-invert {
display: none;
}
.is-locked .foreground { .is-locked .foreground {
pointer-events: auto; pointer-events: auto;
} }
@ -765,5 +751,5 @@ a.switch-pane {
} }
.figure-num { .figure-num {
font-size: 2rem; font-size: 2em;
} }

View File

@ -1,19 +0,0 @@
let _reminderErrors = [];
const reminderErrors = () => {
return _reminderErrors;
}
const guildId = () => {
let selected: HTMLElement = document.querySelector(".guildList a.is-active");
return selected.dataset["guild"];
}
function loadErrors() {
fetch(`/dashboard/api/guild/${guildId()}/errors`).then(response => response.json())
}
document.addEventListener('DOMContentLoaded', () => {
})

View File

@ -47,7 +47,7 @@
<p class="navbar-item pageTitle"> <p class="navbar-item pageTitle">
</p> </p>
<a role="button" class="dashboard-burger navbar-burger is-right" aria-label="menu" aria-expanded="false" <a role="button" class="navbar-burger is-right" aria-label="menu" aria-expanded="false"
data-target="mobileSidebar"> data-target="mobileSidebar">
<span aria-hidden="true"></span> <span aria-hidden="true"></span>
<span aria-hidden="true"></span> <span aria-hidden="true"></span>
@ -335,14 +335,34 @@
<section id="guild" class="is-hidden"> <section id="guild" class="is-hidden">
{% include "reminder_dashboard/reminder_dashboard" %} {% include "reminder_dashboard/reminder_dashboard" %}
</section> </section>
<section id="reminder-errors" class="is-hidden"> <section id="guild-error" class="is-hidden hero is-fullheight">
{% include "reminder_dashboard/reminder_errors" %} <div class="hero-body">
<div class="container has-text-centered">
<p class="title">
We couldn't get this server's data
</p>
<p class="subtitle">
Please check Reminder Bot is in the server, and has correct permissions.
</p>
<a class="button is-size-4 is-rounded is-success" href="https://invite.reminder-bot.com">
<p class="is-size-4">
<span>Add to Server</span> <span class="icon"><i class="fas fa-chevron-right"></i></span>
</p>
</a>
</div>
</div>
</section> </section>
<section id="guild-error" class="is-hidden"> <section id="user-error" class="is-hidden hero is-fullheight">
{% include "reminder_dashboard/guild_error" %} <div class="hero-body">
</section> <div class="container has-text-centered">
<section id="user-error" class="is-hidden"> <p class="title">
{% include "reminder_dashboard/user_error" %} You do not have permissions for this server
</p>
<p class="subtitle">
Ask an admin to grant you the "Manage Messages" permission.
</p>
</div>
</div>
</section> </section>
</div> </div>
<!-- /main content --> <!-- /main content -->

View File

@ -1,17 +0,0 @@
<div class="hero is-fullheight">
<div class="hero-body">
<div class="container has-text-centered">
<p class="title">
We couldn't get this server's data
</p>
<p class="subtitle">
Please check Reminder Bot is in the server, and has correct permissions.
</p>
<a class="button is-size-4 is-rounded is-success" href="https://invite.reminder-bot.com">
<p class="is-size-4">
<span>Add to Server</span> <span class="icon"><i class="fas fa-chevron-right"></i></span>
</p>
</a>
</div>
</div>
</div>

View File

@ -165,9 +165,6 @@
<div class="collapses split-controls"> <div class="collapses split-controls">
<div> <div>
<div class="patreon-only"> <div class="patreon-only">
<div class="patreon-invert foreground">
Intervals available on <a href="https://patreon.com/jellywx">Patreon</a> or <a href="https://gitea.jellypro.xyz/jude/reminder-bot">self-hosting</a>
</div>
<div class="field"> <div class="field">
<label class="label">Interval <a class="foreground" href="/help/intervals"><i class="fas fa-question-circle"></i></a></label> <label class="label">Interval <a class="foreground" href="/help/intervals"><i class="fas fa-question-circle"></i></a></label>
<div class="control intervalSelector"> <div class="control intervalSelector">

View File

@ -1,5 +0,0 @@
<div>
</div>
<script src="/static/js/reminder_errors.js"></script>

View File

@ -1,12 +0,0 @@
<div class="hero is-fullheight">
<div class="hero-body">
<div class="container has-text-centered">
<p class="title">
You do not have permissions for this server
</p>
<p class="subtitle">
Ask an admin to grant you the "Manage Messages" permission.
</p>
</div>
</div>
</div>