1
0
Fork 0
forked from mirror/grapevine

Compare commits

...

2 commits

Author SHA1 Message Date
Lambda
cd658d038a Add type annotation to fix weird inference error
error[E0275]: overflow evaluating the requirement `Box<[_]>: Deserialize<'_>`
    --> src/api/server_server.rs:1801:32
     |
1801 |       let invited_user: Box<_> = serde_json::from_value(
     |  ________________________________^
1802 | |         signed_event
1803 | |             .get("state_key")
1804 | |             .ok_or(Error::BadRequest(
...    |
1809 | |             .into(),
1810 | |     )
     | |_____^
     |
     = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`grapevine`)
     = note: required for `Box<zerovec::varzerovec::slice::VarZeroSlice<[_], _>>` to implement `Deserialize<'_>`
     = note: 126 redundant requirements hidden
     = note: required for `Box<VarZeroSlice<VarZeroSlice<VarZeroSlice<VarZeroSlice<..., ...>, ...>, ...>, ...>>` to implement `for<'de> Deserialize<'de>`
     = note: required for `Box<VarZeroSlice<VarZeroSlice<VarZeroSlice<VarZeroSlice<..., ...>, ...>, ...>, ...>>` to implement `DeserializeOwned`
note: required by a bound in `serde_json::from_value`
    --> /home/xiretza/.cargo/registry/src/index.crates.io-6f17d22bba15001f/serde_json-1.0.117/src/value/mod.rs:1006:8
     |
1004 | pub fn from_value<T>(value: Value) -> Result<T, Error>
     |        ---------- required by a bound in this function
1005 | where
1006 |     T: DeserializeOwned,
     |        ^^^^^^^^^^^^^^^^ required by this bound in `from_value`
     = note: the full name for the type has been written to '/home/xiretza/dev/rust/grapevine-fork/target/debug/deps/grapevine-212231bd4a0b94d3.long-type-685143825526684512.txt'
     = note: consider using `--verbose` to print the full type name to the console
     = note: the full name for the type has been written to '/home/xiretza/dev/rust/grapevine-fork/target/debug/deps/grapevine-212231bd4a0b94d3.long-type-685143825526684512.txt'
     = note: consider using `--verbose` to print the full type name to the console
2024-09-06 17:17:00 +00:00
Lambda
d6fe411443 Add authenticated media certificate generator 2024-09-06 17:17:00 +00:00
14 changed files with 1932 additions and 13 deletions

1391
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -1,3 +1,7 @@
[workspace]
resolver = "2"
members = ["auth-media-cert-gen"]
# Keep alphabetically sorted
[workspace.lints.rust]
elided_lifetimes_in_paths = "warn"
@ -89,6 +93,7 @@ workspace = true
[dependencies]
argon2 = "0.5.3"
async-trait = "0.1.80"
auth-media-cert-gen = { path = "auth-media-cert-gen" }
axum = { version = "0.7.5", default-features = false, features = ["form", "http1", "http2", "json", "matched-path", "tracing"] }
axum-extra = { version = "0.9.3", features = ["typed-header"] }
axum-server = { version = "0.6.0", features = ["tls-rustls"] }

View file

@ -0,0 +1,13 @@
[package]
name = "auth-media-cert-gen"
version = "0.1.0"
edition = "2021"
[dependencies]
comemo = "0.4.0"
time = "0.3.36"
typst = "0.11.1"
typst-render = "0.11.1"
[lints]
workspace = true

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,44 @@
#let issuer = sys.inputs.issuer
#let target = sys.inputs.target
#set page(
width: 11cm,
height: 7cm,
fill: red.lighten(90%),
footer: text(size: 0.5em)[Issued by #issuer, #datetime.today().display()]
)
#set text(size: 1.1em)
#set text(font: "Comic Neue", weight: "bold", fill: gray.darken(80%))
#set align(center)
#set par(leading: 0.5em)
#let target = text(target.replace(".", "\u{200A}.\u{200A}"))
#text(size: 1.5em)[
Congratulations, \
#target user!
]
#parbreak()
#text(size: 0.9em)[
Your homeserver supports authenticated media!
]
#block(
above: 34pt,
radius: 4pt,
inset: 7pt,
fill: green.lighten(85%),
stroke: 2pt + green.lighten(10%),
grid(
columns: (2.3em, auto),
grid.cell(text(size: 1.7em, top-edge: 0.85em, emoji.checkmark.box)),
grid.cell(align(left)[
#target \
MSC3916 certified
]),
)
)
#let emojiscale = 45%
#place(horizon + right, dx: 41pt, dy: 35pt, scale(x: emojiscale, y: emojiscale, image("party.svg")))
#place(horizon + left, dx: -46pt, dy: 40pt, scale(x: emojiscale, y: emojiscale, image("confetti.svg")))

View file

