mirror of
https://forgejo.ellis.link/continuwuation/continuwuity.git
synced 2026-05-26 20:49:55 +00:00
feat: Add a webpage for threepid validation links
This commit is contained in:
@@ -122,7 +122,7 @@ impl Service {
|
||||
/// if they were not.
|
||||
pub async fn empower_first_user(&self, user: &UserId) -> Result<bool> {
|
||||
#[derive(Template)]
|
||||
#[template(path = "welcome.md.j2")]
|
||||
#[template(path = "welcome.md")]
|
||||
struct WelcomeMessage<'a> {
|
||||
config: &'a Dep<config::Service>,
|
||||
domain: &'a str,
|
||||
|
||||
@@ -6,7 +6,7 @@ pub trait MessageTemplate: Template {
|
||||
}
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "mail/change_email.txt.j2")]
|
||||
#[template(path = "mail/change_email.txt")]
|
||||
pub struct ChangeEmail<'a> {
|
||||
pub user_id: &'a UserId,
|
||||
pub verification_link: String,
|
||||
@@ -17,7 +17,7 @@ impl MessageTemplate for ChangeEmail<'_> {
|
||||
}
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "mail/new_account.txt.j2")]
|
||||
#[template(path = "mail/new_account.txt")]
|
||||
pub struct NewAccount<'a> {
|
||||
pub server_name: &'a str,
|
||||
pub verification_link: String,
|
||||
@@ -28,7 +28,7 @@ impl MessageTemplate for NewAccount<'_> {
|
||||
}
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "mail/password_reset.txt.j2")]
|
||||
#[template(path = "mail/password_reset.txt")]
|
||||
pub struct PasswordReset<'a> {
|
||||
pub display_name: Option<&'a str>,
|
||||
pub user_id: &'a UserId,
|
||||
@@ -40,7 +40,7 @@ impl MessageTemplate for PasswordReset<'_> {
|
||||
}
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "mail/test.txt.j2")]
|
||||
#[template(path = "mail/test.txt")]
|
||||
pub struct Test;
|
||||
|
||||
impl MessageTemplate for Test {
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
{% extends "_base.txt.j2" %}
|
||||
{% extends "_base.txt" %}
|
||||
|
||||
{% block content -%}
|
||||
Hello!
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
{% extends "_base.txt.j2" %}
|
||||
{% extends "_base.txt" %}
|
||||
|
||||
{% block content -%}
|
||||
Hello!
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
{% extends "_base.txt.j2" %}
|
||||
{% extends "_base.txt" %}
|
||||
|
||||
{% block content -%}
|
||||
{%- if let Some(display_name) = display_name -%}
|
||||
@@ -1,4 +1,4 @@
|
||||
{% extends "_base.txt.j2" %}
|
||||
{% extends "_base.txt" %}
|
||||
|
||||
{% block content -%}
|
||||
If you're seeing this, SMTP is configured correctly. :3
|
||||
@@ -90,6 +90,7 @@ pub fn build() -> Router<state::State> {
|
||||
.merge(resources::build())
|
||||
.merge(password_reset::build())
|
||||
.merge(debug::build())
|
||||
.merge(threepid::build())
|
||||
.fallback(async || WebError::NotFound),
|
||||
)
|
||||
.layer(CatchPanicLayer::custom(|panic: Box<dyn Any + Send + 'static>| {
|
||||
|
||||
@@ -1,17 +1,14 @@
|
||||
use askama::Template;
|
||||
use axum::{Router, extract::State, response::IntoResponse, routing::get};
|
||||
|
||||
use crate::{WebError, template};
|
||||
|
||||
pub(crate) fn build() -> Router<crate::State> {
|
||||
Router::new()
|
||||
.route("/", get(index_handler))
|
||||
.route("/_continuwuity/", get(index_handler))
|
||||
.route("/", get(index))
|
||||
.route("/_continuwuity/", get(index))
|
||||
}
|
||||
|
||||
async fn index_handler(
|
||||
State(services): State<crate::State>,
|
||||
) -> Result<impl IntoResponse, WebError> {
|
||||
async fn index(State(services): State<crate::State>) -> Result<impl IntoResponse, WebError> {
|
||||
template! {
|
||||
struct Index<'a> use "index.html.j2" {
|
||||
server_name: &'a str,
|
||||
|
||||
@@ -3,6 +3,7 @@ pub(super) mod debug;
|
||||
pub(super) mod index;
|
||||
pub(super) mod password_reset;
|
||||
pub(super) mod resources;
|
||||
pub(super) mod threepid;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct TemplateContext {
|
||||
@@ -43,6 +44,8 @@ macro_rules! template {
|
||||
#[allow(single_use_lifetimes)]
|
||||
impl$(<$lifetime>)? axum::response::IntoResponse for $name$(<$lifetime>)? {
|
||||
fn into_response(self) -> axum::response::Response {
|
||||
use askama::Template;
|
||||
|
||||
match self.render() {
|
||||
Ok(rendered) => axum::response::Html(rendered).into_response(),
|
||||
Err(err) => $crate::WebError::from(err).into_response()
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
use askama::Template;
|
||||
use axum::{
|
||||
Router,
|
||||
extract::{
|
||||
@@ -20,11 +19,6 @@ use crate::{
|
||||
|
||||
const INVALID_TOKEN_ERROR: &str = "Invalid reset token. Your reset link may have expired.";
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct PasswordResetQuery {
|
||||
token: String,
|
||||
}
|
||||
|
||||
template! {
|
||||
struct PasswordReset<'a> use "password_reset.html.j2" {
|
||||
user_card: UserCard<'a>,
|
||||
@@ -63,6 +57,11 @@ pub(crate) fn build() -> Router<crate::State> {
|
||||
.route("/account/reset_password", get(get_password_reset).post(post_password_reset))
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct PasswordResetQuery {
|
||||
token: String,
|
||||
}
|
||||
|
||||
async fn password_reset_form(
|
||||
services: crate::State,
|
||||
query: PasswordResetQuery,
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
{% extends "_layout.html.j2" %}
|
||||
|
||||
{%- block content -%}
|
||||
<div class="panel">
|
||||
<h1>Email verification</h1>
|
||||
<p>Your email address has been verified. Return to your Matrix client to continue.</p>
|
||||
</div>
|
||||
{%- endblock content -%}
|
||||
@@ -0,0 +1,39 @@
|
||||
use axum::{
|
||||
Router,
|
||||
extract::{Query, State, rejection::QueryRejection},
|
||||
response::IntoResponse,
|
||||
routing::get,
|
||||
};
|
||||
use ruma::OwnedSessionId;
|
||||
use serde::Deserialize;
|
||||
|
||||
use crate::{WebError, template};
|
||||
|
||||
template! {
|
||||
struct ThreepidValidation use "threepid_validation.html.j2" {}
|
||||
}
|
||||
|
||||
pub(crate) fn build() -> Router<crate::State> {
|
||||
Router::new().route("/3pid/email/validate", get(threepid_validation))
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct ThreepidValidationQuery {
|
||||
session: OwnedSessionId,
|
||||
token: String,
|
||||
}
|
||||
|
||||
async fn threepid_validation(
|
||||
State(services): State<crate::State>,
|
||||
query: Result<Query<ThreepidValidationQuery>, QueryRejection>,
|
||||
) -> Result<impl IntoResponse, WebError> {
|
||||
let Query(query) = query?;
|
||||
|
||||
services
|
||||
.threepid
|
||||
.try_validate_session(&query.session, &query.token)
|
||||
.await
|
||||
.map_err(|message| WebError::BadRequest(message.into_owned()))?;
|
||||
|
||||
Ok(ThreepidValidation::new(&services))
|
||||
}
|
||||
Reference in New Issue
Block a user