CORS fixup
This commit is contained in:
parent
49aacc71ef
commit
36409b3dca
|
@ -18,4 +18,4 @@ paste = "1.0.11"
|
||||||
totp-rs = { version = "4.2.0", features = ["qr", "otpauth", "gen_secret"]}
|
totp-rs = { version = "4.2.0", features = ["qr", "otpauth", "gen_secret"]}
|
||||||
uuid = { version = "1.3.0", features = ["v4", "fast-rng", "macro-diagnostics"]}
|
uuid = { version = "1.3.0", features = ["v4", "fast-rng", "macro-diagnostics"]}
|
||||||
url = { version = "2.3.1", features = ["serde"] }
|
url = { version = "2.3.1", features = ["serde"] }
|
||||||
urlencoding = "2.1.2"
|
urlencoding = "2.1.2"
|
||||||
|
|
|
@ -5,7 +5,9 @@ use std::fs;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use dotenvy::dotenv;
|
use dotenvy::dotenv;
|
||||||
use log::{error, info};
|
use log::{error, info};
|
||||||
use rocket::{catchers, routes};
|
use rocket::{catchers, Request, Response, routes};
|
||||||
|
use rocket::fairing::{Fairing, Info, Kind};
|
||||||
|
use rocket::http::Header;
|
||||||
use sqlx::migrate::Migrator;
|
use sqlx::migrate::Migrator;
|
||||||
use sqlx::postgres::PgPoolOptions;
|
use sqlx::postgres::PgPoolOptions;
|
||||||
use crate::config::TFConfig;
|
use crate::config::TFConfig;
|
||||||
|
@ -20,6 +22,25 @@ pub mod auth;
|
||||||
|
|
||||||
static MIGRATOR: Migrator = sqlx::migrate!();
|
static MIGRATOR: Migrator = sqlx::migrate!();
|
||||||
|
|
||||||
|
pub struct CORS;
|
||||||
|
|
||||||
|
#[rocket::async_trait]
|
||||||
|
impl Fairing for CORS {
|
||||||
|
fn info(&self) -> Info {
|
||||||
|
Info {
|
||||||
|
name: "Add CORS headers to responses",
|
||||||
|
kind: Kind::Response
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn on_response<'r>(&self, _request: &'r Request<'_>, response: &mut Response<'r>) {
|
||||||
|
response.set_header(Header::new("Access-Control-Allow-Origin", "*"));
|
||||||
|
response.set_header(Header::new("Access-Control-Allow-Methods", "POST, GET, PATCH, OPTIONS"));
|
||||||
|
response.set_header(Header::new("Access-Control-Allow-Headers", "*"));
|
||||||
|
response.set_header(Header::new("Access-Control-Allow-Credentials", "true"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[rocket::main]
|
#[rocket::main]
|
||||||
async fn main() -> Result<(), Box<dyn Error>> {
|
async fn main() -> Result<(), Box<dyn Error>> {
|
||||||
let _ = rocket::build();
|
let _ = rocket::build();
|
||||||
|
@ -81,11 +102,17 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
||||||
let _ = rocket::custom(figment)
|
let _ = rocket::custom(figment)
|
||||||
.mount("/", routes![
|
.mount("/", routes![
|
||||||
crate::routes::v1::auth::magic_link::magiclink_request,
|
crate::routes::v1::auth::magic_link::magiclink_request,
|
||||||
|
crate::routes::v1::auth::magic_link::options,
|
||||||
crate::routes::v1::signup::signup_request,
|
crate::routes::v1::signup::signup_request,
|
||||||
|
crate::routes::v1::signup::options,
|
||||||
crate::routes::v1::auth::verify_magic_link::verify_magic_link,
|
crate::routes::v1::auth::verify_magic_link::verify_magic_link,
|
||||||
|
crate::routes::v1::auth::verify_magic_link::options,
|
||||||
crate::routes::v1::totp_authenticators::totp_authenticators_request,
|
crate::routes::v1::totp_authenticators::totp_authenticators_request,
|
||||||
|
crate::routes::v1::totp_authenticators::options,
|
||||||
crate::routes::v1::verify_totp_authenticator::verify_totp_authenticator_request,
|
crate::routes::v1::verify_totp_authenticator::verify_totp_authenticator_request,
|
||||||
crate::routes::v1::auth::totp::totp_request
|
crate::routes::v1::verify_totp_authenticator::options,
|
||||||
|
crate::routes::v1::auth::totp::totp_request,
|
||||||
|
crate::routes::v1::auth::totp::options
|
||||||
])
|
])
|
||||||
.register("/", catchers![
|
.register("/", catchers![
|
||||||
crate::routes::handler_400,
|
crate::routes::handler_400,
|
||||||
|
@ -101,6 +128,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
||||||
crate::routes::handler_504,
|
crate::routes::handler_504,
|
||||||
crate::routes::handler_505,
|
crate::routes::handler_505,
|
||||||
])
|
])
|
||||||
|
.attach(CORS)
|
||||||
.manage(pool)
|
.manage(pool)
|
||||||
.manage(config)
|
.manage(config)
|
||||||
.launch().await?;
|
.launch().await?;
|
||||||
|
|
|
@ -5,6 +5,7 @@ use rocket::http::{ContentType, Status};
|
||||||
use sqlx::PgPool;
|
use sqlx::PgPool;
|
||||||
use crate::config::TFConfig;
|
use crate::config::TFConfig;
|
||||||
use crate::tokens::send_magic_link;
|
use crate::tokens::send_magic_link;
|
||||||
|
use rocket::options;
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(crate = "rocket::serde")]
|
#[serde(crate = "rocket::serde")]
|
||||||
|
@ -23,6 +24,12 @@ pub struct MagicLinkResponse {
|
||||||
pub metadata: MagicLinkResponseMetadata,
|
pub metadata: MagicLinkResponseMetadata,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[options("/v1/auth/magic-link")]
|
||||||
|
pub async fn options() -> &'static str {
|
||||||
|
""
|
||||||
|
}
|
||||||
|
|
||||||
#[post("/v1/auth/magic-link", data = "<req>")]
|
#[post("/v1/auth/magic-link", data = "<req>")]
|
||||||
pub async fn magiclink_request(req: Json<MagicLinkRequest>, pool: &State<PgPool>, config: &State<TFConfig>) -> Result<(ContentType, Json<MagicLinkResponse>), (Status, String)> {
|
pub async fn magiclink_request(req: Json<MagicLinkRequest>, pool: &State<PgPool>, config: &State<TFConfig>) -> Result<(ContentType, Json<MagicLinkResponse>), (Status, String)> {
|
||||||
// figure out if the user already exists
|
// figure out if the user already exists
|
||||||
|
|
|
@ -4,6 +4,7 @@ use crate::auth::PartialUserInfo;
|
||||||
use serde::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
use rocket::{post, State};
|
use rocket::{post, State};
|
||||||
use sqlx::PgPool;
|
use sqlx::PgPool;
|
||||||
|
use rocket::options;
|
||||||
use crate::tokens::{generate_auth_token, get_totpmachine, user_has_totp};
|
use crate::tokens::{generate_auth_token, get_totpmachine, user_has_totp};
|
||||||
|
|
||||||
pub const TOTP_GENERIC_UNAUTHORIZED_ERROR: &str = "{\"errors\":[{\"code\":\"ERR_INVALID_TOTP_CODE\",\"message\":\"invalid TOTP code (maybe it expired?)\",\"path\":\"code\"}]}";
|
pub const TOTP_GENERIC_UNAUTHORIZED_ERROR: &str = "{\"errors\":[{\"code\":\"ERR_INVALID_TOTP_CODE\",\"message\":\"invalid TOTP code (maybe it expired?)\",\"path\":\"code\"}]}";
|
||||||
|
@ -32,6 +33,12 @@ pub struct TotpResponse {
|
||||||
metadata: TotpResponseMetadata
|
metadata: TotpResponseMetadata
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[options("/v1/auth/totp")]
|
||||||
|
pub async fn options() -> &'static str {
|
||||||
|
""
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#[post("/v1/auth/totp", data = "<req>")]
|
#[post("/v1/auth/totp", data = "<req>")]
|
||||||
pub async fn totp_request(req: Json<TotpRequest>, user: PartialUserInfo, db: &State<PgPool>) -> Result<(ContentType, Json<TotpResponse>), (Status, String)> {
|
pub async fn totp_request(req: Json<TotpRequest>, user: PartialUserInfo, db: &State<PgPool>) -> Result<(ContentType, Json<TotpResponse>), (Status, String)> {
|
||||||
if !match user_has_totp(user.user_id, db.inner()).await {
|
if !match user_has_totp(user.user_id, db.inner()).await {
|
||||||
|
|
|
@ -6,6 +6,7 @@ use rocket::{post, State};
|
||||||
use sqlx::PgPool;
|
use sqlx::PgPool;
|
||||||
use crate::config::TFConfig;
|
use crate::config::TFConfig;
|
||||||
use crate::tokens::generate_session_token;
|
use crate::tokens::generate_session_token;
|
||||||
|
use rocket::options;
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(crate = "rocket::serde")]
|
#[serde(crate = "rocket::serde")]
|
||||||
|
@ -30,6 +31,12 @@ pub struct VerifyMagicLinkResponse {
|
||||||
pub metadata: VerifyMagicLinkResponseMetadata,
|
pub metadata: VerifyMagicLinkResponseMetadata,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[options("/v1/auth/verify-magic-link")]
|
||||||
|
pub async fn options() -> &'static str {
|
||||||
|
""
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#[post("/v1/auth/verify-magic-link", data = "<req>")]
|
#[post("/v1/auth/verify-magic-link", data = "<req>")]
|
||||||
pub async fn verify_magic_link(req: Json<VerifyMagicLinkRequest>, db: &State<PgPool>, config: &State<TFConfig>) -> Result<(ContentType, Json<VerifyMagicLinkResponse>), (Status, String)> {
|
pub async fn verify_magic_link(req: Json<VerifyMagicLinkRequest>, db: &State<PgPool>, config: &State<TFConfig>) -> Result<(ContentType, Json<VerifyMagicLinkResponse>), (Status, String)> {
|
||||||
// get the current time to check if the token is expired
|
// get the current time to check if the token is expired
|
||||||
|
|
|
@ -6,6 +6,7 @@ use rocket::http::{ContentType, Status};
|
||||||
use sqlx::PgPool;
|
use sqlx::PgPool;
|
||||||
use crate::config::TFConfig;
|
use crate::config::TFConfig;
|
||||||
use crate::tokens::send_magic_link;
|
use crate::tokens::send_magic_link;
|
||||||
|
use rocket::options;
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(crate = "rocket::serde")]
|
#[serde(crate = "rocket::serde")]
|
||||||
|
@ -29,6 +30,11 @@ created_on TIMESTAMP NOT NULL,
|
||||||
banned INTEGER NOT NULL,
|
banned INTEGER NOT NULL,
|
||||||
ban_reason VARCHAR(1024) NOT NULL
|
ban_reason VARCHAR(1024) NOT NULL
|
||||||
*/
|
*/
|
||||||
|
#[options("/v1/signup")]
|
||||||
|
pub async fn options() -> &'static str {
|
||||||
|
""
|
||||||
|
}
|
||||||
|
|
||||||
#[post("/v1/signup", data = "<req>")]
|
#[post("/v1/signup", data = "<req>")]
|
||||||
pub async fn signup_request(req: Json<SignupRequest>, pool: &State<PgPool>, config: &State<TFConfig>) -> Result<(ContentType, Json<SignupResponse>), (Status, String)> {
|
pub async fn signup_request(req: Json<SignupRequest>, pool: &State<PgPool>, config: &State<TFConfig>) -> Result<(ContentType, Json<SignupResponse>), (Status, String)> {
|
||||||
// figure out if the user already exists
|
// figure out if the user already exists
|
||||||
|
|
|
@ -6,6 +6,7 @@ use serde::{Serialize, Deserialize};
|
||||||
use crate::auth::PartialUserInfo;
|
use crate::auth::PartialUserInfo;
|
||||||
use crate::config::TFConfig;
|
use crate::config::TFConfig;
|
||||||
use crate::tokens::{create_totp_token, user_has_totp};
|
use crate::tokens::{create_totp_token, user_has_totp};
|
||||||
|
use rocket::options;
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
pub struct TotpAuthenticatorsRequest {}
|
pub struct TotpAuthenticatorsRequest {}
|
||||||
|
@ -27,6 +28,12 @@ pub struct TotpAuthenticatorsResponse {
|
||||||
pub metadata: TotpAuthenticatorsResponseMetadata,
|
pub metadata: TotpAuthenticatorsResponseMetadata,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[options("/v1/totp-authenticators")]
|
||||||
|
pub async fn options() -> &'static str {
|
||||||
|
""
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#[post("/v1/totp-authenticators", data = "<_req>")]
|
#[post("/v1/totp-authenticators", data = "<_req>")]
|
||||||
pub async fn totp_authenticators_request(_req: Json<TotpAuthenticatorsRequest>, user: PartialUserInfo, db: &State<PgPool>, config: &State<TFConfig>) -> Result<(ContentType, Json<TotpAuthenticatorsResponse>), (Status, String)> {
|
pub async fn totp_authenticators_request(_req: Json<TotpAuthenticatorsRequest>, user: PartialUserInfo, db: &State<PgPool>, config: &State<TFConfig>) -> Result<(ContentType, Json<TotpAuthenticatorsResponse>), (Status, String)> {
|
||||||
if match user_has_totp(user.user_id, db.inner()).await {
|
if match user_has_totp(user.user_id, db.inner()).await {
|
||||||
|
|
|
@ -15,6 +15,7 @@ use rocket::State;
|
||||||
use serde::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
use sqlx::PgPool;
|
use sqlx::PgPool;
|
||||||
use crate::tokens::{generate_auth_token, use_totp_token, verify_totp_token};
|
use crate::tokens::{generate_auth_token, use_totp_token, verify_totp_token};
|
||||||
|
use rocket::options;
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
pub struct VerifyTotpAuthenticatorRequest {
|
pub struct VerifyTotpAuthenticatorRequest {
|
||||||
|
@ -38,6 +39,12 @@ pub struct VerifyTotpAuthenticatorResponse {
|
||||||
pub metadata: VerifyTotpAuthenticatorResponseMetadata,
|
pub metadata: VerifyTotpAuthenticatorResponseMetadata,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[options("/v1/auth/verify-totp-authenticator")]
|
||||||
|
pub async fn options() -> &'static str {
|
||||||
|
""
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#[post("/v1/verify-totp-authenticator", data = "<req>")]
|
#[post("/v1/verify-totp-authenticator", data = "<req>")]
|
||||||
pub async fn verify_totp_authenticator_request(req: Json<VerifyTotpAuthenticatorRequest>, db: &State<PgPool>, user: PartialUserInfo) -> Result<(ContentType, Json<VerifyTotpAuthenticatorResponse>), (Status, String)> {
|
pub async fn verify_totp_authenticator_request(req: Json<VerifyTotpAuthenticatorRequest>, db: &State<PgPool>, user: PartialUserInfo) -> Result<(ContentType, Json<VerifyTotpAuthenticatorResponse>), (Status, String)> {
|
||||||
let totpmachine = match verify_totp_token(req.0.totp_token.clone(), user.email.clone(), db.inner()).await {
|
let totpmachine = match verify_totp_token(req.0.totp_token.clone(), user.email.clone(), db.inner()).await {
|
||||||
|
|
Loading…
Reference in New Issue