@ -0,0 +1,116 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xml:space="preserve"
viewBox="0 0 137.28036 150.47484"
version="1.1"
id="svg20"
sodipodi:docname="confetti.svg"
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25, custom)"
width="137.28036"
height="150.47484"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs20" /><sodipodi:namedview
id="namedview20"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="4.5519999"
inkscape:cx="69.310195"
inkscape:cy="77.328648"
inkscape:window-width="1920"
inkscape:window-height="1032"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="svg20" /><path
d="m 36.102519,33.502424 a 4.336,4.336 0 0 1 2.981459,4.273757 C 38.893916,43.179918 38.196064,54.230597 35.561493,62.547558 32.317231,72.815487 27.62103,79.774991 25.056491,83.084437 23.922089,84.551384 21.979385,85.109954 20.226181,84.51727 15.909693,83.067568 7.8389298,79.104583 2.5612233,69.033294 -4.9583309,54.719483 5.3332491,37.699769 17.201466,33.823503 29.069683,29.947242 36.102519,33.502424 36.102519,33.502424"
style="fill:#ffc107"
id="path1" /><radialGradient
id="a"
cx="39.661999"
cy="33.066002"
r="15.102"
gradientUnits="userSpaceOnUse"
gradientTransform="rotate(-36,76.403023,62.749107)"><stop
offset=".376"
style="stop-color:#af5700"
id="stop1" /><stop
offset="1"
style="stop-color:#8f4700"
id="stop2" /></radialGradient><path
d="m 24.58535,79.730898 c -0.658535,1.084127 -2.321358,0.598826 -2.308258,-0.65912 0.05175,-3.671637 0.673125,-10.080941 3.284076,-19.740415 2.833376,-10.476192 6.262826,-15.946756 8.408695,-18.556478 0.74373,-0.898813 2.194066,-0.382711 2.202328,0.785526 0.03421,3.806958 -0.400859,11.119194 -3.365803,19.985204 -2.872918,8.601374 -6.14462,14.748412 -8.221038,18.185283"
style="fill:url(#a)"
id="path2" /><path
d="m 9.325047,44.72518 c 1.535965,1.331475 3.964078,0.420233 5.680907,-1.333904 1.861,-1.895966 4.313276,-4.134994 2.498971,-6.104764 -1.875295,-2.036707 -5.354133,0.626784 -6.611838,1.651807 -1.8350814,1.506315 -2.9283594,4.612077 -1.56804,5.786861"
style="fill:#ffee58"
id="path3" /><path
d="m 48.054922,10.381219 c 7.783173,-9.63494661 24.411187,-16.6233057 39.437834,-1.9294759 5.709964,5.5793299 7.274599,13.0579489 7.689403,17.3547449 0.207787,2.123399 -0.923219,4.156466 -2.860926,5.045148 -3.782763,1.734764 -11.27732,4.349283 -23.251427,5.187589 -6.65392,0.471036 -16.927314,-0.569056 -22.835159,-1.282831 -2.669408,-0.322565 -4.627624,-2.694566 -4.388867,-5.37725 0.465691,-5.245536 1.889405,-13.646889 6.209142,-18.997925"
style="fill:#ffc107"
id="path4" /><radialGradient
id="b"
cx="90.500999"
cy="31.969999"
r="21.224001"
gradientUnits="userSpaceOnUse"
gradientTransform="rotate(-36,76.403023,62.749107)"><stop
offset=".376"
style="stop-color:#af5700"
id="stop4" /><stop
offset="1"
style="stop-color:#8f4700"
id="stop5" /></radialGradient><path
d="m 50.331875,31.940273 c -0.879985,-0.139376 -1.017628,-1.349604 -0.184465,-1.682995 3.654704,-1.468722 10.622011,-3.873226 17.984713,-4.389462 7.556785,-0.521332 16.398675,0.607035 20.982404,1.318705 0.902045,0.135709 1.019073,1.385634 0.154302,1.692544 -3.939955,1.416344 -11.446832,3.656632 -20.258529,3.964888 -8.955794,0.31407 -15.304041,-0.376387 -18.678425,-0.90368"
style="fill:url(#b)"
id="path5" /><path
d="m 52.293787,17.338376 c -2.466763,3.324934 -5.004693,1.720219 -4.543772,-1.235126 0.330395,-2.13123 3.91154,-8.1075506 9.091506,-10.4371771 3.421685,-1.534228 7.46144,2.0695183 3.237676,5.0517381 -2.877129,2.028553 -4.763201,2.545979 -7.78541,6.620565"
style="fill:#ffee58"
id="path6" /><path
d="M 137.28037,89.346941 C 122.60573,90.33027 106.8948,82.894884 95.24954,69.452536 84.730746,57.30544 78.341734,41.910669 73.212902,29.543377 l 6.888164,-1.407586 c 4.912932,11.831952 11.519209,24.905756 21.190764,36.073876 10.0037,11.557209 23.26391,17.967263 35.44975,17.148166 z m -41.620109,26.827219 -6.954712,-3.95805 c 2.122879,-3.7302 0.93592,-9.20885 -2.540451,-11.71392 C 84.469543,99.274316 82.22013,98.56008 79.849426,97.797999 77.914637,97.176553 75.90413,96.535956 73.932752,95.557915 68.783063,92.995436 64.687891,88.430737 62.715686,83.028172 61.722979,80.300787 61.298605,77.556027 60.896975,74.893623 60.44258,71.886378 60.009415,69.061477 58.779752,66.790546 57.637498,64.690962 55.709106,62.98949 53.475937,62.127487 51.457404,61.356752 49.068048,61.164455 46.542678,60.972092 44.62678,60.818987 42.638831,60.668787 40.620866,60.256104 35.843172,59.277457 32.286031,56.559139 29.48672,52.672192 l 3.265999,-4.98099 c 0,0 4.014659,3.807389 6.390416,4.763568 2.491167,0.995936 5.119561,0.98984 7.764767,1.194022 2.990739,0.237433 6.335428,-0.177836 9.44555,1.023522 3.981189,1.532618 7.431574,4.563349 9.470736,8.322743 1.895183,3.493176 2.451456,7.168044 2.991613,10.718655 0.362067,2.369769 0.702136,4.607191 1.426109,6.59041 1.279079,3.49582 3.924434,6.456325 7.263724,8.109211 1.433326,0.713844 3.061577,1.236625 4.799359,1.791072 2.868369,0.919654 5.826423,1.860669 8.556805,3.832351 6.800607,4.885808 8.961795,14.835764 4.798463,22.137404"
style="fill:#03a9f4"
id="path7" /><path
d="M 58.691248,150.47484 51.073376,148.0369 C 62.55028,112.23302 46.036873,84.009068 34.560096,71.853426 l 3.79906,-5.046904 c 12.691473,13.43623 33.064396,43.961048 20.332092,83.668318"
style="fill:#f48fb1"
id="path8" /><path
d="m 97.620499,60.449496 0.669771,0.02017 c -1.982355,-2.626399 -3.798481,-5.398291 -5.475623,-8.234078 -3.478925,-0.228845 -6.906275,-0.692934 -10.008304,-1.900166 -0.08747,-0.03533 -0.166856,-0.07654 -0.254331,-0.111875 1.67916,3.229864 3.502421,6.453919 5.521299,9.572927 3.27958,0.447844 6.526233,0.561147 9.547188,0.653023"
style="fill:#0076c6"
id="path9" /><path
d="m 126.73434,66.478192 -7.85431,1.540936 C 118.03737,63.71183 113.9561,60.731533 110.42624,59.377789 105.8364,57.619906 100.49441,57.44678 95.322258,57.286238 89.772205,57.115958 83.488416,56.922535 77.588683,54.620701 66.745548,50.397593 60.478454,39.883235 60.789127,28.24861 l 6.610692,-0.785728 c -0.217215,8.377668 5.287795,16.652199 13.088438,19.69898 4.61114,1.804214 9.927403,1.958943 15.077505,2.123151 5.564028,0.172491 11.861768,0.368127 17.720378,2.613328 7.06558,2.715586 12.22337,8.300539 13.4482,14.579851 M 39.404781,126.51528 c -6.197945,-5.97879 -3.762421,-13.17465 -2.455564,-17.04125 0.159027,-0.46163 0.349719,-1.03281 0.466083,-1.45109 -0.441598,-0.55677 -1.353056,-0.99467 -2.968727,-1.68727 -2.66093,-1.14453 -6.30537,-2.72404 -7.608261,-7.154325 -1.129658,-3.851593 1.306962,-7.166986 2.552239,-9.87639 1.061286,-2.316156 1.470371,-4.492196 0.624607,-7.017326 -0.987455,-2.941333 -5.88644,-8.578358 -5.88644,-8.578358 l 2.272814,-5.174091 c 0,0 5.42504,4.846923 7.552823,7.775563 6.030677,8.300515 2.967367,13.764638 1.819236,16.267496 -0.796326,1.72811 -1.549232,3.362866 -1.260026,4.339369 0.209195,0.71326 0.956704,1.146659 3.114849,2.075527 2.587425,1.111415 6.130424,2.653375 7.592969,6.844055 0.715127,2.0391 0.03629,4.06501 -0.688182,6.19827 -1.27961,3.78501 -1.944044,6.44323 0.42961,8.72353 z M 86.776618,79.329039 c -3.379718,1.404851 -6.591734,1.118048 -9.413403,0.943195 l 0.499352,-7.98934 c 0,0 3.045462,1.112365 6.986114,-0.217961 z m -31.65598,-32.648363 -6.820905,0.666517 -0.516714,-7.992766 6.828995,-0.672395 z m 57.270102,52.727557 -9.35741,0.680007 0.955,-9.148554 8.40812,1.109768 z"
style="fill:#f44336"
id="path10" /><path
d="m 101.42396,41.377903 -0.0146,-7.999991 8.58997,-0.01574 0.0147,7.999983 z"
style="fill:#fb8c00"
id="path11" /><path
d="m 54.036615,71.967132 -8.580053,0.201761 0.10658,-6.097084 8.571961,-0.195882 z"
style="fill:#f44336"
id="path12" /><path
d="m 65.959428,73.848361 c 0,0 1.070873,-0.839838 2.632081,-1.56622 -0.423682,-2.65874 -0.954698,-5.363111 -2.120956,-7.989121 -1.959013,0.842358 -3.174884,2.010031 -3.174884,2.010031 z"
style="fill:#0076c6"
id="path13" /><path
d="m 74.189518,69.030755 c -3.656086,-0.285538 -7.326183,2.591072 -7.326183,2.591072 l -2.67184,-7.539434 c 0,0 3.751323,-3.615465 8.700361,-2.724225 z"
style="fill:#fb8c00"
id="path14" /><path
d="m 39.248262,133.69831 5.610358,-4.6235 5.08776,6.1737 -5.610358,4.6235 z"
style="fill:#fb8c00"
id="path15" /><path
d="m 69.596211,109.91973 -7.573684,-2.58129 c 0.803984,-2.36406 1.311734,-4.84664 1.499672,-7.344067 l 7.979731,0.605217 a 38.2,38.2 0 0 1 -1.905719,9.32014"
style="fill:#fb8c00"
id="path16" /><path
d="m 80.507028,124.8351 c -3.105462,-0.19118 -6.241886,-0.18679 -9.337233,0.0102 l -0.510837,-7.98468 c 3.4218,-0.22409 6.894215,-0.22536 10.33345,-0.0171 z"
style="fill:#f44336"
id="path17" /><path
d="m 95.856542,70.049822 c 2.172094,2.513265 3.88654,4.20949 6.307348,6.28248 l 1.77718,-6.519768 -7.917953,-2.170461 z"
style="fill:#0076c6"
id="path18" /><path
d="m 91.996028,79.163831 2.722156,-9.964875 7.717236,2.108154 -2.722159,9.964877 z"
style="fill:#ffc107"
id="path19" /><path
d="m 113.32155,113.19394 c -2.64324,-1.25626 -5.38874,-2.36409 -8.16299,-3.2903 l 2.53349,-7.58841 a 79,79 0 0 1 9.06345,3.66201 z"
style="fill:#fb8c00"
id="path20" /></svg>

