Skip to content

Commit

Permalink
feat: smtp wip
Browse files Browse the repository at this point in the history
  • Loading branch information
twlite committed Jul 18, 2024
1 parent 6948d7f commit 089dea3
Show file tree
Hide file tree
Showing 23 changed files with 655 additions and 73 deletions.
Binary file modified bun.lockb
Binary file not shown.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "next dev",
"dev": "next dev --turbo",
"build": "next build",
"start": "next start",
"lint": "next lint",
Expand Down Expand Up @@ -43,7 +43,7 @@
"detect-programming-language": "^1.0.4",
"lucide-react": "^0.378.0",
"mime-types": "^2.1.35",
"next": "^14.2.4",
"next": "^14.2.5",
"next-themes": "^0.3.0",
"prettier": "^3.2.5",
"react": "^18.2.0",
Expand Down
73 changes: 73 additions & 0 deletions src-tauri/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,5 @@ tauri-plugin-websocket = "2.0.0-beta.9"
tauri-plugin-fs = "2.0.0-beta.11"
tauri-plugin-store = "2.0.0-beta.10"
local-ip-address = "0.6.1"
mailin-embedded = "0.8.2"
tokio = "1.38.1"
4 changes: 4 additions & 0 deletions src-tauri/capabilities/main.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@
"window:allow-unminimize",
"window:allow-start-dragging",
"window:allow-start-resize-dragging",
"event:allow-listen",
"event:allow-emit",
"event:allow-unlisten",
"event:default",
{
"identifier": "http:default",
"allow": [
Expand Down
1 change: 1 addition & 0 deletions src-tauri/src/commands/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
pub mod network;
pub mod smtp;
145 changes: 145 additions & 0 deletions src-tauri/src/commands/smtp.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
use mailin_embedded::{response, Handler, Response, Server};
use std::collections::VecDeque;
use std::io::Error;
use std::sync::{Arc, RwLock};
use tauri::{Emitter, State};
use tokio::task::JoinHandle;

#[derive(Clone)]
pub struct SmtpHandler {
messages: Arc<RwLock<VecDeque<String>>>,
window: Option<tauri::Window>,
current_data: Arc<RwLock<String>>,
}

impl SmtpHandler {
fn new(window: Option<tauri::Window>) -> Self {
SmtpHandler {
messages: Arc::new(RwLock::new(VecDeque::new())),
window,
current_data: Arc::new(RwLock::new(String::new())),
}
}

fn get_messages(&self) -> Vec<String> {
self.messages.read().unwrap().clone().into()
}

fn set_window(&mut self, window: tauri::Window) {
self.window = Some(window);
}

fn emit_new_email(&self) {
if let Some(window) = &self.window {
window.emit("new-email", ()).expect("Failed to emit event");
}
}
}

impl Handler for SmtpHandler {
fn auth_login(&mut self, _username: &str, _password: &str) -> mailin_embedded::Response {
response::AUTH_OK
}

fn auth_plain(
&mut self,
_authorization_id: &str,
_authentication_id: &str,
_password: &str,
) -> Response {
response::AUTH_OK
}

fn data_start(
&mut self,
_domain: &str,
_from: &str,
_is8bit: bool,
_to: &[String],
) -> Response {
let mut current_data = self.current_data.write().unwrap();
*current_data = String::new();
response::OK
}

fn data(&mut self, buf: &[u8]) -> Result<(), Error> {
let data_str = String::from_utf8_lossy(buf).to_string();
let mut current_data = self.current_data.write().unwrap();
current_data.push_str(&data_str);
Ok(())
}

// TODO: parse properly
fn data_end(&mut self) -> Response {
let accumulated_str = self.current_data.read().unwrap().clone();
self.messages.write().unwrap().push_back(accumulated_str);
self.emit_new_email();

response::OK
}
}

pub struct ServerState {
handle: RwLock<Option<JoinHandle<()>>>,
handler: RwLock<SmtpHandler>,
}

impl ServerState {
pub fn new() -> Self {
ServerState {
handle: RwLock::new(None),
handler: RwLock::new(SmtpHandler::new(None)),
}
}

pub fn set_window(&self, window: tauri::Window) {
let mut handler = self.handler.write().unwrap();
handler.set_window(window);
}

pub fn get_handler(&self) -> SmtpHandler {
self.handler.read().unwrap().clone()
}
}

#[tauri::command]
pub async fn start_smtp_server(state: State<'_, ServerState>, port: u32) -> Result<(), String> {
let mut handle_guard = state.handle.write().unwrap();

if handle_guard.is_some() {
return Err("Server is already running".into());
}

let handler = state.get_handler();
let addr = format!("127.0.0.1:{}", port);

let handle = tokio::spawn(async move {
let mut server = Server::new(handler);
server.with_addr(addr).expect("Failed to set address");
server.serve().expect("Failed to start server");
});

*handle_guard = Some(handle);
Ok(())
}

#[tauri::command]
pub async fn stop_smtp_server(
window: tauri::Window,
state: State<'_, ServerState>,
) -> Result<(), String> {
state.set_window(window);
let mut handle_guard = state.handle.write().unwrap();

if let Some(handle) = handle_guard.take() {
handle.abort();
return Ok(());
}

Err("Server is not running".into())
}

#[tauri::command]
pub fn get_emails(state: State<'_, ServerState>) -> Vec<String> {
state.get_handler().get_messages()
}
5 changes: 4 additions & 1 deletion src-tauri/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,20 @@ pub fn run() {
.plugin(tauri_plugin_store::Builder::new().build())
.plugin(tauri_plugin_websocket::init())
.plugin(tauri_plugin_http::init())
.manage(commands::smtp::ServerState::new())
.setup(|app| {
let main_window = app.get_webview_window("main").unwrap();

main_window.hide_menu().unwrap();

main_window.maximize().unwrap();

Ok(())
})
.invoke_handler(tauri::generate_handler![
commands::network::get_local_address,
commands::smtp::start_smtp_server,
commands::smtp::stop_smtp_server,
commands::smtp::get_emails
])
.run(tauri::generate_context!())
.expect("error while running tauri application");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { useRequestConfig } from '@/stores/api-testing/request-config.store';
import { Globe, GlobeLock } from 'lucide-react';
import { useEffect, useMemo, useState } from 'react';
import { invoke } from '@tauri-apps/api/core';
import { Commands } from '@/lib/constants';
import { Commands } from '@/lib/common/commands';
import { Separator } from '@/components/ui/separator';

const dummyStats = {
Expand Down
2 changes: 2 additions & 0 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { SideNav } from '@/components/layout/side-nav';
import { TooltipProvider } from '@/components/ui/tooltip';
import { ThemeProvider } from '@/components/themes/theme-provider';
import { Toaster } from '@/components/ui/toaster';
import { Toaster as Sonner } from '@/components/ui/sonner';

const fontSans = FontSans({
subsets: ['latin'],
Expand Down Expand Up @@ -37,6 +38,7 @@ export default function RootLayout({
enableSystem
disableTransitionOnChange
>
<Sonner />
<Toaster />
<TooltipProvider>
<div className="flex flex-col bg-muted/40 w-full px-4">
Expand Down
4 changes: 2 additions & 2 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ export default function Page() {
title="SMTP Server"
description="Spin up a fake SMTP server for testing"
action={
<ComingSoon name="SMTP Server">
<Link href="/smtp">
<Button>Get started</Button>
</ComingSoon>
</Link>
}
/>
</div>
Expand Down
Loading

0 comments on commit 089dea3

Please sign in to comment.