Innit
This commit is contained in:
commit
a931dc8d28
14 changed files with 670 additions and 0 deletions
25
.editorconfig
Normal file
25
.editorconfig
Normal file
|
@ -0,0 +1,25 @@
|
|||
root = true
|
||||
|
||||
[*]
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.{yml,yaml}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.fs]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
fsharp_newline_between_type_definition_and_members=true
|
||||
fsharp_multiline_bracket_style=aligned
|
||||
fsharp_keep_max_number_of_blank_lines=1
|
||||
fsharp_multiline_bracket_style = stroustrup
|
||||
|
||||
[*.fsi]
|
||||
fsharp_newline_between_type_definition_and_members=true
|
||||
fsharp_keep_max_number_of_blank_lines=1
|
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
/target
|
||||
bin
|
||||
obj
|
11
.rustfmt.toml
Normal file
11
.rustfmt.toml
Normal file
|
@ -0,0 +1,11 @@
|
|||
condense_wildcard_suffixes = true
|
||||
edition = "2021"
|
||||
fn_single_line = true
|
||||
format_code_in_doc_comments = true
|
||||
format_macro_matchers = true
|
||||
hard_tabs = true
|
||||
match_block_trailing_comma = true
|
||||
imports_granularity = "Crate"
|
||||
newline_style = "Unix"
|
||||
group_imports = "StdExternalCrate"
|
||||
tab_spaces = 4
|
39
Cargo.toml
Normal file
39
Cargo.toml
Normal file
|
@ -0,0 +1,39 @@
|
|||
[package]
|
||||
name = "iomail-server"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
description = "iomail"
|
||||
authors = ["davidontop <me@davidon.top>"]
|
||||
readme = "README.md"
|
||||
documentation = "https://docs.rs/iomail"
|
||||
license = "GLWTPL"
|
||||
repository = "git@github.com:davidontop/iomail.git"
|
||||
|
||||
[dependencies]
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
tracing = "0.1"
|
||||
tracing-subscriber = "0.3"
|
||||
tokio = { version = "1.0", features = ["full"] }
|
||||
|
||||
[profile.release]
|
||||
codegen-units = 1
|
||||
lto = true
|
||||
opt-level = 'z'
|
||||
|
||||
[[workspace.metadata.leptos]]
|
||||
name = "iomail"
|
||||
bin-package = "server"
|
||||
lib-package = "client"
|
||||
site-root = "target/site"
|
||||
site-pkg-dir = "pkg"
|
||||
style-file = "client/globaltw.css"
|
||||
assets-dir = "public"
|
||||
site-addr = "127.0.0.1:8690"
|
||||
reload-port = 3001
|
||||
watch = false
|
||||
env = "DEV"
|
||||
bin-features = []
|
||||
bin-default-features = false
|
||||
lib-features = []
|
||||
lib-default-features = false
|
26
LICENSE
Normal file
26
LICENSE
Normal file
|
@ -0,0 +1,26 @@
|
|||
GLWTS(Good Luck With That Shit) Public License
|
||||
Copyright (c) Every-fucking-one
|
||||
|
||||
Everyone is permitted to copy, distribute, modify, merge, sell, publish,
|
||||
sublicense or whatever the fuck they want with this software but at their
|
||||
OWN RISK.
|
||||
|
||||
Preamble
|
||||
|
||||
The author has absolutely no fucking clue what the code in this project
|
||||
does. It might just fucking work or not, there is no third option.
|
||||
|
||||
|
||||
GOOD LUCK WITH THAT SHIT PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION, AND MODIFICATION
|
||||
|
||||
0. You just DO WHATEVER THE FUCK YOU WANT TO as long as you NEVER LEAVE
|
||||
A FUCKING TRACE TO TRACK THE AUTHOR of the original product to blame for
|
||||
or held responsible.
|
||||
|
||||
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Good luck and Godspeed.
|
1
README.md
Normal file
1
README.md
Normal file
|
@ -0,0 +1 @@
|
|||
# iomail
|
6
app/Cargo.toml
Normal file
6
app/Cargo.toml
Normal file
|
@ -0,0 +1,6 @@
|
|||
[package]
|
||||
name = "app"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
14
app/src/lib.rs
Normal file
14
app/src/lib.rs
Normal file
|
@ -0,0 +1,14 @@
|
|||
pub fn add(left: usize, right: usize) -> usize {
|
||||
left + right
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn it_works() {
|
||||
let result = add(2, 2);
|
||||
assert_eq!(result, 4);
|
||||
}
|
||||
}
|
400
pgmodeler.dbm
Normal file
400
pgmodeler.dbm
Normal file
|
@ -0,0 +1,400 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
CAUTION: Do not modify this file unless you know what you are doing.
|
||||
Unexpected results may occur if the code is changed deliberately.
|
||||
-->
|
||||
<dbmodel pgmodeler-ver="1.1.3" use-changelog="false" max-obj-count="12"
|
||||
last-position="0,137" last-zoom="1"
|
||||
default-owner="postgres"
|
||||
layers="Default layer"
|
||||
active-layers="0"
|
||||
layer-name-colors="#000000"
|
||||
layer-rect-colors="#b4b4b4"
|
||||
show-layer-names="false" show-layer-rects="false">
|
||||
<database name="iomail" is-template="false" allow-conns="true">
|
||||
</database>
|
||||
|
||||
<schema name="public" layers="0" fill-color="#e1e1e1" name-color="#000000" sql-disabled="true">
|
||||
</schema>
|
||||
|
||||
<table name="Grant" layers="0" collapse-mode="2" max-obj-count="4" z-value="0">
|
||||
<schema name="public"/>
|
||||
<role name="postgres"/>
|
||||
<position x="160" y="240"/>
|
||||
<column name="Id" not-null="true">
|
||||
<type name="bytea" length="0"/>
|
||||
</column>
|
||||
<column name="Resource" not-null="true">
|
||||
<type name="bytea" length="0"/>
|
||||
</column>
|
||||
<column name="Permission" not-null="true">
|
||||
<type name="integer" length="0"/>
|
||||
</column>
|
||||
<column name="GrantedTo" not-null="true">
|
||||
<type name="bigint" length="0"/>
|
||||
</column>
|
||||
<constraint name="Grant_pk" type="pk-constr" table="public."Grant"">
|
||||
<columns names="Id" ref-type="src-columns"/>
|
||||
</constraint>
|
||||
</table>
|
||||
|
||||
<table name="Project" layers="0" collapse-mode="2" max-obj-count="3" z-value="0">
|
||||
<schema name="public"/>
|
||||
<role name="postgres"/>
|
||||
<position x="480" y="260"/>
|
||||
<column name="Id" not-null="true">
|
||||
<type name="bytea" length="0"/>
|
||||
</column>
|
||||
<column name="Name" not-null="true">
|
||||
<type name="varchar" length="0"/>
|
||||
</column>
|
||||
<column name="Description" not-null="true">
|
||||
<type name="varchar" length="0"/>
|
||||
</column>
|
||||
<constraint name="Project_pk" type="pk-constr" table="public."Project"">
|
||||
<columns names="Id" ref-type="src-columns"/>
|
||||
</constraint>
|
||||
</table>
|
||||
|
||||
<extension name="hstore">
|
||||
<schema name="public"/>
|
||||
<type name="hstore"/>
|
||||
</extension>
|
||||
|
||||
<table name="Mail" layers="0" collapse-mode="2" max-obj-count="7" z-value="0">
|
||||
<schema name="public"/>
|
||||
<role name="postgres"/>
|
||||
<position x="760" y="280"/>
|
||||
<column name="Id" not-null="true">
|
||||
<type name="bytea" length="0"/>
|
||||
</column>
|
||||
<column name="From" not-null="true">
|
||||
<type name="varchar" length="0"/>
|
||||
</column>
|
||||
<column name="To" not-null="true">
|
||||
<type name="varchar" length="0" dimension="1"/>
|
||||
</column>
|
||||
<column name="Properties" not-null="true">
|
||||
<type name="public.hstore" length="0"/>
|
||||
</column>
|
||||
<column name="Body" not-null="true">
|
||||
<type name="bytea" length="0"/>
|
||||
</column>
|
||||
<constraint name="Mail_pk" type="pk-constr" table="public."Mail"">
|
||||
<columns names="Id" ref-type="src-columns"/>
|
||||
</constraint>
|
||||
|
||||
<customidxs object-type="column">
|
||||
<object name="Lists" index="5"/>
|
||||
</customidxs>
|
||||
<customidxs object-type="constraint">
|
||||
<object name="Lists_fk" index="1"/>
|
||||
</customidxs></table>
|
||||
|
||||
<table name="Lists" layers="0" collapse-mode="2" max-obj-count="6" z-value="0">
|
||||
<schema name="public"/>
|
||||
<role name="postgres"/>
|
||||
<position x="160" y="620"/>
|
||||
<column name="Id" not-null="true">
|
||||
<type name="bytea" length="0"/>
|
||||
</column>
|
||||
<column name="Name" not-null="true">
|
||||
<type name="varchar" length="0"/>
|
||||
</column>
|
||||
<column name="Description" not-null="true">
|
||||
<type name="varchar" length="0"/>
|
||||
</column>
|
||||
<column name="Mail" not-null="true">
|
||||
<type name="varchar" length="0"/>
|
||||
</column>
|
||||
<constraint name="List_pk" type="pk-constr" table="public."Lists"">
|
||||
<columns names="Id" ref-type="src-columns"/>
|
||||
</constraint>
|
||||
<constraint name="Unique Mail" type="uq-constr" table="public."Lists"">
|
||||
<columns names="Mail" ref-type="src-columns"/>
|
||||
</constraint>
|
||||
|
||||
<customidxs object-type="column">
|
||||
<object name="Project" index="3"/>
|
||||
</customidxs>
|
||||
<customidxs object-type="constraint">
|
||||
<object name="Project_fk" index="1"/>
|
||||
</customidxs></table>
|
||||
|
||||
<relationship name="List_has_many_Mails" type="rel1n" layers="0"
|
||||
src-col-pattern="{st}"
|
||||
pk-pattern="{dt}_pk" uq-pattern="{dt}_uq"
|
||||
src-fk-pattern="{st}_fk"
|
||||
custom-color="#254479"
|
||||
src-table="public."Lists""
|
||||
dst-table="public."Mail""
|
||||
src-required="true" dst-required="false"/>
|
||||
|
||||
<relationship name="Project_has_many_List" type="rel1n" layers="0"
|
||||
src-col-pattern="{st}"
|
||||
pk-pattern="{dt}_pk" uq-pattern="{dt}_uq"
|
||||
src-fk-pattern="{st}_fk"
|
||||
custom-color="#ced88f"
|
||||
src-table="public."Project""
|
||||
dst-table="public."Lists""
|
||||
src-required="true" dst-required="false"/>
|
||||
|
||||
<table name="Board" layers="0" collapse-mode="2" max-obj-count="4" z-value="0">
|
||||
<schema name="public"/>
|
||||
<role name="postgres"/>
|
||||
<position x="520" y="660"/>
|
||||
<column name="Id" not-null="true">
|
||||
<type name="bytea" length="0"/>
|
||||
</column>
|
||||
<column name="Name" not-null="true">
|
||||
<type name="varchar" length="0"/>
|
||||
</column>
|
||||
<column name="Description" not-null="true">
|
||||
<type name="varchar" length="0"/>
|
||||
</column>
|
||||
<constraint name="Board_pk" type="pk-constr" table="public."Board"">
|
||||
<columns names="Id" ref-type="src-columns"/>
|
||||
</constraint>
|
||||
|
||||
<customidxs object-type="column">
|
||||
<object name="Project" index="3"/>
|
||||
</customidxs>
|
||||
<customidxs object-type="constraint">
|
||||
<object name="Project_fk" index="1"/>
|
||||
</customidxs></table>
|
||||
|
||||
<relationship name="Project_has_many_Boards" type="rel1n" layers="0"
|
||||
src-col-pattern="{st}"
|
||||
pk-pattern="{dt}_pk" uq-pattern="{dt}_uq"
|
||||
src-fk-pattern="{st}_fk"
|
||||
custom-color="#47e6ba"
|
||||
src-table="public."Project""
|
||||
dst-table="public."Board""
|
||||
src-required="true" dst-required="false"/>
|
||||
|
||||
<table name="Issue" layers="0" collapse-mode="2" max-obj-count="2" z-value="0">
|
||||
<schema name="public"/>
|
||||
<role name="postgres"/>
|
||||
<position x="900" y="560"/>
|
||||
<column name="Id" not-null="true">
|
||||
<type name="bytea" length="0"/>
|
||||
</column>
|
||||
<constraint name="Issue_pk" type="pk-constr" table="public."Issue"">
|
||||
<columns names="Id" ref-type="src-columns"/>
|
||||
</constraint>
|
||||
|
||||
<customidxs object-type="column">
|
||||
<object name="Board" index="1"/>
|
||||
</customidxs>
|
||||
<customidxs object-type="constraint">
|
||||
<object name="Board_fk" index="1"/>
|
||||
</customidxs></table>
|
||||
|
||||
<relationship name="Board_has_many_Issues" type="rel1n" layers="0"
|
||||
src-col-pattern="{st}"
|
||||
pk-pattern="{dt}_pk" uq-pattern="{dt}_uq"
|
||||
src-fk-pattern="{st}_fk"
|
||||
custom-color="#1e54c7"
|
||||
src-table="public."Board""
|
||||
dst-table="public."Issue""
|
||||
src-required="true" dst-required="false"/>
|
||||
|
||||
<table name="IssueField" layers="0" collapse-mode="2" max-obj-count="6" z-value="0">
|
||||
<schema name="public"/>
|
||||
<role name="postgres"/>
|
||||
<position x="1020" y="800"/>
|
||||
<column name="Id" not-null="true">
|
||||
<type name="bytea" length="0"/>
|
||||
</column>
|
||||
<column name="Type" not-null="true">
|
||||
<type name="smallint" length="0"/>
|
||||
</column>
|
||||
<column name="Opts" not-null="true">
|
||||
<type name="smallint" length="0"/>
|
||||
</column>
|
||||
<column name="Default">
|
||||
<type name="bytea" length="0"/>
|
||||
</column>
|
||||
<constraint name="IssueField_pk" type="pk-constr" table="public."IssueField"">
|
||||
<columns names="Id" ref-type="src-columns"/>
|
||||
</constraint>
|
||||
|
||||
<customidxs object-type="column">
|
||||
<object name="Board" index="4"/>
|
||||
</customidxs>
|
||||
<customidxs object-type="constraint">
|
||||
<object name="Board_fk" index="1"/>
|
||||
</customidxs></table>
|
||||
|
||||
<relationship name="Board_has_many_IssueField" type="rel1n" layers="0"
|
||||
src-col-pattern="{st}"
|
||||
pk-pattern="{dt}_pk" uq-pattern="{dt}_uq"
|
||||
src-fk-pattern="{st}_fk"
|
||||
custom-color="#3d6105"
|
||||
src-table="public."Board""
|
||||
dst-table="public."IssueField""
|
||||
src-required="true" dst-required="false"/>
|
||||
|
||||
<table name="IssueData" layers="0" collapse-mode="2" max-obj-count="4" z-value="0">
|
||||
<schema name="public"/>
|
||||
<role name="postgres"/>
|
||||
<position x="1280" y="480"/>
|
||||
<column name="Id" not-null="true">
|
||||
<type name="bytea" length="0"/>
|
||||
</column>
|
||||
<column name="Data">
|
||||
<type name="bytea" length="0"/>
|
||||
</column>
|
||||
<constraint name="IssueData_pk" type="pk-constr" table="public."IssueData"">
|
||||
<columns names="Id" ref-type="src-columns"/>
|
||||
</constraint>
|
||||
|
||||
<customidxs object-type="column">
|
||||
<object name="Field" index="3"/>
|
||||
<object name="Issue" index="2"/>
|
||||
</customidxs>
|
||||
<customidxs object-type="constraint">
|
||||
<object name="IssueField_fk" index="2"/>
|
||||
<object name="Issue_fk" index="1"/>
|
||||
</customidxs></table>
|
||||
|
||||
<relationship name="Issue_has_many_IssueData" type="rel1n" layers="0"
|
||||
src-col-pattern="Issue"
|
||||
pk-pattern="{dt}_pk" uq-pattern="{dt}_uq"
|
||||
src-fk-pattern="{st}_fk"
|
||||
custom-color="#60ecee"
|
||||
src-table="public."Issue""
|
||||
dst-table="public."IssueData""
|
||||
src-required="true" dst-required="false"/>
|
||||
|
||||
<relationship name="IssueField_has_many_IssueData" type="rel1n" layers="0"
|
||||
src-col-pattern="Field"
|
||||
pk-pattern="{dt}_pk" uq-pattern="{dt}_uq"
|
||||
src-fk-pattern="{st}_fk"
|
||||
custom-color="#19f273"
|
||||
src-table="public."IssueField""
|
||||
dst-table="public."IssueData""
|
||||
src-required="true" dst-required="false"/>
|
||||
|
||||
<table name="PermissionPreset" layers="0" collapse-mode="2" max-obj-count="3" z-value="0">
|
||||
<schema name="public"/>
|
||||
<role name="postgres"/>
|
||||
<position x="1080" y="300"/>
|
||||
<column name="Id" not-null="true">
|
||||
<type name="bytea" length="0"/>
|
||||
</column>
|
||||
<column name="Name" not-null="true">
|
||||
<type name="varchar" length="0"/>
|
||||
</column>
|
||||
<column name="Permission" not-null="true">
|
||||
<type name="integer" length="0"/>
|
||||
</column>
|
||||
<constraint name="PermissionPreset_pk" type="pk-constr" table="public."PermissionPreset"">
|
||||
<columns names="Id" ref-type="src-columns"/>
|
||||
</constraint>
|
||||
</table>
|
||||
|
||||
<table name="SuperAdmins" layers="0" collapse-mode="2" max-obj-count="2" z-value="0">
|
||||
<schema name="public"/>
|
||||
<role name="postgres"/>
|
||||
<position x="520" y="900"/>
|
||||
<column name="Id" not-null="true">
|
||||
<type name="bytea" length="0"/>
|
||||
</column>
|
||||
<column name="User" not-null="true">
|
||||
<type name="bigint" length="0"/>
|
||||
</column>
|
||||
<constraint name="SuperAdmins_pk" type="pk-constr" table="public."SuperAdmins"">
|
||||
<columns names="Id" ref-type="src-columns"/>
|
||||
</constraint>
|
||||
</table>
|
||||
|
||||
<index name="Resource" table="public."Grant""
|
||||
concurrent="false" unique="false" fast-update="false" buffering="false" nulls-not-distinct="false"
|
||||
index-type="btree" factor="0">
|
||||
<idxelement use-sorting="false">
|
||||
<column name="Resource"/>
|
||||
</idxelement>
|
||||
</index>
|
||||
|
||||
<index name="User" table="public."Grant""
|
||||
concurrent="false" unique="false" fast-update="false" buffering="false" nulls-not-distinct="false"
|
||||
index-type="btree" factor="0">
|
||||
<idxelement use-sorting="false">
|
||||
<column name="GrantedTo"/>
|
||||
</idxelement>
|
||||
</index>
|
||||
|
||||
<index name="Name" table="public."Project""
|
||||
concurrent="false" unique="false" fast-update="false" buffering="false" nulls-not-distinct="false"
|
||||
index-type="btree" factor="0">
|
||||
<idxelement use-sorting="false">
|
||||
<column name="Name"/>
|
||||
</idxelement>
|
||||
</index>
|
||||
|
||||
<index name="Project_1" table="public."Lists""
|
||||
concurrent="false" unique="false" fast-update="false" buffering="false" nulls-not-distinct="false"
|
||||
index-type="btree" factor="0">
|
||||
<idxelement use-sorting="false">
|
||||
<column name="Project"/>
|
||||
</idxelement>
|
||||
</index>
|
||||
|
||||
<index name="Project_2" table="public."Board""
|
||||
concurrent="false" unique="false" fast-update="false" buffering="false" nulls-not-distinct="false"
|
||||
index-type="btree" factor="0">
|
||||
<idxelement use-sorting="false">
|
||||
<column name="Project"/>
|
||||
</idxelement>
|
||||
</index>
|
||||
|
||||
<index name="User_1" table="public."SuperAdmins""
|
||||
concurrent="false" unique="false" fast-update="false" buffering="false" nulls-not-distinct="false"
|
||||
index-type="btree" factor="0">
|
||||
<idxelement use-sorting="false">
|
||||
<column name="User"/>
|
||||
</idxelement>
|
||||
</index>
|
||||
|
||||
<index name="List_1" table="public."Mail""
|
||||
concurrent="false" unique="false" fast-update="false" buffering="false" nulls-not-distinct="false"
|
||||
index-type="btree" factor="0">
|
||||
<idxelement use-sorting="false">
|
||||
<column name="Lists"/>
|
||||
</idxelement>
|
||||
</index>
|
||||
|
||||
<index name="Board_1" table="public."Issue""
|
||||
concurrent="false" unique="false" fast-update="false" buffering="false" nulls-not-distinct="false"
|
||||
index-type="btree" factor="0">
|
||||
<idxelement use-sorting="false">
|
||||
<column name="Board"/>
|
||||
</idxelement>
|
||||
</index>
|
||||
|
||||
<index name="Board_2" table="public."IssueField""
|
||||
concurrent="false" unique="false" fast-update="false" buffering="false" nulls-not-distinct="false"
|
||||
index-type="btree" factor="0">
|
||||
<idxelement use-sorting="false">
|
||||
<column name="Board"/>
|
||||
</idxelement>
|
||||
</index>
|
||||
|
||||
<index name="Issue_1" table="public."IssueData""
|
||||
concurrent="false" unique="false" fast-update="false" buffering="false" nulls-not-distinct="false"
|
||||
index-type="btree" factor="0">
|
||||
<idxelement use-sorting="false">
|
||||
<column name="Issue"/>
|
||||
</idxelement>
|
||||
</index>
|
||||
|
||||
<index name="Mail_1" table="public."Lists""
|
||||
concurrent="false" unique="false" fast-update="false" buffering="false" nulls-not-distinct="false"
|
||||
index-type="btree" factor="0">
|
||||
<idxelement use-sorting="false">
|
||||
<column name="Mail"/>
|
||||
</idxelement>
|
||||
</index>
|
||||
|
||||
</dbmodel>
|
0
server/Cargo.toml
Normal file
0
server/Cargo.toml
Normal file
3
server/src/main.rs
Normal file
3
server/src/main.rs
Normal file
|
@ -0,0 +1,3 @@
|
|||
fn main() {
|
||||
println!("Hello, world!");
|
||||
}
|
9
smtp/go.mod
Normal file
9
smtp/go.mod
Normal file
|
@ -0,0 +1,9 @@
|
|||
module git.davidon.top/iomail.git
|
||||
|
||||
go 1.22.3
|
||||
|
||||
require (
|
||||
github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21 // indirect
|
||||
github.com/emersion/go-smtp v0.21.2 // indirect
|
||||
github.com/rabbitmq/amqp091-go v1.10.0 // indirect
|
||||
)
|
6
smtp/go.sum
Normal file
6
smtp/go.sum
Normal file
|
@ -0,0 +1,6 @@
|
|||
github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21 h1:OJyUGMJTzHTd1XQp98QTaHernxMYzRaOasRir9hUlFQ=
|
||||
github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21/go.mod h1:iL2twTeMvZnrg54ZoPDNfJaJaqy0xIQFuBdrLsmspwQ=
|
||||
github.com/emersion/go-smtp v0.21.2 h1:OLDgvZKuofk4em9fT5tFG5j4jE1/hXnX75UMvcrL4AA=
|
||||
github.com/emersion/go-smtp v0.21.2/go.mod h1:qm27SGYgoIPRot6ubfQ/GpiPy/g3PaZAVRxiO/sDUgQ=
|
||||
github.com/rabbitmq/amqp091-go v1.10.0 h1:STpn5XsHlHGcecLmMFCtg7mqq0RnD+zFr4uzukfVhBw=
|
||||
github.com/rabbitmq/amqp091-go v1.10.0/go.mod h1:Hy4jKW5kQART1u+JkDTF9YYOQUHXqMuhrgxOEeS7G4o=
|
127
smtp/main.go
Normal file
127
smtp/main.go
Normal file
|
@ -0,0 +1,127 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/emersion/go-smtp"
|
||||
"github.com/rabbitmq/amqp091-go"
|
||||
)
|
||||
|
||||
type Mail struct {
|
||||
From *string `json:"from"`
|
||||
To *string `json:"to"`
|
||||
Body *string `json:"body"`
|
||||
UTF8 *bool `json:"UTF8"`
|
||||
}
|
||||
|
||||
type backend struct{
|
||||
Queue *amqp091.Queue
|
||||
Channel *amqp091.Channel
|
||||
}
|
||||
|
||||
func (bkd *backend) NewSession(c *smtp.Conn) (smtp.Session, error) {
|
||||
return &session{
|
||||
Queue: bkd.Queue,
|
||||
Channel: bkd.Channel,
|
||||
MailBuilder: Mail{},
|
||||
}, nil
|
||||
}
|
||||
|
||||
type session struct{
|
||||
Queue *amqp091.Queue
|
||||
MailBuilder Mail
|
||||
Channel *amqp091.Channel
|
||||
}
|
||||
|
||||
func (s *session) AuthPlain(username, password string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *session) Mail(from string, opts *smtp.MailOptions) error {
|
||||
s.MailBuilder.From = &from
|
||||
s.MailBuilder.UTF8 = &opts.UTF8
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *session) Rcpt(to string, opts *smtp.RcptOptions) error {
|
||||
s.MailBuilder.To = &to
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *session) Data(r io.Reader) error {
|
||||
buf := new(bytes.Buffer)
|
||||
if _, err := buf.ReadFrom(r); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
body := base64.StdEncoding.EncodeToString(buf.Bytes())
|
||||
s.MailBuilder.Body = &body
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *session) Reset() {
|
||||
submitMail(s.MailBuilder, s.Channel, s.Queue)
|
||||
}
|
||||
|
||||
func (s *session) Logout() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func submitMail(mail Mail, ch *amqp091.Channel, q *amqp091.Queue) {
|
||||
mb, err := json.Marshal(mail)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
err = ch.Publish(
|
||||
"",
|
||||
q.Name,
|
||||
false,
|
||||
false,
|
||||
amqp091.Publishing{
|
||||
ContentType: "application/octet-stream",
|
||||
Body: []byte(base64.StdEncoding.EncodeToString(mb)),
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
log.Println("oh uh")
|
||||
log.Fatal(err)
|
||||
}
|
||||
log.Println("Submited mail to rabbitmq")
|
||||
}
|
||||
|
||||
|
||||
func main() {
|
||||
conn, err := amqp091.Dial("amqp://d:8o9HGX!CFx!2sg!@dUqN@localhost:5672/")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
ch, err := conn.Channel()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer ch.Close()
|
||||
|
||||
q, err := ch.QueueDeclare("mail", true, false, false, false, nil)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
s := smtp.NewServer(&backend{
|
||||
Queue: &q,
|
||||
Channel: ch,
|
||||
})
|
||||
|
||||
s.Addr = "0.0.0.0:8700"
|
||||
s.AllowInsecureAuth = true
|
||||
s.Debug = os.Stderr
|
||||
|
||||
log.Println("Starting smtp server")
|
||||
log.Fatal(s.ListenAndServe())
|
||||
|
||||
}
|
Loading…
Reference in a new issue