After

Width:  |  Height:  |  Size: 9.6 KiB

View file

@ -0,0 +1,102 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xml:space="preserve"
viewBox="0 0 128.43089 126.50923"
version="1.1"
id="svg18"
sodipodi:docname="party.svg"
width="128.43089"
height="126.50923"
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs18" /><sodipodi:namedview
id="namedview18"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="6.4375"
inkscape:cx="67.184466"
inkscape:cy="60.893204"
inkscape:window-width="1920"
inkscape:window-height="1032"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="svg18" /><path
d="M 0.33214338,109.12986 C 2.140482,111.94667 12.093386,109.34546 19.958618,107.23925 25.85088,105.66857 49.2214,100.56934 60.872169,97.841032 64.017581,97.106062 68.560207,96.221441 72.33318,92.733623 75.683329,89.628192 85.576723,75.674169 73.779987,57.692505 61.808268,39.436285 45.870065,41.083673 39.489089,44.101476 35.733835,45.876347 32.076328,50.724886 30.377634,53.217785 23.199449,63.751335 12.145966,83.42074 7.6987152,91.13569 4.4311846,96.824719 -1.4599719,106.33623 0.33214338,109.12986"
style="fill:#ffc107"
id="path1" /><path
d="m 28.31235,56.407612 c -0.164275,1.737876 -0.311016,4.585659 -0.07563,10.16124 0.158098,3.825572 0.79704,7.918706 1.420731,10.658635 1.867602,8.239483 5.842614,12.128824 9.984377,15.418004 7.036767,5.586801 12.186266,7.307131 12.186266,7.307131 l -6.798857,1.471748 c 0,0 -3.700094,-1.474918 -8.484314,-4.978921 -4.558854,-3.342415 -9.024106,-8.425015 -11.387658,-17.249505 -1.021231,-3.825452 -1.372204,-7.421022 -1.444423,-10.236334 -0.08564,-3.48786 0.142907,-5.417489 0.142907,-5.417489 z M 17.000935,75.005956 c 0,0 -0.33913,6.530322 3.517261,15.526652 4.521044,10.524962 12.885179,13.594012 12.885179,13.594012 l -6.158183,1.35117 c 0,0 -6.06554,-3.09022 -10.694172,-12.486726 C 13.664788,87.130845 13.695179,80.739017 13.695179,80.739017 Z M 8.8645436,89.188552 c 0,0 0.4653897,5.768451 2.8909254,10.44062 2.885613,5.575788 7.410141,7.845958 7.410141,7.845958 l -4.745914,1.17371 c 0,0 -3.215208,-1.28788 -6.0526991,-6.56071 C 6.209763,98.082672 6.1338746,93.906047 6.1338746,93.906047 Z"
style="fill:#ff8f00"
id="path2" /><g
style="opacity:0.44"
id="g3"
transform="rotate(10,84.702281,75.521203)"><path
d="m 9.96,116.37 c -0.2,-0.45 -0.2,-0.96 0.01,-1.4 l 25.47,-52.82 4.19,15.75 -26.8,38.71 c -0.72,1.08 -2.34,0.94 -2.87,-0.24"
style="fill:#fffde7"
id="path3" /></g><linearGradient
id="a"
x1="74.384003"
x2="44.617001"
y1="61.839001"
y2="79.698997"
gradientUnits="userSpaceOnUse"
gradientTransform="rotate(10,84.702281,75.521203)"><stop
offset=".024"
style="stop-color:#8f4700"
id="stop3" /><stop
offset="1"
style="stop-color:#703e2d"
id="stop4" /></linearGradient><path
d="M 40.972388,75.597543 C 50.274417,91.37248 63.92071,92.011848 68.973435,89.328478 74.037743,86.636997 79.65986,75.311202 70.367132,59.771453 60.625934,43.492599 46.069317,45.07897 42.330382,47.567518 38.591448,50.056065 32.435774,61.125311 40.972388,75.597543"
style="fill:url(#a)"
id="path4" /><path
d="M 80.226477,88.337493 C 76.584491,83.99916 74.196714,84.238157 70.919803,84.97025 66.692317,85.910439 60.284288,86.029505 52.375873,81.700455 l 3.605838,-5.649684 c 4.696037,2.564417 8.45441,2.384315 11.900973,1.09319 4.434771,-1.655053 10.501303,-3.926111 17.783537,4.760399 3.037113,3.622423 6.339981,6.255969 9.178414,5.822269 2.064528,-0.306149 3.610837,-3.029002 4.540859,-5.251267 0.08571,-0.198127 0.26868,-0.775119 0.419801,-1.286649 1.109995,-3.530893 3.273135,-11.191652 9.786785,-14.1556 6.96603,-3.168497 13.4953,-2.017208 13.4953,-2.017208 l -0.88812,11.947287 c -2.92551,-0.972792 -5.12096,-0.730347 -7.05569,-0.06622 -7.28878,2.52264 -4.00849,17.723191 -15.179587,20.66809 -10.751122,2.866628 -17.47097,-6.533056 -19.737506,-9.227572"
style="fill:#03a9f4"
id="path5" /><path
d="M 46.309865,66.922595 42.711291,62.338059 C 52.105677,54.957246 51.17324,48.151942 50.49305,43.198577 50.354458,42.19933 50.226885,41.252796 50.190848,40.363021 50.056015,37.211732 50.383519,34.548136 50.996665,32.280152 48.644753,27.996671 48.00812,23.832863 47.966371,23.551337 47.112268,17.683883 49.444327,12.520397 53.499848,8.0060469 61.705874,-1.1582171 73.277363,0.8821445 73.277363,0.8821445 L 75.316237,11.89348 C 72.402348,11.257831 62.754729,9.7090089 58.97895,13.846204 c -4.767366,5.211329 -2.954219,9.267806 -2.849886,9.712682 0.883875,-0.808805 1.744606,-1.428759 2.497031,-1.895189 5.455234,-3.353657 9.65796,-3.232013 12.226024,-2.535492 2.887843,0.78337 5.286352,2.729432 6.759856,5.4872 1.609094,3.025379 1.856373,6.633127 0.642612,9.658319 -1.18017,2.949881 -3.675417,5.180474 -7.028161,6.285058 -5.854559,1.932728 -10.23643,0.753915 -13.045013,-0.766894 0.0076,0.0724 0.0035,0.15293 0.01104,0.22534 0.02151,0.511505 0.116609,1.239073 0.232004,2.081916 0.791517,5.704104 2.520797,14.843234 -12.114594,24.823448 m 13.75536,-35.683518 c 0.498255,0.514335 1.038211,0.964943 1.615228,1.320544 1.922233,1.191899 4.226063,1.313808 7.02967,0.386562 1.649149,-0.541861 1.979224,-1.377235 2.08867,-1.652411 0.328341,-0.825527 0.225646,-1.970757 -0.27035,-2.901019 -0.434577,-0.817889 -1.018564,-1.306724 -1.78267,-1.522689 -1.454638,-0.388498 -3.618763,0.194563 -5.932226,1.624559 -1.106337,0.688344 -2.020899,1.613589 -2.748322,2.744454"
style="fill:#f44336"
id="path6" /><path
d="m 63.132929,71.544101 -6.086135,-1.245773 c 0,0 5.798161,-15.894635 15.68929,-16.993757 1.853103,-0.20127 3.87536,-0.382868 5.865789,-0.326375 1.183481,0.0259 3.052261,0.08125 4.007476,-0.09556 0.479438,-1.509683 0.176761,-3.593906 -0.157816,-5.95792 -0.265571,-1.833976 -0.542149,-3.720667 -0.513464,-5.726155 0.0597,-3.90902 1.666194,-7.088356 4.526439,-8.97027 3.488712,-2.278812 8.48214,-2.322376 13.719172,-0.119504 2.98697,1.257788 5.01242,3.188839 6.79511,4.884157 2.54687,2.429165 4.05899,3.701063 8.00309,1.949337 4.77126,-2.12374 1.18205,-14.362943 -0.63613,-21.385356 l 11.87206,-2.658831 c 0.91402,3.512075 5.14472,21.500004 -1.27486,30.207546 -2.16147,2.92916 -5.28417,4.571869 -9.02922,4.73401 -8.14816,0.370718 -12.19906,-3.491386 -15.15496,-6.307457 -1.399742,-1.333316 -2.642451,-2.4054 -4.072805,-3.104395 -9.942353,-4.829849 1.956337,13.149483 -6.108824,18.865827 -4.837707,3.421928 -15.065647,2.745594 -15.743405,2.788548 -6.734702,0.416865 -11.700808,9.461925 -11.700808,9.461925"
style="fill:#f48fb1"
id="path7" /><path
d="m 50.986817,32.278416 c -0.56914,2.133584 -0.885251,3.408054 -0.820544,6.323583 2.357452,2.466844 8.25645,3.506997 8.25645,3.506997 -0.115391,-0.842844 -0.220347,-1.572148 -0.232003,-2.081916 -0.0076,-0.0724 -0.0035,-0.152931 -0.01104,-0.22534 -5.469588,-4.051334 -7.192864,-7.523324 -7.192864,-7.523324"
style="fill:#c92b27"
id="path8" /><path
d="m 37.005678,39.815116 -9.302516,-6.788497 6.363703,-6.432682 7.0543,6.696705 z"
style="fill:#ffc107"
id="path9" /><path
d="M 24.435228,23.342017 C 19.358733,21.725941 14.838411,16.379776 14.345936,15.775071 l 6.168669,-5.096245 c 1.315197,1.582421 4.207372,4.356791 6.351398,5.039469 z"
style="fill:#fb8c00"
id="path10" /><path
d="M 35.928366,11.832931 28.876212,8.0610329 C 30.194898,5.5925184 30.919775,2.8060592 30.957617,0 l 8.000515,0.1211146 c -0.05794,4.0717987 -1.107041,8.1211433 -3.029766,11.7118164"
style="fill:#03a9f4"
id="path11" /><path
d="m 83.702688,14.21982 7.993335,-0.326495 0.430974,10.551201 -7.993335,0.326495 z"
style="fill:#fb8c00"
id="path12" /><path
d="m 102.37053,19.994485 -4.407543,-6.676799 c 3.310303,-2.188418 4.580203,-5.5895751 4.587153,-5.6289671 l 7.55597,2.6422231 c -0.20787,0.603064 -2.18538,6.001691 -7.73558,9.663543"
style="fill:#ffc107"
id="path13" /><path
d="m 100.02783,50.866597 7.25978,-0.937082 1.02413,7.934177 -7.25978,0.937082 z"
style="fill:#fb8c00"
id="path14" /><path
d="m 90.841481,114.69114 -7.665994,-2.30623 c 0.826259,-2.72796 -0.649125,-6.51163 -1.086607,-7.37066 l 7.136285,-3.61572 c 0.363308,0.70377 3.468004,7.11022 1.616316,13.29261"
style="fill:#f44336"
id="path15" /><path
d="m 115.07559,108.66784 c -2.86644,-0.96237 -5.84869,-1.67101 -8.84191,-2.08709 l 1.12329,-7.925348 c 3.47751,0.49133 6.93884,1.30474 10.2641,2.429248 z"
style="fill:#fb8c00"
id="path16" /><path
d="m 102.57033,117.64484 6.52394,-4.63015 6.29121,8.86439 -6.52393,4.63015 z"
style="fill:#f48fb1"
id="path17" /><path
d="m 95.09196,64.977986 4.544606,7.51232 -7.51232,4.544606 -4.544606,-7.51232 z"
style="fill:#f44336"
id="path18" /></svg>

After

Width:  |  Height:  |  Size: 9 KiB

View file

@ -0,0 +1,10 @@
#set page(
width: 11cm,
height: 5cm,
fill: red.lighten(90%),
)
#set text(font: "Comic Neue", weight: "bold", size: 2.2em, fill: gray.darken(70%))
#set align(center)
#set par(leading: 0.5em)
Unfortunately, your server does not support authenticated media as of #datetime.today().display().

View file

@ -0,0 +1,161 @@
use std::collections::HashMap;
use comemo::Prehashed;
use time::OffsetDateTime;
use typst::{
diag::{FileError, FileResult},
eval::Tracer,
foundations::{Bytes, Datetime, IntoValue},
syntax::{FileId, Source, VirtualPath},
text::{Font, FontBook},
visualize::Color,
Library, World,
};
const EMBEDDED_FONTS: &[&[u8]] = &[
include_bytes!("../res/ComicNeue-Bold.ttf"),
include_bytes!("../res/NotoColorEmoji.ttf"),
];
const AUTH_SOURCE: &str = include_str!("../res/auth.typ");
const UNAUTH_SOURCE: &str = include_str!("../res/unauth.typ");
const FILE_SOURCES: &[(&str, &[u8])] = &[
("confetti.svg", include_bytes!("../res/confetti.svg")),
("party.svg", include_bytes!("../res/party.svg")),
];
fn get_fonts() -> (FontBook, Vec<Font>) {
let mut book = FontBook::new();
let mut fonts = vec![];
for font in EMBEDDED_FONTS
.iter()
.flat_map(|data| Font::iter(Bytes::from_static(data)))
{
book.push(font.info().clone());
fonts.push(font);
}
(book, fonts)
}
/// A minimal world that generates Authenticated Media certificates
pub struct AuthMediaWorld {
/// The name of the server issuing the certificate
issuer: String,
/// File ID of the authenticated source
auth_id: FileId,
/// File ID of the unauthenticated source
unauth_id: FileId,
/// True if the authenticated source should be used
is_authenticated: bool,
/// Typst's standard library.
library: Prehashed<Library>,
/// Metadata about discovered fonts.
book: Prehashed<FontBook>,
/// Locations of and storage for lazily loaded fonts.
fonts: Vec<Font>,
/// Maps file ids to source files and buffers.
slots: HashMap<FileId, (Bytes, Option<Source>)>,
/// The current datetime if requested. This is stored here to ensure it is
/// always the same within one compilation. Reset between compilations.
now: Datetime,
}
impl AuthMediaWorld {
#[must_use]
pub fn new(issuer: String) -> Self {
let auth_id = FileId::new_fake(VirtualPath::new("<auth>"));
let unauth_id = FileId::new_fake(VirtualPath::new("<unauth>"));
let mut slots = HashMap::new();
for &(name, data) in FILE_SOURCES {
let id = FileId::new(None, VirtualPath::new(format!("/{name}")));
let bytes = data.into();
let source = std::str::from_utf8(data)
.ok()
.map(|s| Source::new(id, s.to_owned()));
slots.insert(id, (bytes, source));
}
let library = Library::builder().build();
let (book, fonts) = get_fonts();
let now = Datetime::Date(OffsetDateTime::now_utc().date());
Self {
issuer,
auth_id,
unauth_id,
is_authenticated: false,
library: Prehashed::new(library),
book: Prehashed::new(book),
fonts,
slots,
now,
}
}
pub fn generate(&mut self, target: Option<&str>) -> Option<Vec<u8>> {
let mut inputs =
vec![("issuer".into(), self.issuer.as_str().into_value())];
if let Some(target) = target {
inputs.push(("target".into(), target.into_value()));
}
let library = Library::builder()
.with_inputs(inputs.into_iter().collect())
.build();
self.library.update(|old| *old = library);
self.is_authenticated = target.is_some();
let mut tracer = Tracer::new();
let document = typst::compile(self, &mut tracer).unwrap();
if document.pages.len() != 1 {
return None;
}
typst_render::render(&document.pages[0].frame, 2.0, Color::WHITE)
.encode_png()
.ok()
}
}
impl World for AuthMediaWorld {
fn library(&self) -> &Prehashed<Library> {
&self.library
}
fn book(&self) -> &Prehashed<FontBook> {
&self.book
}
fn main(&self) -> Source {
if self.is_authenticated {
Source::new(self.auth_id, AUTH_SOURCE.to_owned())
} else {
Source::new(self.unauth_id, UNAUTH_SOURCE.to_owned())
}
}
fn source(&self, id: FileId) -> FileResult<Source> {
let (_bytes, source) = self.slots.get(&id).ok_or(
FileError::NotFound(id.vpath().as_rooted_path().to_owned()),
)?;
Ok(source.as_ref().ok_or(FileError::NotSource)?.clone())
}
fn file(&self, id: FileId) -> FileResult<Bytes> {
let (bytes, _source) = self.slots.get(&id).ok_or(
FileError::NotFound(id.vpath().as_rooted_path().to_owned()),
)?;
Ok(bytes.clone())
}
fn font(&self, index: usize) -> Option<Font> {
self.fonts.get(index).cloned()
}
fn today(&self, offset: Option<i64>) -> Option<Datetime> {
assert_eq!(offset, None, "today offset not supported");
Some(self.now)
}
}

View file

@ -1,6 +1,7 @@
use std::time::Duration;
use axum::response::IntoResponse;
use axum_extra::headers::ContentType;
use http::{
header::{CONTENT_DISPOSITION, CONTENT_SECURITY_POLICY, CONTENT_TYPE},
HeaderName, HeaderValue, Method,
@ -449,6 +450,24 @@ async fn get_content_route_ruma(
) -> Result<authenticated_media_client::get_content::v1::Response> {
let mxc = MxcData::new(&body.server_name, &body.media_id)?;
if body.media_id.starts_with("auth_media_cert") {
let Some(file) = services().media.generate_auth_media_cert(None).await
else {
return Err(Error::BadRequest(
ErrorKind::NotYetUploaded,
"Failed to generate authenticated media certificate",
));
};
return Ok(authenticated_media_client::get_content::v1::Response {
file,
content_type: Some(ContentType::png().to_string()),
content_disposition: Some(ContentDisposition::new(
ContentDispositionType::Inline,
)),
});
}
if let Some((
FileMeta {
content_type,

View file

@ -10,7 +10,7 @@ use std::{
};
use axum::{response::IntoResponse, Json};
use axum_extra::headers::{Authorization, HeaderMapExt};
use axum_extra::headers::{Authorization, ContentType, HeaderMapExt};
use base64::Engine as _;
use get_profile_information::v1::ProfileField;
use ruma::{
@ -55,6 +55,7 @@ use ruma::{
},
StateEventType, TimelineEventType,
},
http_headers::ContentDisposition,
serde::{Base64, JsonObject, Raw},
server_util::authorization::XMatrix,
state_res::Event,
@ -62,7 +63,7 @@ use ruma::{
uint, user_id, CanonicalJsonObject, CanonicalJsonValue, EventId,
MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedRoomId, OwnedServerName,
OwnedServerSigningKeyId, OwnedSigningKeyId, OwnedUserId, RoomId,
ServerName,
ServerName, UserId,
};
use serde_json::value::{to_raw_value, RawValue as RawJsonValue};
use tokio::sync::RwLock;
@ -1796,7 +1797,7 @@ pub(crate) async fn create_invite_route(
Error::BadRequest(ErrorKind::InvalidParam, "sender is not a user id.")
})?;
let invited_user: Box<_> = serde_json::from_value(
let invited_user: Box<UserId> = serde_json::from_value(
signed_event
.get("state_key")
.ok_or(Error::BadRequest(
@ -2046,6 +2047,33 @@ pub(crate) async fn media_download_route(
body: Ar<authenticated_media::get_content::v1::Request>,
) -> Result<Ra<authenticated_media::get_content::v1::Response>> {
let mxc = MxcData::new(services().globals.server_name(), &body.media_id)?;
if body.media_id.starts_with("auth_media_cert") {
let Some(file) = services()
.media
.generate_auth_media_cert(body.sender_servername.as_deref())
.await
else {
return Err(Error::BadRequest(
ErrorKind::NotYetUploaded,
"Failed to generate authenticated media certificate",
));
};
return Ok(Ra(authenticated_media::get_content::v1::Response {
metadata: authenticated_media::ContentMetadata {},
content: authenticated_media::FileOrLocation::File(
authenticated_media::Content {
file,
content_type: Some(ContentType::png().to_string()),
content_disposition: Some(ContentDisposition::new(
ruma::http_headers::ContentDispositionType::Inline,
)),
},
),
}));
}
let Some((
crate::service::media::FileMeta {
content_disposition,
@ -2086,6 +2114,14 @@ pub(crate) async fn media_thumbnail_route(
body: Ar<authenticated_media::get_content_thumbnail::v1::Request>,
) -> Result<Ra<authenticated_media::get_content_thumbnail::v1::Response>> {
let mxc = MxcData::new(services().globals.server_name(), &body.media_id)?;
if body.media_id.starts_with("auth_media_cert") {
return Err(Error::BadRequest(
ErrorKind::NotYetUploaded,
"No thumbnails for authenticated media certificates",
));
}
let width = body.width.try_into().map_err(|_| {
Error::BadRequest(ErrorKind::InvalidParam, "Width is invalid.")
})?;

View file

@ -145,9 +145,7 @@ impl Services {
account_data: db,
admin: admin::Service::build(),
key_backups: db,
media: media::Service {
db,
},
media: media::Service::new(db),
sending: sending::Service::build(db, &config),
globals: globals::Service::load(db, config, reload_handles)?,

View file

@ -1,12 +1,13 @@
use std::io::Cursor;
use image::imageops::FilterType;
use ruma::http_headers::ContentDisposition;
use ruma::{http_headers::ContentDisposition, ServerName};
use tokio::{
fs::File,
io::{AsyncReadExt, AsyncWriteExt},
sync::Mutex,
};
use tracing::{debug, warn};
use tracing::{debug, info, warn};
use crate::{services, Result};
@ -39,9 +40,17 @@ impl MediaFileKey {
pub(crate) struct Service {
pub(crate) db: &'static dyn Data,
cert_gen: Mutex<Option<auth_media_cert_gen::AuthMediaWorld>>,
}
impl Service {
pub(crate) fn new(db: &'static dyn Data) -> Self {
Self {
db,
cert_gen: Mutex::new(None),
}
}
/// Uploads a file.
#[tracing::instrument(skip(self, file))]
pub(crate) async fn create(
@ -287,4 +296,29 @@ impl Service {
Ok(Some((meta, thumbnail_bytes.clone())))
}
#[tracing::instrument(skip(self))]
pub(crate) async fn generate_auth_media_cert(
&self,
target: Option<&ServerName>,
) -> Option<Vec<u8>> {
let mut cert_gen_lock = self.cert_gen.lock().await;
let mut cert_gen = cert_gen_lock.take().unwrap_or_else(|| {
auth_media_cert_gen::AuthMediaWorld::new(
services().globals.server_name().to_string(),
)
});
let target = target.map(|s| s.to_string());
let (file, cert_gen) = tokio::task::spawn_blocking(move || {
info!(target, "generating authenticated media cert");
(cert_gen.generate(target.as_deref()), cert_gen)
})
.await
.ok()?;
*cert_gen_lock = Some(cert_gen);
file
}
}