Compare commits

...

36 Commits

Author SHA1 Message Date
ycc
f8537aad6d long poll exit fix 2025-05-07 22:53:34 +02:00
ycc
8d589505e5 change array of pointer to array of requestjobs 2025-05-07 20:44:41 +02:00
ycc
511e260157 change longpoll job array param type 2025-05-04 23:19:18 +02:00
ycc
839fb7c0f9 long poll helper first draft - untested 2025-05-04 22:34:20 +02:00
ycc
3af112b860 go 1.24 2025-05-04 21:12:55 +02:00
ycc
7e68a12adb refactor 2025-05-04 09:56:09 +02:00
ycc
ec8924d05a save peer status when db created or last message when received
Some checks failed
continuous-integration/drone/push Build is failing
2024-06-05 23:18:25 +02:00
ycc
d2bd4deb82 fix server creatiuon with userkp
Some checks failed
continuous-integration/drone/push Build is failing
2024-06-05 22:40:38 +02:00
ycc
9b6caf4e62 adding loggers
Some checks failed
continuous-integration/drone/push Build is failing
2024-06-05 22:23:48 +02:00
ycc
050de1a0b3 clean logwriter
Some checks failed
continuous-integration/drone/push Build is failing
2024-06-05 21:31:34 +02:00
ycc
606c42cd5e add name to server when creating from uid or url
Some checks failed
continuous-integration/drone/push Build is failing
2024-06-05 21:07:00 +02:00
ycc
af55df1ff5 store unknown servers in the invitation process answer and finalize + server storage fixes and testing
Some checks failed
continuous-integration/drone/push Build is failing
2024-06-05 14:45:01 +02:00
ycc
c0fd74f1e6 again
Some checks failed
continuous-integration/drone/push Build is failing
2024-06-04 22:36:45 +02:00
ycc
24cc151938 lokiwriter fix
Some checks failed
continuous-integration/drone/push Build is failing
2024-06-04 22:34:44 +02:00
ycc
cc663d88c8 added lokiwriter log, server logger setting function and some zerolog logs
Some checks failed
continuous-integration/drone/push Build is failing
2024-06-04 22:02:18 +02:00
ycc
118eb29d17 add nameexists to peers storage
Some checks failed
continuous-integration/drone/push Build is failing
2024-05-28 20:19:58 +02:00
ycc
e9624e4576 write peer storage test + fix loading
Some checks failed
continuous-integration/drone/push Build is failing
2024-05-28 18:39:32 +02:00
ycc
78a8b797e6 initial load peers fix
Some checks failed
continuous-integration/drone/push Build is failing
2024-05-28 18:05:41 +02:00
ycc
9179021544 peer db default load fix
Some checks failed
continuous-integration/drone/push Build is failing
2024-05-28 17:32:26 +02:00
ycc
d049f87cdc peers db alpha release
Some checks failed
continuous-integration/drone/push Build is failing
2024-05-28 17:25:10 +02:00
ycc
e674a0cb33 peers separate
Some checks failed
continuous-integration/drone/push Build is failing
2024-05-28 16:47:04 +02:00
ycc
c1883f1524 ready to switch to peer DB
Some checks failed
continuous-integration/drone/push Build is failing
2024-05-28 14:28:10 +02:00
ycc
c284b15788 some video retated fixes
Some checks failed
continuous-integration/drone/push Build is failing
2024-05-27 18:38:38 +02:00
ycc
17c991f442 some adjustmentsfor server delivery and peer storage study
Some checks failed
continuous-integration/drone/push Build is failing
2024-05-23 14:14:12 +02:00
ycc
d657e64ae4 models and doc update
Some checks failed
continuous-integration/drone/push Build is failing
2024-05-22 10:06:00 +02:00
ycc
2e2ebad364 bugfix : return valur from subscribe
Some checks failed
continuous-integration/drone/push Build is failing
2024-04-24 20:12:03 +02:00
ycc
428eda0ab7 Update RedisRouter.Publish method to use channel prefix for destination
Some checks failed
continuous-integration/drone/push Build is failing
2024-04-24 19:39:12 +02:00
ycc
a3557d5183 Add RedisRouter.Publish method to store and publish messages
Some checks failed
continuous-integration/drone/push Build is failing
2024-04-23 23:35:23 +02:00
ycc
5491244d01 Refactor RedisRouter subscribe function to include timeout parameter
Some checks failed
continuous-integration/drone/push Build is failing
2024-04-23 22:48:37 +02:00
ycc
04d2b0246a Add longPoll parameter to CheckForMessages function
Some checks failed
continuous-integration/drone/push Build is failing
2024-04-23 22:41:58 +02:00
ycc
4dfec86279 Update Config.Load function to override default values if not set or wrong
Some checks failed
continuous-integration/drone/push Build is failing
2024-04-23 22:31:11 +02:00
ycc
d14cd161da manage http timeout to allow long poll
Some checks failed
continuous-integration/drone/push Build is failing
2024-04-20 22:29:22 +02:00
ycc
7c17a11426 long poll routing first version
Some checks failed
continuous-integration/drone/push Build is failing
2024-04-19 09:13:50 +02:00
ycc
6cfc54d943 change meowurl scheme to meow://http//url for safer uri parsing
Some checks failed
continuous-integration/drone/push Build is failing
2024-04-12 14:37:20 +02:00
ycc
5aec7b3ad4 refactor router
Some checks failed
continuous-integration/drone/push Build is failing
2024-04-10 11:18:42 +02:00
ycc
d709cb9454 Update PrepareUserMessage function to include replyToUid parameter 2024-04-09 20:58:29 +02:00
61 changed files with 5561 additions and 690 deletions

View File

@ -0,0 +1,103 @@
# Details
Date : 2024-08-27 08:23:38
Directory /home/yves/Documents/code/go/meow/meowlib
Total : 88 files, 10488 codes, 836 comments, 1073 blanks, all 12397 lines
[Summary](results.md) / Details / [Diff Summary](diff.md) / [Diff Details](diff-details.md)
## Files
| filename | language | code | comment | blank | total |
| :--- | :--- | ---: | ---: | ---: | ---: |
| [.drone.yml](/.drone.yml) | YAML | 9 | 0 | 3 | 12 |
| [README.md](/README.md) | Markdown | 21 | 0 | 8 | 29 |
| [asymcrypt.go](/asymcrypt.go) | Go | 237 | 36 | 41 | 314 |
| [asymcrypt_test.go](/asymcrypt_test.go) | Go | 101 | 65 | 17 | 183 |
| [buffer.go](/buffer.go) | Go | 62 | 0 | 5 | 67 |
| [buffer_test.go](/buffer_test.go) | Go | 20 | 0 | 5 | 25 |
| [clean.sh](/clean.sh) | Shell Script | 9 | 1 | 1 | 11 |
| [client/avatar.go](/client/avatar.go) | Go | 6 | 0 | 3 | 9 |
| [client/config.go](/client/config.go) | Go | 99 | 7 | 15 | 121 |
| [client/config_test.go](/client/config_test.go) | Go | 17 | 0 | 4 | 21 |
| [client/dbmessage.go](/client/dbmessage.go) | Go | 46 | 0 | 6 | 52 |
| [client/helpers/backgroundHelper.go](/client/helpers/backgroundHelper.go) | Go | 140 | 28 | 23 | 191 |
| [client/helpers/call.go](/client/helpers/call.go) | Go | 42 | 3 | 11 | 56 |
| [client/helpers/contactHelper.go](/client/helpers/contactHelper.go) | Go | 1 | 0 | 1 | 2 |
| [client/helpers/invitationAnswerHelper.go](/client/helpers/invitationAnswerHelper.go) | Go | 106 | 27 | 23 | 156 |
| [client/helpers/invitationCheckHelper.go](/client/helpers/invitationCheckHelper.go) | Go | 52 | 65 | 10 | 127 |
| [client/helpers/invitationCreateHelper.go](/client/helpers/invitationCreateHelper.go) | Go | 77 | 50 | 17 | 144 |
| [client/helpers/invitationFinalizeHelper.go](/client/helpers/invitationFinalizeHelper.go) | Go | 34 | 12 | 8 | 54 |
| [client/helpers/logger.go](/client/helpers/logger.go) | Go | 8 | 1 | 4 | 13 |
| [client/helpers/messageHelper.go](/client/helpers/messageHelper.go) | Go | 66 | 9 | 12 | 87 |
| [client/helpers/networkHelper.go](/client/helpers/networkHelper.go) | Go | 25 | 2 | 4 | 31 |
| [client/helpers/serverHelper.go](/client/helpers/serverHelper.go) | Go | 1 | 0 | 1 | 2 |
| [client/helpers/storageHelper.go](/client/helpers/storageHelper.go) | Go | 13 | 0 | 3 | 16 |
| [client/identity.go](/client/identity.go) | Go | 254 | 81 | 27 | 362 |
| [client/identity_test.go](/client/identity_test.go) | Go | 91 | 27 | 11 | 129 |
| [client/internalusermessage.go](/client/internalusermessage.go) | Go | 41 | 5 | 5 | 51 |
| [client/logger.go](/client/logger.go) | Go | 8 | 1 | 4 | 13 |
| [client/matriochka.go](/client/matriochka.go) | Go | 44 | 4 | 4 | 52 |
| [client/messagestorage.go](/client/messagestorage.go) | Go | 314 | 30 | 23 | 367 |
| [client/messagestorage_test.go](/client/messagestorage_test.go) | Go | 74 | 5 | 5 | 84 |
| [client/peer.go](/client/peer.go) | Go | 249 | 42 | 35 | 326 |
| [client/peer_test.go](/client/peer_test.go) | Go | 26 | 0 | 4 | 30 |
| [client/peerlist.go](/client/peerlist.go) | Go | 34 | 11 | 7 | 52 |
| [client/peerstorage.go](/client/peerstorage.go) | Go | 209 | 20 | 20 | 249 |
| [client/peerstorage_test.go](/client/peerstorage_test.go) | Go | 50 | 1 | 10 | 61 |
| [client/server.go](/client/server.go) | Go | 249 | 33 | 26 | 308 |
| [client/serverlist.go](/client/serverlist.go) | Go | 37 | 9 | 7 | 53 |
| [client/serverstorage.go](/client/serverstorage.go) | Go | 234 | 17 | 18 | 269 |
| [client/serverstorage_test.go](/client/serverstorage_test.go) | Go | 177 | 21 | 27 | 225 |
| [contactcard.go](/contactcard.go) | Go | 147 | 7 | 24 | 178 |
| [contactcard_test.go](/contactcard_test.go) | Go | 61 | 0 | 5 | 66 |
| [crypt.go](/crypt.go) | Go | 5 | 0 | 2 | 7 |
| [doc/act_01_send_msg.puml](/doc/act_01_send_msg.puml) | PlantUML | 21 | 0 | 1 | 22 |
| [doc/act_02_srv_recv_msg.puml](/doc/act_02_srv_recv_msg.puml) | PlantUML | 21 | 0 | 1 | 22 |
| [doc/act_03_srv_proc_msg.puml](/doc/act_03_srv_proc_msg.puml) | PlantUML | 20 | 0 | 0 | 20 |
| [doc/architecture.tex](/doc/architecture.tex) | LaTeX | 0 | 0 | 1 | 1 |
| [doc/class_messages01.puml](/doc/class_messages01.puml) | PlantUML | 70 | 0 | 14 | 84 |
| [doc/docgen.sh](/doc/docgen.sh) | Shell Script | 13 | 1 | 4 | 18 |
| [doc/endpoints/company_endpoint.puml](/doc/endpoints/company_endpoint.puml) | PlantUML | 7 | 0 | 0 | 7 |
| [doc/endpoints/public_endpoint.puml](/doc/endpoints/public_endpoint.puml) | PlantUML | 10 | 0 | 0 | 10 |
| [doc/general_deployment.puml](/doc/general_deployment.puml) | PlantUML | 19 | 0 | 3 | 22 |
| [doc/invitation/sq_invitation.puml](/doc/invitation/sq_invitation.puml) | PlantUML | 7 | 0 | 0 | 7 |
| [doc/invitation/sq_srvinv01.puml](/doc/invitation/sq_srvinv01.puml) | PlantUML | 12 | 0 | 0 | 12 |
| [doc/invitation/sq_srvinv02.puml](/doc/invitation/sq_srvinv02.puml) | PlantUML | 11 | 0 | 0 | 11 |
| [doc/invitation/sq_srvinv03.puml](/doc/invitation/sq_srvinv03.puml) | PlantUML | 11 | 0 | 1 | 12 |
| [doc/invitation/sq_srvinv04.puml](/doc/invitation/sq_srvinv04.puml) | PlantUML | 8 | 0 | 1 | 9 |
| [doc/meow.svg](/doc/meow.svg) | SVG | 2,814 | 1 | 2 | 2,817 |
| [doc/meow.tex](/doc/meow.tex) | LaTeX | 175 | 0 | 50 | 225 |
| [doc/messaging/sq_msg01.puml](/doc/messaging/sq_msg01.puml) | PlantUML | 9 | 0 | 1 | 10 |
| [doc/messaging/wbs_messages_encapsulation.puml](/doc/messaging/wbs_messages_encapsulation.puml) | PlantUML | 13 | 0 | 2 | 15 |
| [doc/protocol.tex](/doc/protocol.tex) | LaTeX | 60 | 0 | 24 | 84 |
| [doc/server/server_deployment.puml](/doc/server/server_deployment.puml) | PlantUML | 33 | 0 | 3 | 36 |
| [doc/server/server_messaging.puml](/doc/server/server_messaging.puml) | PlantUML | 18 | 0 | 6 | 24 |
| [doc/server/sq_01_srvmessaging.puml](/doc/server/sq_01_srvmessaging.puml) | PlantUML | 18 | 0 | 2 | 20 |
| [doc/server/sq_02_srvmessaging.puml](/doc/server/sq_02_srvmessaging.puml) | PlantUML | 27 | 0 | 3 | 30 |
| [doc/usecase01.puml](/doc/usecase01.puml) | PlantUML | 9 | 0 | 7 | 16 |
| [doc/usecase02.puml](/doc/usecase02.puml) | PlantUML | 10 | 0 | 6 | 16 |
| [doc/usecase03.puml](/doc/usecase03.puml) | PlantUML | 33 | 0 | 7 | 40 |
| [endtoend_test.go](/endtoend_test.go) | Go | 125 | 55 | 18 | 198 |
| [go.mod](/go.mod) | Go Module File | 45 | 0 | 5 | 50 |
| [go.sum](/go.sum) | Go Checksum File | 344 | 0 | 1 | 345 |
| [http.go](/http.go) | Go | 41 | 0 | 4 | 45 |
| [lokiwriter.go](/lokiwriter.go) | Go | 74 | 5 | 19 | 98 |
| [message.go](/message.go) | Go | 37 | 0 | 7 | 44 |
| [messages.pb.go](/messages.pb.go) | Go | 2,058 | 45 | 265 | 2,368 |
| [pb/messages.proto](/pb/messages.proto) | Protocol Buffers | 194 | 0 | 40 | 234 |
| [pb/messages.py](/pb/messages.py) | Python | 11 | 1 | 5 | 17 |
| [pb/protogen.bat](/pb/protogen.bat) | Batch | 4 | 0 | 1 | 5 |
| [pb/protogen.sh](/pb/protogen.sh) | Shell Script | 12 | 1 | 1 | 14 |
| [proto_test.go](/proto_test.go) | Go | 33 | 0 | 5 | 38 |
| [server/identity.go](/server/identity.go) | Go | 135 | 15 | 20 | 170 |
| [server/invitation.go](/server/invitation.go) | Go | 62 | 1 | 8 | 71 |
| [server/logger.go](/server/logger.go) | Go | 8 | 1 | 4 | 13 |
| [server/router.go](/server/router.go) | Go | 271 | 54 | 21 | 346 |
| [server/videoserver.go](/server/videoserver.go) | Go | 35 | 0 | 7 | 42 |
| [servercard.go](/servercard.go) | Go | 10 | 0 | 3 | 13 |
| [symcrypt.go](/symcrypt.go) | Go | 26 | 36 | 7 | 69 |
| [symcrypt_test.go](/symcrypt_test.go) | Go | 18 | 0 | 4 | 22 |
[Summary](results.md) / Details / [Diff Summary](diff.md) / [Diff Details](diff-details.md)

View File

@ -0,0 +1,15 @@
# Diff Details
Date : 2024-08-27 08:23:38
Directory /home/yves/Documents/code/go/meow/meowlib
Total : 0 files, 0 codes, 0 comments, 0 blanks, all 0 lines
[Summary](results.md) / [Details](details.md) / [Diff Summary](diff.md) / Diff Details
## Files
| filename | language | code | comment | blank | total |
| :--- | :--- | ---: | ---: | ---: | ---: |
[Summary](results.md) / [Details](details.md) / [Diff Summary](diff.md) / Diff Details

View File

@ -0,0 +1,2 @@
"filename", "language", "", "comment", "blank", "total"
"Total", "-", , 0, 0, 0
1 filename language comment blank total
2 Total - 0 0 0

View File

@ -0,0 +1,19 @@
# Diff Summary
Date : 2024-08-27 08:23:38
Directory /home/yves/Documents/code/go/meow/meowlib
Total : 0 files, 0 codes, 0 comments, 0 blanks, all 0 lines
[Summary](results.md) / [Details](details.md) / Diff Summary / [Diff Details](diff-details.md)
## Languages
| language | files | code | comment | blank | total |
| :--- | ---: | ---: | ---: | ---: | ---: |
## Directories
| path | files | code | comment | blank | total |
| :--- | ---: | ---: | ---: | ---: | ---: |
[Summary](results.md) / [Details](details.md) / Diff Summary / [Diff Details](diff-details.md)

View File

@ -0,0 +1,22 @@
Date : 2024-08-27 08:23:38
Directory : /home/yves/Documents/code/go/meow/meowlib
Total : 0 files, 0 codes, 0 comments, 0 blanks, all 0 lines
Languages
+----------+------------+------------+------------+------------+------------+
| language | files | code | comment | blank | total |
+----------+------------+------------+------------+------------+------------+
+----------+------------+------------+------------+------------+------------+
Directories
+------+------------+------------+------------+------------+------------+
| path | files | code | comment | blank | total |
+------+------------+------------+------------+------------+------------+
+------+------------+------------+------------+------------+------------+
Files
+----------+----------+------------+------------+------------+------------+
| filename | language | code | comment | blank | total |
+----------+----------+------------+------------+------------+------------+
| Total | | 0 | 0 | 0 | 0 |
+----------+----------+------------+------------+------------+------------+

View File

@ -0,0 +1,90 @@
"filename", "language", "Go", "Go Module File", "Markdown", "YAML", "Go Checksum File", "Shell Script", "Batch", "Protocol Buffers", "Python", "LaTeX", "PlantUML", "SVG", "comment", "blank", "total"
"/home/yves/Documents/code/go/meow/meowlib/.drone.yml", "YAML", 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 12
"/home/yves/Documents/code/go/meow/meowlib/README.md", "Markdown", 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 29
"/home/yves/Documents/code/go/meow/meowlib/asymcrypt.go", "Go", 237, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 41, 314
"/home/yves/Documents/code/go/meow/meowlib/asymcrypt_test.go", "Go", 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65, 17, 183
"/home/yves/Documents/code/go/meow/meowlib/buffer.go", "Go", 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 67
"/home/yves/Documents/code/go/meow/meowlib/buffer_test.go", "Go", 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 25
"/home/yves/Documents/code/go/meow/meowlib/clean.sh", "Shell Script", 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 1, 1, 11
"/home/yves/Documents/code/go/meow/meowlib/client/avatar.go", "Go", 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 9
"/home/yves/Documents/code/go/meow/meowlib/client/config.go", "Go", 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 15, 121
"/home/yves/Documents/code/go/meow/meowlib/client/config_test.go", "Go", 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 21
"/home/yves/Documents/code/go/meow/meowlib/client/dbmessage.go", "Go", 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 52
"/home/yves/Documents/code/go/meow/meowlib/client/helpers/backgroundHelper.go", "Go", 140, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 23, 191
"/home/yves/Documents/code/go/meow/meowlib/client/helpers/call.go", "Go", 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 11, 56
"/home/yves/Documents/code/go/meow/meowlib/client/helpers/contactHelper.go", "Go", 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2
"/home/yves/Documents/code/go/meow/meowlib/client/helpers/invitationAnswerHelper.go", "Go", 106, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 23, 156
"/home/yves/Documents/code/go/meow/meowlib/client/helpers/invitationCheckHelper.go", "Go", 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65, 10, 127
"/home/yves/Documents/code/go/meow/meowlib/client/helpers/invitationCreateHelper.go", "Go", 77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 17, 144
"/home/yves/Documents/code/go/meow/meowlib/client/helpers/invitationFinalizeHelper.go", "Go", 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 8, 54
"/home/yves/Documents/code/go/meow/meowlib/client/helpers/logger.go", "Go", 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 13
"/home/yves/Documents/code/go/meow/meowlib/client/helpers/messageHelper.go", "Go", 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 12, 87
"/home/yves/Documents/code/go/meow/meowlib/client/helpers/networkHelper.go", "Go", 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 31
"/home/yves/Documents/code/go/meow/meowlib/client/helpers/serverHelper.go", "Go", 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2
"/home/yves/Documents/code/go/meow/meowlib/client/helpers/storageHelper.go", "Go", 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 16
"/home/yves/Documents/code/go/meow/meowlib/client/identity.go", "Go", 254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 27, 362
"/home/yves/Documents/code/go/meow/meowlib/client/identity_test.go", "Go", 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 11, 129
"/home/yves/Documents/code/go/meow/meowlib/client/internalusermessage.go", "Go", 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 51
"/home/yves/Documents/code/go/meow/meowlib/client/logger.go", "Go", 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 13
"/home/yves/Documents/code/go/meow/meowlib/client/matriochka.go", "Go", 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 52
"/home/yves/Documents/code/go/meow/meowlib/client/messagestorage.go", "Go", 314, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 23, 367
"/home/yves/Documents/code/go/meow/meowlib/client/messagestorage_test.go", "Go", 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 84
"/home/yves/Documents/code/go/meow/meowlib/client/peer.go", "Go", 249, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 35, 326
"/home/yves/Documents/code/go/meow/meowlib/client/peer_test.go", "Go", 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 30
"/home/yves/Documents/code/go/meow/meowlib/client/peerlist.go", "Go", 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 7, 52
"/home/yves/Documents/code/go/meow/meowlib/client/peerstorage.go", "Go", 209, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 20, 249
"/home/yves/Documents/code/go/meow/meowlib/client/peerstorage_test.go", "Go", 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 10, 61
"/home/yves/Documents/code/go/meow/meowlib/client/server.go", "Go", 249, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 26, 308
"/home/yves/Documents/code/go/meow/meowlib/client/serverlist.go", "Go", 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 7, 53
"/home/yves/Documents/code/go/meow/meowlib/client/serverstorage.go", "Go", 234, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 18, 269
"/home/yves/Documents/code/go/meow/meowlib/client/serverstorage_test.go", "Go", 177, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 27, 225
"/home/yves/Documents/code/go/meow/meowlib/contactcard.go", "Go", 147, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 24, 178
"/home/yves/Documents/code/go/meow/meowlib/contactcard_test.go", "Go", 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 66
"/home/yves/Documents/code/go/meow/meowlib/crypt.go", "Go", 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 7
"/home/yves/Documents/code/go/meow/meowlib/doc/act_01_send_msg.puml", "PlantUML", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 22
"/home/yves/Documents/code/go/meow/meowlib/doc/act_02_srv_recv_msg.puml", "PlantUML", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 22
"/home/yves/Documents/code/go/meow/meowlib/doc/act_03_srv_proc_msg.puml", "PlantUML", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 20
"/home/yves/Documents/code/go/meow/meowlib/doc/architecture.tex", "LaTeX", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1
"/home/yves/Documents/code/go/meow/meowlib/doc/class_messages01.puml", "PlantUML", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 0, 0, 14, 84
"/home/yves/Documents/code/go/meow/meowlib/doc/docgen.sh", "Shell Script", 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 1, 4, 18
"/home/yves/Documents/code/go/meow/meowlib/doc/endpoints/company_endpoint.puml", "PlantUML", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 7
"/home/yves/Documents/code/go/meow/meowlib/doc/endpoints/public_endpoint.puml", "PlantUML", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 10
"/home/yves/Documents/code/go/meow/meowlib/doc/general_deployment.puml", "PlantUML", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 3, 22
"/home/yves/Documents/code/go/meow/meowlib/doc/invitation/sq_invitation.puml", "PlantUML", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 7
"/home/yves/Documents/code/go/meow/meowlib/doc/invitation/sq_srvinv01.puml", "PlantUML", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 12
"/home/yves/Documents/code/go/meow/meowlib/doc/invitation/sq_srvinv02.puml", "PlantUML", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 11
"/home/yves/Documents/code/go/meow/meowlib/doc/invitation/sq_srvinv03.puml", "PlantUML", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 1, 12
"/home/yves/Documents/code/go/meow/meowlib/doc/invitation/sq_srvinv04.puml", "PlantUML", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 1, 9
"/home/yves/Documents/code/go/meow/meowlib/doc/meow.svg", "SVG", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2814, 1, 2, 2817
"/home/yves/Documents/code/go/meow/meowlib/doc/meow.tex", "LaTeX", 0, 0, 0, 0, 0, 0, 0, 0, 0, 175, 0, 0, 0, 50, 225
"/home/yves/Documents/code/go/meow/meowlib/doc/messaging/sq_msg01.puml", "PlantUML", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 1, 10
"/home/yves/Documents/code/go/meow/meowlib/doc/messaging/wbs_messages_encapsulation.puml", "PlantUML", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 2, 15
"/home/yves/Documents/code/go/meow/meowlib/doc/protocol.tex", "LaTeX", 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 0, 24, 84
"/home/yves/Documents/code/go/meow/meowlib/doc/server/server_deployment.puml", "PlantUML", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 3, 36
"/home/yves/Documents/code/go/meow/meowlib/doc/server/server_messaging.puml", "PlantUML", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 6, 24
"/home/yves/Documents/code/go/meow/meowlib/doc/server/sq_01_srvmessaging.puml", "PlantUML", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 2, 20
"/home/yves/Documents/code/go/meow/meowlib/doc/server/sq_02_srvmessaging.puml", "PlantUML", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 3, 30
"/home/yves/Documents/code/go/meow/meowlib/doc/usecase01.puml", "PlantUML", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 7, 16
"/home/yves/Documents/code/go/meow/meowlib/doc/usecase02.puml", "PlantUML", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 6, 16
"/home/yves/Documents/code/go/meow/meowlib/doc/usecase03.puml", "PlantUML", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 7, 40
"/home/yves/Documents/code/go/meow/meowlib/endtoend_test.go", "Go", 125, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 18, 198
"/home/yves/Documents/code/go/meow/meowlib/go.mod", "Go Module File", 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 50
"/home/yves/Documents/code/go/meow/meowlib/go.sum", "Go Checksum File", 0, 0, 0, 0, 344, 0, 0, 0, 0, 0, 0, 0, 0, 1, 345
"/home/yves/Documents/code/go/meow/meowlib/http.go", "Go", 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 45
"/home/yves/Documents/code/go/meow/meowlib/lokiwriter.go", "Go", 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 19, 98
"/home/yves/Documents/code/go/meow/meowlib/message.go", "Go", 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 44
"/home/yves/Documents/code/go/meow/meowlib/messages.pb.go", "Go", 2058, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 265, 2368
"/home/yves/Documents/code/go/meow/meowlib/pb/messages.proto", "Protocol Buffers", 0, 0, 0, 0, 0, 0, 0, 194, 0, 0, 0, 0, 0, 40, 234
"/home/yves/Documents/code/go/meow/meowlib/pb/messages.py", "Python", 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 1, 5, 17
"/home/yves/Documents/code/go/meow/meowlib/pb/protogen.bat", "Batch", 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 1, 5
"/home/yves/Documents/code/go/meow/meowlib/pb/protogen.sh", "Shell Script", 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 1, 1, 14
"/home/yves/Documents/code/go/meow/meowlib/proto_test.go", "Go", 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 38
"/home/yves/Documents/code/go/meow/meowlib/server/identity.go", "Go", 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 20, 170
"/home/yves/Documents/code/go/meow/meowlib/server/invitation.go", "Go", 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 8, 71
"/home/yves/Documents/code/go/meow/meowlib/server/logger.go", "Go", 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 13
"/home/yves/Documents/code/go/meow/meowlib/server/router.go", "Go", 271, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 21, 346
"/home/yves/Documents/code/go/meow/meowlib/server/videoserver.go", "Go", 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 42
"/home/yves/Documents/code/go/meow/meowlib/servercard.go", "Go", 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 13
"/home/yves/Documents/code/go/meow/meowlib/symcrypt.go", "Go", 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 7, 69
"/home/yves/Documents/code/go/meow/meowlib/symcrypt_test.go", "Go", 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 22
"Total", "-", 6390, 45, 21, 9, 344, 34, 4, 194, 11, 235, 387, 2814, 836, 1073, 12397
1 filename language Go Go Module File Markdown YAML Go Checksum File Shell Script Batch Protocol Buffers Python LaTeX PlantUML SVG comment blank total
2 /home/yves/Documents/code/go/meow/meowlib/.drone.yml YAML 0 0 0 9 0 0 0 0 0 0 0 0 0 3 12
3 /home/yves/Documents/code/go/meow/meowlib/README.md Markdown 0 0 21 0 0 0 0 0 0 0 0 0 0 8 29
4 /home/yves/Documents/code/go/meow/meowlib/asymcrypt.go Go 237 0 0 0 0 0 0 0 0 0 0 0 36 41 314
5 /home/yves/Documents/code/go/meow/meowlib/asymcrypt_test.go Go 101 0 0 0 0 0 0 0 0 0 0 0 65 17 183
6 /home/yves/Documents/code/go/meow/meowlib/buffer.go Go 62 0 0 0 0 0 0 0 0 0 0 0 0 5 67
7 /home/yves/Documents/code/go/meow/meowlib/buffer_test.go Go 20 0 0 0 0 0 0 0 0 0 0 0 0 5 25
8 /home/yves/Documents/code/go/meow/meowlib/clean.sh Shell Script 0 0 0 0 0 9 0 0 0 0 0 0 1 1 11
9 /home/yves/Documents/code/go/meow/meowlib/client/avatar.go Go 6 0 0 0 0 0 0 0 0 0 0 0 0 3 9
10 /home/yves/Documents/code/go/meow/meowlib/client/config.go Go 99 0 0 0 0 0 0 0 0 0 0 0 7 15 121
11 /home/yves/Documents/code/go/meow/meowlib/client/config_test.go Go 17 0 0 0 0 0 0 0 0 0 0 0 0 4 21
12 /home/yves/Documents/code/go/meow/meowlib/client/dbmessage.go Go 46 0 0 0 0 0 0 0 0 0 0 0 0 6 52
13 /home/yves/Documents/code/go/meow/meowlib/client/helpers/backgroundHelper.go Go 140 0 0 0 0 0 0 0 0 0 0 0 28 23 191
14 /home/yves/Documents/code/go/meow/meowlib/client/helpers/call.go Go 42 0 0 0 0 0 0 0 0 0 0 0 3 11 56
15 /home/yves/Documents/code/go/meow/meowlib/client/helpers/contactHelper.go Go 1 0 0 0 0 0 0 0 0 0 0 0 0 1 2
16 /home/yves/Documents/code/go/meow/meowlib/client/helpers/invitationAnswerHelper.go Go 106 0 0 0 0 0 0 0 0 0 0 0 27 23 156
17 /home/yves/Documents/code/go/meow/meowlib/client/helpers/invitationCheckHelper.go Go 52 0 0 0 0 0 0 0 0 0 0 0 65 10 127
18 /home/yves/Documents/code/go/meow/meowlib/client/helpers/invitationCreateHelper.go Go 77 0 0 0 0 0 0 0 0 0 0 0 50 17 144
19 /home/yves/Documents/code/go/meow/meowlib/client/helpers/invitationFinalizeHelper.go Go 34 0 0 0 0 0 0 0 0 0 0 0 12 8 54
20 /home/yves/Documents/code/go/meow/meowlib/client/helpers/logger.go Go 8 0 0 0 0 0 0 0 0 0 0 0 1 4 13
21 /home/yves/Documents/code/go/meow/meowlib/client/helpers/messageHelper.go Go 66 0 0 0 0 0 0 0 0 0 0 0 9 12 87
22 /home/yves/Documents/code/go/meow/meowlib/client/helpers/networkHelper.go Go 25 0 0 0 0 0 0 0 0 0 0 0 2 4 31
23 /home/yves/Documents/code/go/meow/meowlib/client/helpers/serverHelper.go Go 1 0 0 0 0 0 0 0 0 0 0 0 0 1 2
24 /home/yves/Documents/code/go/meow/meowlib/client/helpers/storageHelper.go Go 13 0 0 0 0 0 0 0 0 0 0 0 0 3 16
25 /home/yves/Documents/code/go/meow/meowlib/client/identity.go Go 254 0 0 0 0 0 0 0 0 0 0 0 81 27 362
26 /home/yves/Documents/code/go/meow/meowlib/client/identity_test.go Go 91 0 0 0 0 0 0 0 0 0 0 0 27 11 129
27 /home/yves/Documents/code/go/meow/meowlib/client/internalusermessage.go Go 41 0 0 0 0 0 0 0 0 0 0 0 5 5 51
28 /home/yves/Documents/code/go/meow/meowlib/client/logger.go Go 8 0 0 0 0 0 0 0 0 0 0 0 1 4 13
29 /home/yves/Documents/code/go/meow/meowlib/client/matriochka.go Go 44 0 0 0 0 0 0 0 0 0 0 0 4 4 52
30 /home/yves/Documents/code/go/meow/meowlib/client/messagestorage.go Go 314 0 0 0 0 0 0 0 0 0 0 0 30 23 367
31 /home/yves/Documents/code/go/meow/meowlib/client/messagestorage_test.go Go 74 0 0 0 0 0 0 0 0 0 0 0 5 5 84
32 /home/yves/Documents/code/go/meow/meowlib/client/peer.go Go 249 0 0 0 0 0 0 0 0 0 0 0 42 35 326
33 /home/yves/Documents/code/go/meow/meowlib/client/peer_test.go Go 26 0 0 0 0 0 0 0 0 0 0 0 0 4 30
34 /home/yves/Documents/code/go/meow/meowlib/client/peerlist.go Go 34 0 0 0 0 0 0 0 0 0 0 0 11 7 52
35 /home/yves/Documents/code/go/meow/meowlib/client/peerstorage.go Go 209 0 0 0 0 0 0 0 0 0 0 0 20 20 249
36 /home/yves/Documents/code/go/meow/meowlib/client/peerstorage_test.go Go 50 0 0 0 0 0 0 0 0 0 0 0 1 10 61
37 /home/yves/Documents/code/go/meow/meowlib/client/server.go Go 249 0 0 0 0 0 0 0 0 0 0 0 33 26 308
38 /home/yves/Documents/code/go/meow/meowlib/client/serverlist.go Go 37 0 0 0 0 0 0 0 0 0 0 0 9 7 53
39 /home/yves/Documents/code/go/meow/meowlib/client/serverstorage.go Go 234 0 0 0 0 0 0 0 0 0 0 0 17 18 269
40 /home/yves/Documents/code/go/meow/meowlib/client/serverstorage_test.go Go 177 0 0 0 0 0 0 0 0 0 0 0 21 27 225
41 /home/yves/Documents/code/go/meow/meowlib/contactcard.go Go 147 0 0 0 0 0 0 0 0 0 0 0 7 24 178
42 /home/yves/Documents/code/go/meow/meowlib/contactcard_test.go Go 61 0 0 0 0 0 0 0 0 0 0 0 0 5 66
43 /home/yves/Documents/code/go/meow/meowlib/crypt.go Go 5 0 0 0 0 0 0 0 0 0 0 0 0 2 7
44 /home/yves/Documents/code/go/meow/meowlib/doc/act_01_send_msg.puml PlantUML 0 0 0 0 0 0 0 0 0 0 21 0 0 1 22
45 /home/yves/Documents/code/go/meow/meowlib/doc/act_02_srv_recv_msg.puml PlantUML 0 0 0 0 0 0 0 0 0 0 21 0 0 1 22
46 /home/yves/Documents/code/go/meow/meowlib/doc/act_03_srv_proc_msg.puml PlantUML 0 0 0 0 0 0 0 0 0 0 20 0 0 0 20
47 /home/yves/Documents/code/go/meow/meowlib/doc/architecture.tex LaTeX 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1
48 /home/yves/Documents/code/go/meow/meowlib/doc/class_messages01.puml PlantUML 0 0 0 0 0 0 0 0 0 0 70 0 0 14 84
49 /home/yves/Documents/code/go/meow/meowlib/doc/docgen.sh Shell Script 0 0 0 0 0 13 0 0 0 0 0 0 1 4 18
50 /home/yves/Documents/code/go/meow/meowlib/doc/endpoints/company_endpoint.puml PlantUML 0 0 0 0 0 0 0 0 0 0 7 0 0 0 7
51 /home/yves/Documents/code/go/meow/meowlib/doc/endpoints/public_endpoint.puml PlantUML 0 0 0 0 0 0 0 0 0 0 10 0 0 0 10
52 /home/yves/Documents/code/go/meow/meowlib/doc/general_deployment.puml PlantUML 0 0 0 0 0 0 0 0 0 0 19 0 0 3 22
53 /home/yves/Documents/code/go/meow/meowlib/doc/invitation/sq_invitation.puml PlantUML 0 0 0 0 0 0 0 0 0 0 7 0 0 0 7
54 /home/yves/Documents/code/go/meow/meowlib/doc/invitation/sq_srvinv01.puml PlantUML 0 0 0 0 0 0 0 0 0 0 12 0 0 0 12
55 /home/yves/Documents/code/go/meow/meowlib/doc/invitation/sq_srvinv02.puml PlantUML 0 0 0 0 0 0 0 0 0 0 11 0 0 0 11
56 /home/yves/Documents/code/go/meow/meowlib/doc/invitation/sq_srvinv03.puml PlantUML 0 0 0 0 0 0 0 0 0 0 11 0 0 1 12
57 /home/yves/Documents/code/go/meow/meowlib/doc/invitation/sq_srvinv04.puml PlantUML 0 0 0 0 0 0 0 0 0 0 8 0 0 1 9
58 /home/yves/Documents/code/go/meow/meowlib/doc/meow.svg SVG 0 0 0 0 0 0 0 0 0 0 0 2814 1 2 2817
59 /home/yves/Documents/code/go/meow/meowlib/doc/meow.tex LaTeX 0 0 0 0 0 0 0 0 0 175 0 0 0 50 225
60 /home/yves/Documents/code/go/meow/meowlib/doc/messaging/sq_msg01.puml PlantUML 0 0 0 0 0 0 0 0 0 0 9 0 0 1 10
61 /home/yves/Documents/code/go/meow/meowlib/doc/messaging/wbs_messages_encapsulation.puml PlantUML 0 0 0 0 0 0 0 0 0 0 13 0 0 2 15
62 /home/yves/Documents/code/go/meow/meowlib/doc/protocol.tex LaTeX 0 0 0 0 0 0 0 0 0 60 0 0 0 24 84
63 /home/yves/Documents/code/go/meow/meowlib/doc/server/server_deployment.puml PlantUML 0 0 0 0 0 0 0 0 0 0 33 0 0 3 36
64 /home/yves/Documents/code/go/meow/meowlib/doc/server/server_messaging.puml PlantUML 0 0 0 0 0 0 0 0 0 0 18 0 0 6 24
65 /home/yves/Documents/code/go/meow/meowlib/doc/server/sq_01_srvmessaging.puml PlantUML 0 0 0 0 0 0 0 0 0 0 18 0 0 2 20
66 /home/yves/Documents/code/go/meow/meowlib/doc/server/sq_02_srvmessaging.puml PlantUML 0 0 0 0 0 0 0 0 0 0 27 0 0 3 30
67 /home/yves/Documents/code/go/meow/meowlib/doc/usecase01.puml PlantUML 0 0 0 0 0 0 0 0 0 0 9 0 0 7 16
68 /home/yves/Documents/code/go/meow/meowlib/doc/usecase02.puml PlantUML 0 0 0 0 0 0 0 0 0 0 10 0 0 6 16
69 /home/yves/Documents/code/go/meow/meowlib/doc/usecase03.puml PlantUML 0 0 0 0 0 0 0 0 0 0 33 0 0 7 40
70 /home/yves/Documents/code/go/meow/meowlib/endtoend_test.go Go 125 0 0 0 0 0 0 0 0 0 0 0 55 18 198
71 /home/yves/Documents/code/go/meow/meowlib/go.mod Go Module File 0 45 0 0 0 0 0 0 0 0 0 0 0 5 50
72 /home/yves/Documents/code/go/meow/meowlib/go.sum Go Checksum File 0 0 0 0 344 0 0 0 0 0 0 0 0 1 345
73 /home/yves/Documents/code/go/meow/meowlib/http.go Go 41 0 0 0 0 0 0 0 0 0 0 0 0 4 45
74 /home/yves/Documents/code/go/meow/meowlib/lokiwriter.go Go 74 0 0 0 0 0 0 0 0 0 0 0 5 19 98
75 /home/yves/Documents/code/go/meow/meowlib/message.go Go 37 0 0 0 0 0 0 0 0 0 0 0 0 7 44
76 /home/yves/Documents/code/go/meow/meowlib/messages.pb.go Go 2058 0 0 0 0 0 0 0 0 0 0 0 45 265 2368
77 /home/yves/Documents/code/go/meow/meowlib/pb/messages.proto Protocol Buffers 0 0 0 0 0 0 0 194 0 0 0 0 0 40 234
78 /home/yves/Documents/code/go/meow/meowlib/pb/messages.py Python 0 0 0 0 0 0 0 0 11 0 0 0 1 5 17
79 /home/yves/Documents/code/go/meow/meowlib/pb/protogen.bat Batch 0 0 0 0 0 0 4 0 0 0 0 0 0 1 5
80 /home/yves/Documents/code/go/meow/meowlib/pb/protogen.sh Shell Script 0 0 0 0 0 12 0 0 0 0 0 0 1 1 14
81 /home/yves/Documents/code/go/meow/meowlib/proto_test.go Go 33 0 0 0 0 0 0 0 0 0 0 0 0 5 38
82 /home/yves/Documents/code/go/meow/meowlib/server/identity.go Go 135 0 0 0 0 0 0 0 0 0 0 0 15 20 170
83 /home/yves/Documents/code/go/meow/meowlib/server/invitation.go Go 62 0 0 0 0 0 0 0 0 0 0 0 1 8 71
84 /home/yves/Documents/code/go/meow/meowlib/server/logger.go Go 8 0 0 0 0 0 0 0 0 0 0 0 1 4 13
85 /home/yves/Documents/code/go/meow/meowlib/server/router.go Go 271 0 0 0 0 0 0 0 0 0 0 0 54 21 346
86 /home/yves/Documents/code/go/meow/meowlib/server/videoserver.go Go 35 0 0 0 0 0 0 0 0 0 0 0 0 7 42
87 /home/yves/Documents/code/go/meow/meowlib/servercard.go Go 10 0 0 0 0 0 0 0 0 0 0 0 0 3 13
88 /home/yves/Documents/code/go/meow/meowlib/symcrypt.go Go 26 0 0 0 0 0 0 0 0 0 0 0 36 7 69
89 /home/yves/Documents/code/go/meow/meowlib/symcrypt_test.go Go 18 0 0 0 0 0 0 0 0 0 0 0 0 4 22
90 Total - 6390 45 21 9 344 34 4 194 11 235 387 2814 836 1073 12397

View File

@ -0,0 +1,44 @@
# Summary
Date : 2024-08-27 08:23:38
Directory /home/yves/Documents/code/go/meow/meowlib
Total : 88 files, 10488 codes, 836 comments, 1073 blanks, all 12397 lines
Summary / [Details](details.md) / [Diff Summary](diff.md) / [Diff Details](diff-details.md)
## Languages
| language | files | code | comment | blank | total |
| :--- | ---: | ---: | ---: | ---: | ---: |
| Go | 53 | 6,390 | 831 | 869 | 8,090 |
| SVG | 1 | 2,814 | 1 | 2 | 2,817 |
| PlantUML | 21 | 387 | 0 | 58 | 445 |
| Go Checksum File | 1 | 344 | 0 | 1 | 345 |
| LaTeX | 3 | 235 | 0 | 75 | 310 |
| Protocol Buffers | 1 | 194 | 0 | 40 | 234 |
| Go Module File | 1 | 45 | 0 | 5 | 50 |
| Shell Script | 3 | 34 | 3 | 6 | 43 |
| Markdown | 1 | 21 | 0 | 8 | 29 |
| Python | 1 | 11 | 1 | 5 | 17 |
| YAML | 1 | 9 | 0 | 3 | 12 |
| Batch | 1 | 4 | 0 | 1 | 5 |
## Directories
| path | files | code | comment | blank | total |
| :--- | ---: | ---: | ---: | ---: | ---: |
| . | 88 | 10,488 | 836 | 1,073 | 12,397 |
| . (Files) | 21 | 3,483 | 250 | 449 | 4,182 |
| client | 32 | 2,824 | 511 | 378 | 3,713 |
| client (Files) | 20 | 2,259 | 314 | 261 | 2,834 |
| client/helpers | 12 | 565 | 197 | 117 | 879 |
| doc | 26 | 3,449 | 2 | 139 | 3,590 |
| doc (Files) | 13 | 3,265 | 2 | 120 | 3,387 |
| doc/endpoints | 2 | 17 | 0 | 0 | 17 |
| doc/invitation | 5 | 49 | 0 | 2 | 51 |
| doc/messaging | 2 | 22 | 0 | 3 | 25 |
| doc/server | 4 | 96 | 0 | 14 | 110 |
| pb | 4 | 221 | 2 | 47 | 270 |
| server | 5 | 511 | 71 | 60 | 642 |
Summary / [Details](details.md) / [Diff Summary](diff.md) / [Diff Details](diff-details.md)

View File

@ -0,0 +1,135 @@
Date : 2024-08-27 08:23:38
Directory : /home/yves/Documents/code/go/meow/meowlib
Total : 88 files, 10488 codes, 836 comments, 1073 blanks, all 12397 lines
Languages
+------------------+------------+------------+------------+------------+------------+
| language | files | code | comment | blank | total |
+------------------+------------+------------+------------+------------+------------+
| Go | 53 | 6,390 | 831 | 869 | 8,090 |
| SVG | 1 | 2,814 | 1 | 2 | 2,817 |
| PlantUML | 21 | 387 | 0 | 58 | 445 |
| Go Checksum File | 1 | 344 | 0 | 1 | 345 |
| LaTeX | 3 | 235 | 0 | 75 | 310 |
| Protocol Buffers | 1 | 194 | 0 | 40 | 234 |
| Go Module File | 1 | 45 | 0 | 5 | 50 |
| Shell Script | 3 | 34 | 3 | 6 | 43 |
| Markdown | 1 | 21 | 0 | 8 | 29 |
| Python | 1 | 11 | 1 | 5 | 17 |
| YAML | 1 | 9 | 0 | 3 | 12 |
| Batch | 1 | 4 | 0 | 1 | 5 |
+------------------+------------+------------+------------+------------+------------+
Directories
+-----------------------------------------------------------------------------------------+------------+------------+------------+------------+------------+
| path | files | code | comment | blank | total |
+-----------------------------------------------------------------------------------------+------------+------------+------------+------------+------------+
| . | 88 | 10,488 | 836 | 1,073 | 12,397 |
| . (Files) | 21 | 3,483 | 250 | 449 | 4,182 |
| client | 32 | 2,824 | 511 | 378 | 3,713 |
| client (Files) | 20 | 2,259 | 314 | 261 | 2,834 |
| client/helpers | 12 | 565 | 197 | 117 | 879 |
| doc | 26 | 3,449 | 2 | 139 | 3,590 |
| doc (Files) | 13 | 3,265 | 2 | 120 | 3,387 |
| doc/endpoints | 2 | 17 | 0 | 0 | 17 |
| doc/invitation | 5 | 49 | 0 | 2 | 51 |
| doc/messaging | 2 | 22 | 0 | 3 | 25 |
| doc/server | 4 | 96 | 0 | 14 | 110 |
| pb | 4 | 221 | 2 | 47 | 270 |
| server | 5 | 511 | 71 | 60 | 642 |
+-----------------------------------------------------------------------------------------+------------+------------+------------+------------+------------+
Files
+-----------------------------------------------------------------------------------------+------------------+------------+------------+------------+------------+
| filename | language | code | comment | blank | total |
+-----------------------------------------------------------------------------------------+------------------+------------+------------+------------+------------+
| /home/yves/Documents/code/go/meow/meowlib/.drone.yml | YAML | 9 | 0 | 3 | 12 |
| /home/yves/Documents/code/go/meow/meowlib/README.md | Markdown | 21 | 0 | 8 | 29 |
| /home/yves/Documents/code/go/meow/meowlib/asymcrypt.go | Go | 237 | 36 | 41 | 314 |
| /home/yves/Documents/code/go/meow/meowlib/asymcrypt_test.go | Go | 101 | 65 | 17 | 183 |
| /home/yves/Documents/code/go/meow/meowlib/buffer.go | Go | 62 | 0 | 5 | 67 |
| /home/yves/Documents/code/go/meow/meowlib/buffer_test.go | Go | 20 | 0 | 5 | 25 |
| /home/yves/Documents/code/go/meow/meowlib/clean.sh | Shell Script | 9 | 1 | 1 | 11 |
| /home/yves/Documents/code/go/meow/meowlib/client/avatar.go | Go | 6 | 0 | 3 | 9 |
| /home/yves/Documents/code/go/meow/meowlib/client/config.go | Go | 99 | 7 | 15 | 121 |
| /home/yves/Documents/code/go/meow/meowlib/client/config_test.go | Go | 17 | 0 | 4 | 21 |
| /home/yves/Documents/code/go/meow/meowlib/client/dbmessage.go | Go | 46 | 0 | 6 | 52 |
| /home/yves/Documents/code/go/meow/meowlib/client/helpers/backgroundHelper.go | Go | 140 | 28 | 23 | 191 |
| /home/yves/Documents/code/go/meow/meowlib/client/helpers/call.go | Go | 42 | 3 | 11 | 56 |
| /home/yves/Documents/code/go/meow/meowlib/client/helpers/contactHelper.go | Go | 1 | 0 | 1 | 2 |
| /home/yves/Documents/code/go/meow/meowlib/client/helpers/invitationAnswerHelper.go | Go | 106 | 27 | 23 | 156 |
| /home/yves/Documents/code/go/meow/meowlib/client/helpers/invitationCheckHelper.go | Go | 52 | 65 | 10 | 127 |
| /home/yves/Documents/code/go/meow/meowlib/client/helpers/invitationCreateHelper.go | Go | 77 | 50 | 17 | 144 |
| /home/yves/Documents/code/go/meow/meowlib/client/helpers/invitationFinalizeHelper.go | Go | 34 | 12 | 8 | 54 |
| /home/yves/Documents/code/go/meow/meowlib/client/helpers/logger.go | Go | 8 | 1 | 4 | 13 |
| /home/yves/Documents/code/go/meow/meowlib/client/helpers/messageHelper.go | Go | 66 | 9 | 12 | 87 |
| /home/yves/Documents/code/go/meow/meowlib/client/helpers/networkHelper.go | Go | 25 | 2 | 4 | 31 |
| /home/yves/Documents/code/go/meow/meowlib/client/helpers/serverHelper.go | Go | 1 | 0 | 1 | 2 |
| /home/yves/Documents/code/go/meow/meowlib/client/helpers/storageHelper.go | Go | 13 | 0 | 3 | 16 |
| /home/yves/Documents/code/go/meow/meowlib/client/identity.go | Go | 254 | 81 | 27 | 362 |
| /home/yves/Documents/code/go/meow/meowlib/client/identity_test.go | Go | 91 | 27 | 11 | 129 |
| /home/yves/Documents/code/go/meow/meowlib/client/internalusermessage.go | Go | 41 | 5 | 5 | 51 |
| /home/yves/Documents/code/go/meow/meowlib/client/logger.go | Go | 8 | 1 | 4 | 13 |
| /home/yves/Documents/code/go/meow/meowlib/client/matriochka.go | Go | 44 | 4 | 4 | 52 |
| /home/yves/Documents/code/go/meow/meowlib/client/messagestorage.go | Go | 314 | 30 | 23 | 367 |
| /home/yves/Documents/code/go/meow/meowlib/client/messagestorage_test.go | Go | 74 | 5 | 5 | 84 |
| /home/yves/Documents/code/go/meow/meowlib/client/peer.go | Go | 249 | 42 | 35 | 326 |
| /home/yves/Documents/code/go/meow/meowlib/client/peer_test.go | Go | 26 | 0 | 4 | 30 |
| /home/yves/Documents/code/go/meow/meowlib/client/peerlist.go | Go | 34 | 11 | 7 | 52 |
| /home/yves/Documents/code/go/meow/meowlib/client/peerstorage.go | Go | 209 | 20 | 20 | 249 |
| /home/yves/Documents/code/go/meow/meowlib/client/peerstorage_test.go | Go | 50 | 1 | 10 | 61 |
| /home/yves/Documents/code/go/meow/meowlib/client/server.go | Go | 249 | 33 | 26 | 308 |
| /home/yves/Documents/code/go/meow/meowlib/client/serverlist.go | Go | 37 | 9 | 7 | 53 |
| /home/yves/Documents/code/go/meow/meowlib/client/serverstorage.go | Go | 234 | 17 | 18 | 269 |
| /home/yves/Documents/code/go/meow/meowlib/client/serverstorage_test.go | Go | 177 | 21 | 27 | 225 |
| /home/yves/Documents/code/go/meow/meowlib/contactcard.go | Go | 147 | 7 | 24 | 178 |
| /home/yves/Documents/code/go/meow/meowlib/contactcard_test.go | Go | 61 | 0 | 5 | 66 |
| /home/yves/Documents/code/go/meow/meowlib/crypt.go | Go | 5 | 0 | 2 | 7 |
| /home/yves/Documents/code/go/meow/meowlib/doc/act_01_send_msg.puml | PlantUML | 21 | 0 | 1 | 22 |
| /home/yves/Documents/code/go/meow/meowlib/doc/act_02_srv_recv_msg.puml | PlantUML | 21 | 0 | 1 | 22 |
| /home/yves/Documents/code/go/meow/meowlib/doc/act_03_srv_proc_msg.puml | PlantUML | 20 | 0 | 0 | 20 |
| /home/yves/Documents/code/go/meow/meowlib/doc/architecture.tex | LaTeX | 0 | 0 | 1 | 1 |
| /home/yves/Documents/code/go/meow/meowlib/doc/class_messages01.puml | PlantUML | 70 | 0 | 14 | 84 |
| /home/yves/Documents/code/go/meow/meowlib/doc/docgen.sh | Shell Script | 13 | 1 | 4 | 18 |
| /home/yves/Documents/code/go/meow/meowlib/doc/endpoints/company_endpoint.puml | PlantUML | 7 | 0 | 0 | 7 |
| /home/yves/Documents/code/go/meow/meowlib/doc/endpoints/public_endpoint.puml | PlantUML | 10 | 0 | 0 | 10 |
| /home/yves/Documents/code/go/meow/meowlib/doc/general_deployment.puml | PlantUML | 19 | 0 | 3 | 22 |
| /home/yves/Documents/code/go/meow/meowlib/doc/invitation/sq_invitation.puml | PlantUML | 7 | 0 | 0 | 7 |
| /home/yves/Documents/code/go/meow/meowlib/doc/invitation/sq_srvinv01.puml | PlantUML | 12 | 0 | 0 | 12 |
| /home/yves/Documents/code/go/meow/meowlib/doc/invitation/sq_srvinv02.puml | PlantUML | 11 | 0 | 0 | 11 |
| /home/yves/Documents/code/go/meow/meowlib/doc/invitation/sq_srvinv03.puml | PlantUML | 11 | 0 | 1 | 12 |
| /home/yves/Documents/code/go/meow/meowlib/doc/invitation/sq_srvinv04.puml | PlantUML | 8 | 0 | 1 | 9 |
| /home/yves/Documents/code/go/meow/meowlib/doc/meow.svg | SVG | 2,814 | 1 | 2 | 2,817 |
| /home/yves/Documents/code/go/meow/meowlib/doc/meow.tex | LaTeX | 175 | 0 | 50 | 225 |
| /home/yves/Documents/code/go/meow/meowlib/doc/messaging/sq_msg01.puml | PlantUML | 9 | 0 | 1 | 10 |
| /home/yves/Documents/code/go/meow/meowlib/doc/messaging/wbs_messages_encapsulation.puml | PlantUML | 13 | 0 | 2 | 15 |
| /home/yves/Documents/code/go/meow/meowlib/doc/protocol.tex | LaTeX | 60 | 0 | 24 | 84 |
| /home/yves/Documents/code/go/meow/meowlib/doc/server/server_deployment.puml | PlantUML | 33 | 0 | 3 | 36 |
| /home/yves/Documents/code/go/meow/meowlib/doc/server/server_messaging.puml | PlantUML | 18 | 0 | 6 | 24 |
| /home/yves/Documents/code/go/meow/meowlib/doc/server/sq_01_srvmessaging.puml | PlantUML | 18 | 0 | 2 | 20 |
| /home/yves/Documents/code/go/meow/meowlib/doc/server/sq_02_srvmessaging.puml | PlantUML | 27 | 0 | 3 | 30 |
| /home/yves/Documents/code/go/meow/meowlib/doc/usecase01.puml | PlantUML | 9 | 0 | 7 | 16 |
| /home/yves/Documents/code/go/meow/meowlib/doc/usecase02.puml | PlantUML | 10 | 0 | 6 | 16 |
| /home/yves/Documents/code/go/meow/meowlib/doc/usecase03.puml | PlantUML | 33 | 0 | 7 | 40 |
| /home/yves/Documents/code/go/meow/meowlib/endtoend_test.go | Go | 125 | 55 | 18 | 198 |
| /home/yves/Documents/code/go/meow/meowlib/go.mod | Go Module File | 45 | 0 | 5 | 50 |
| /home/yves/Documents/code/go/meow/meowlib/go.sum | Go Checksum File | 344 | 0 | 1 | 345 |
| /home/yves/Documents/code/go/meow/meowlib/http.go | Go | 41 | 0 | 4 | 45 |
| /home/yves/Documents/code/go/meow/meowlib/lokiwriter.go | Go | 74 | 5 | 19 | 98 |
| /home/yves/Documents/code/go/meow/meowlib/message.go | Go | 37 | 0 | 7 | 44 |
| /home/yves/Documents/code/go/meow/meowlib/messages.pb.go | Go | 2,058 | 45 | 265 | 2,368 |
| /home/yves/Documents/code/go/meow/meowlib/pb/messages.proto | Protocol Buffers | 194 | 0 | 40 | 234 |
| /home/yves/Documents/code/go/meow/meowlib/pb/messages.py | Python | 11 | 1 | 5 | 17 |
| /home/yves/Documents/code/go/meow/meowlib/pb/protogen.bat | Batch | 4 | 0 | 1 | 5 |
| /home/yves/Documents/code/go/meow/meowlib/pb/protogen.sh | Shell Script | 12 | 1 | 1 | 14 |
| /home/yves/Documents/code/go/meow/meowlib/proto_test.go | Go | 33 | 0 | 5 | 38 |
| /home/yves/Documents/code/go/meow/meowlib/server/identity.go | Go | 135 | 15 | 20 | 170 |
| /home/yves/Documents/code/go/meow/meowlib/server/invitation.go | Go | 62 | 1 | 8 | 71 |
| /home/yves/Documents/code/go/meow/meowlib/server/logger.go | Go | 8 | 1 | 4 | 13 |
| /home/yves/Documents/code/go/meow/meowlib/server/router.go | Go | 271 | 54 | 21 | 346 |
| /home/yves/Documents/code/go/meow/meowlib/server/videoserver.go | Go | 35 | 0 | 7 | 42 |
| /home/yves/Documents/code/go/meow/meowlib/servercard.go | Go | 10 | 0 | 3 | 13 |
| /home/yves/Documents/code/go/meow/meowlib/symcrypt.go | Go | 26 | 36 | 7 | 69 |
| /home/yves/Documents/code/go/meow/meowlib/symcrypt_test.go | Go | 18 | 0 | 4 | 22 |
| Total | | 10,488 | 836 | 1,073 | 12,397 |
+-----------------------------------------------------------------------------------------+------------------+------------+------------+------------+------------+

8
client/avatar.go Normal file
View File

@ -0,0 +1,8 @@
package client
import "time"
type Avatar struct {
File string
Date time.Time
}

View File

@ -18,9 +18,12 @@ type Config struct {
MaxIdsPerUser int `json:"max_ids_per_user,omitempty"`
MsgDbRollingPeriod int `json:"msg_db_rolling_period,omitempty"`
Chunksize int64 `json:"chunksize,omitempty"`
ServerPollInterval int `json:"server_poll_interval,omitempty"`
DbSize int `json:"db_size,omitempty"`
UserAgent string `json:"user_agent,omitempty"`
// Network
ServerPollInterval int `json:"server_poll_interval,omitempty"`
HttpTimeOut int `json:"http_timeout,omitempty"`
HttpLongPoll int `json:"http_long_poll,omitempty"`
// GUI
LastOpenChat string `json:"last_open_chat,omitempty"`
SoundNotificationEnable bool `json:"sound_notification_enable,omitempty"`
@ -68,6 +71,15 @@ func (c *Config) Load(filename string) error {
if err != nil {
return err
}
// override values if not set or wrong
if c.HttpTimeOut <= 0 {
c.HttpTimeOut = 10
c.Save(filename)
}
if c.HttpLongPoll <= 1 {
c.HttpLongPoll = 300
c.Save(filename)
}
return nil
}

View File

@ -14,7 +14,7 @@ func DbMessageToInternalUserMessage(id int64, dbFile string, dbm *meowlib.DbMess
ium.Outbound = false
}
ium.Message = string(dbm.Data)
ium.ConversationStatus = dbm.Status
ium.Status = dbm.Status
ium.Contact = dbm.Contact
ium.CurrentLocation = dbm.CurrentLocation
ium.Messagetype = dbm.Type
@ -23,6 +23,19 @@ func DbMessageToInternalUserMessage(id int64, dbFile string, dbm *meowlib.DbMess
return &ium
}
func InternalUserMessageToDbMessage(ium *InternalUserMessage) *meowlib.DbMessage {
var dbm meowlib.DbMessage
dbm.Outbound = ium.Outbound
dbm.Type = ium.Messagetype
dbm.Data = []byte(ium.Message)
dbm.Appdata = ium.Appdata
dbm.Contact = ium.Contact
dbm.CurrentLocation = ium.CurrentLocation
dbm.Status = ium.Status
dbm.FilePaths = ium.FilePaths
return &dbm
}
func UserMessageToDbMessage(outbound bool, um *meowlib.UserMessage, filepaths []string) *meowlib.DbMessage {
var dbm meowlib.DbMessage
dbm.Outbound = outbound

View File

@ -6,6 +6,7 @@ import (
"os"
"path/filepath"
"strconv"
"sync"
"time"
"forge.redroom.link/yves/meowlib"
@ -27,7 +28,7 @@ type ReceivedMessage struct {
}
// CheckForMessages checks for messages on a single server
func CheckForMessages(storage_path string, job *client.RequestsJob) (int, string, error) {
func CheckForMessages(storage_path string, job *client.RequestsJob, timeout int, longPoll bool) (int, string, error) {
count := 0
@ -63,12 +64,17 @@ func CheckForMessages(storage_path string, job *client.RequestsJob) (int, string
var toSrv meowlib.ToServerMessage
toSrv.PullRequest = crl
toSrv.From = job.Server.UserKp.Public
if longPoll {
toSrv.Timeout = int64(timeout)
}
data, err := job.Server.ProcessOutboundMessage(&toSrv)
if err != nil {
return -1, "CheckMessages: ProcessOutboundMessage", err
}
response, err := meowlib.HttpPostMessage(job.Server.Url, data)
response, err := meowlib.HttpPostMessage(job.Server.Url, data, timeout)
if err != nil {
return -1, "CheckMessages: httpPostMessage", err
}
@ -183,3 +189,53 @@ func ReadMessage(messageFilename string) ([]string, []string, string, error) {
// list of messages & detached files
return messagesOverview, filenames, "", nil
}
// CheckForMessages checks for messages on a single server
func LongPollForMessages(storage_path string, jobs []client.RequestsJob, timeout int, longPoll bool) (int, string, error) {
// Channel to collect results
resultChan := make(chan int, len(jobs))
errChan := make(chan error, len(jobs))
// WaitGroup to sync goroutines
var wg sync.WaitGroup
// Loop through each job (server)
for _, job := range jobs {
wg.Add(1)
go func(job client.RequestsJob) {
defer wg.Done()
// Long-polling call to the server
cnt, _, err := CheckForMessages(storage_path, &job, timeout, true)
if err == nil && cnt > 0 {
select {
case resultChan <- cnt:
default:
}
// Close the error channel to notify all goroutines
close(errChan)
}
}(job)
}
// Close the result channel when all workers are done
go func() {
wg.Wait()
close(resultChan)
}()
// Wait for the first message or all timeouts
select {
case cnt := <-resultChan:
return cnt, "", nil
case <-errChan:
// If one fails and exitOnMessage is true
return 0, "", nil
}
}

55
client/helpers/call.go Normal file
View File

@ -0,0 +1,55 @@
package helpers
import (
"forge.redroom.link/yves/meowlib"
"forge.redroom.link/yves/meowlib/client"
)
func BuildCallRequestMessage(users []string, expiry uint64, srvuid string) ([]byte, string, error) {
// Server: get the invitation server
server, err := client.GetConfig().GetIdentity().MessageServers.LoadServer(srvuid)
if err != nil {
return nil, "BuildCallRequestMessage: LoadServer", err
}
toSrvMsg, err := server.BuildVideoRoomRequestMessage(users, expiry)
if err != nil {
return nil, "BuildCallRequestMessage: BuildVideoRoomRequestMessage", err
}
msg, err := server.ProcessOutboundMessage(toSrvMsg)
if err != nil {
return nil, "BuildCallRequestMessage: ProcessOutboundMessage", err
}
return msg, "", nil
}
func ReadCallRequestResponseMessage(data []byte, srvuid string) (*meowlib.VideoData, string, error) {
server, err := client.GetConfig().GetIdentity().MessageServers.LoadServer(srvuid)
if err != nil {
return nil, "ReadCallRequestResponseMessage: LoadServer", err
}
// Server inbound processing : get the invitation server
serverMsg, err := server.ProcessInboundServerResponse(data)
if err != nil {
return nil, "ReadCallRequestResponseMessage: ProcessInboundServerResponse", err
}
return serverMsg.VideoData, "", nil
}
func BuildCallMessage(videodata *meowlib.VideoData, srvuid string, peer_uid string, replyToUid string, filelist []string) ([]byte, string, error) {
peer := client.GetConfig().GetIdentity().Peers.GetFromUid(peer_uid)
// Creating User message
usermessage, err := peer.BuildSimpleUserMessage(nil)
if err != nil {
return nil, "BuildCallMessage : BuildSimpleUserMessage", err
}
usermessage.Status.AnswerToUuid = replyToUid
return messageBuildPostprocess(usermessage, srvuid, peer)
}
func BuildCancelCallMessage() {
}

View File

@ -91,14 +91,16 @@ func InvitationAnswerFile(invitationFile string, nickname string, myNickname str
func InvitationAnswerMessage(invitationId string, invitationServerUid string, timeout int) ([]byte, string, error) {
// find the peer with that invitation id
var peer *client.Peer
/*var peer *client.Peer
for i := len(client.GetConfig().GetIdentity().Peers) - 1; i >= 0; i-- { //! to allow self invitation : testing only, findinc the received peer before myself
// for i := 0; i < len(client.GetConfig().GetIdentity().Peers); i++ {
if client.GetConfig().GetIdentity().Peers[i].InvitationId == invitationId {
peer = client.GetConfig().GetIdentity().Peers[i]
break
}
}
}*/
peer := client.GetConfig().GetIdentity().Peers.GetFromInvitationId(invitationId)
if peer == nil {
// declare a custom go error for no peer found
return nil, "InvitationAnswerMessage: loop for peer", errors.New("no peer with that invitation id")

View File

@ -61,23 +61,21 @@ func InvitationCheck(invitationdata []byte) *C.char {
// invitationPassword: the password of the invitation
func InvitationGetMessage(invitationUrl string, serverPublicKey string, invitationPassword string) ([]byte, string, error) {
meowurl := strings.Split(invitationUrl[7:], "?")
meowurl := strings.Split(invitationUrl, "?")
serverurl := meowurl[0]
shortcode := meowurl[1]
srv := client.Server{}
srv := client.CreateServerFromMeowUrl(meowurl[0])
// check if already in msg servers
dbsrv, err := client.GetConfig().GetIdentity().MessageServers.LoadServer(serverurl)
dbsrv, err := client.GetConfig().GetIdentity().MessageServers.LoadServer(srv.Url)
if err != nil {
return nil, "InvitationGetMessage: LoadServer", err
}
if dbsrv == nil {
// create a server object with url & pubkey
srv.Url = serverurl
srv.PublicKey = serverPublicKey
srv.UserKp = meowlib.NewKeyPair()
// save it
err = client.GetConfig().GetIdentity().MessageServers.StoreServer(&srv)
err = client.GetConfig().GetIdentity().MessageServers.StoreServer(srv)
if err != nil {
return nil, "InvitationGetMessage: StoreServer", err
}
@ -85,7 +83,7 @@ func InvitationGetMessage(invitationUrl string, serverPublicKey string, invitati
if dbsrv.PublicKey != serverPublicKey {
dbsrv.PublicKey = serverPublicKey
}
srv = *dbsrv
srv = dbsrv
}
// buildserver message
toSrvMsg, err := srv.BuildToServerMessageInvitationRequest(shortcode, invitationPassword)

View File

@ -73,12 +73,14 @@ func InvitationCreateMessage(invitationId string, invitationServerUid string, ti
// lookup for peer with "invitation_id"
var myContact *meowlib.ContactCard
for i := 0; i < len(client.GetConfig().GetIdentity().Peers); i++ {
/* for i := 0; i < len(client.GetConfig().GetIdentity().Peers); i++ {
if client.GetConfig().GetIdentity().Peers[i].InvitationId == invitationId {
myContact = client.GetConfig().GetIdentity().Peers[i].GetMyContact()
break
}
}
}*/
peer := client.GetConfig().GetIdentity().Peers.GetFromInvitationId(invitationId)
myContact = peer.GetMyContact()
// todo handle not found !!
// lookup for message server with "invitation_server"
invitationServer, err := client.GetConfig().GetIdentity().MessageServers.LoadServer(invitationServerUid) //.GetServerByIdx(int(jsoninv["invitation_server"].(float64)))
@ -122,14 +124,20 @@ func InvitationCreateReadResponse(invitationServerUid string, invitationResponse
// invitationId: the invitation id of the peer
// url: the url of the invitation we got from the server
func InvitationSetUrlInfo(invitationId string, url string, expiry int64) {
id := client.GetConfig().GetIdentity()
// lookup for peer with "invitation_id"
peer := id.Peers.GetFromInvitationId(invitationId)
peer.InvitationUrl = url
peer.InvitationExpiry = time.Unix(expiry, 0)
id.Peers.StorePeer(peer)
for i := 0; i < len(client.GetConfig().GetIdentity().Peers); i++ {
if client.GetConfig().GetIdentity().Peers[i].InvitationId == invitationId {
client.GetConfig().GetIdentity().Peers[i].InvitationUrl = url
client.GetConfig().GetIdentity().Peers[i].InvitationExpiry = time.Unix(expiry, 0)
break
/* for i := 0; i < len(client.GetConfig().GetIdentity().Peers); i++ {
if client.GetConfig().GetIdentity().Peers[i].InvitationId == invitationId {
client.GetConfig().GetIdentity().Peers[i].InvitationUrl = url
client.GetConfig().GetIdentity().Peers[i].InvitationExpiry = time.Unix(expiry, 0)
break
}
}
}
client.GetConfig().GetIdentity().Save()
client.GetConfig().GetIdentity().Save()*/
}

12
client/helpers/logger.go Normal file
View File

@ -0,0 +1,12 @@
package helpers
import (
"github.com/rs/zerolog"
)
var logger zerolog.Logger
// AddLogger sets the logger for the sublibrary
func AddLogger(l zerolog.Logger) {
logger = l
}

View File

@ -1,14 +1,39 @@
package helpers
import "forge.redroom.link/yves/meowlib/client"
import (
"forge.redroom.link/yves/meowlib"
"forge.redroom.link/yves/meowlib/client"
)
func PrepareUserMessage(message string, srvuid string, peer_idx int, filelist []string) ([]byte, string, error) {
peer := client.GetConfig().GetIdentity().Peers[peer_idx]
func messageBuildPostprocess(msg *meowlib.UserMessage, srvuid string, peer *client.Peer) ([]byte, string, error) {
// Get the message server
srv, err := client.GetConfig().GetIdentity().MessageServers.LoadServer(srvuid)
if err != nil {
return nil, "PrepareServerMessage : LoadServer", err
return nil, "messageBuildPostprocess : LoadServer", err
}
// Prepare cyphered + packed user message
packedMsg, err := peer.ProcessOutboundUserMessage(msg)
if err != nil {
return nil, "messageBuildPostprocess : ProcessOutboundUserMessage", err
}
// Creating Server message for transporting the user message
toServerMessage := srv.BuildToServerMessageFromUserMessage(packedMsg)
data, err := srv.ProcessOutboundMessage(toServerMessage)
if err != nil {
return nil, "messageBuildPostprocess : ProcessOutboundMessage", err
}
// Store message
err = peer.StoreMessage(msg, nil)
if err != nil {
return nil, "messageBuildPostprocess : StoreMessage", err
}
return data, "", nil
}
func PrepareUserMessage(message string, srvuid string, peer_uid string, replyToUid string, filelist []string) ([]byte, string, error) {
peer := client.GetConfig().GetIdentity().Peers.GetFromUid(peer_uid)
// Creating User message
usermessage, err := peer.BuildSimpleUserMessage([]byte(message))
if err != nil {
@ -20,6 +45,27 @@ func PrepareUserMessage(message string, srvuid string, peer_idx int, filelist []
return nil, "PrepareServerMessage : AddFile", err
}
}
usermessage.Status.AnswerToUuid = replyToUid
return messageBuildPostprocess(usermessage, srvuid, peer)
}
func BuildAckMessage(messageUid string, srvuid string, peer_uid string, received int64, processed int64) ([]byte, string, error) {
peer := client.GetConfig().GetIdentity().Peers.GetFromUid(peer_uid)
srv, err := client.GetConfig().GetIdentity().MessageServers.LoadServer(srvuid)
if err != nil {
return nil, "PrepareServerMessage : LoadServer", err
}
// Creating User message
usermessage, err := peer.BuildSimpleUserMessage(nil)
if err != nil {
return nil, "PrepareServerMessage : BuildSimpleUserMessage", err
}
usermessage.Status.Uuid = messageUid
usermessage.Status.Received = uint64(received)
usermessage.Status.Processed = uint64(processed)
// Prepare cyphered + packed user message
packedMsg, err := peer.ProcessOutboundUserMessage(usermessage)
if err != nil {
@ -31,10 +77,10 @@ func PrepareUserMessage(message string, srvuid string, peer_idx int, filelist []
if err != nil {
return nil, "PrepareServerMessage : ProcessOutboundMessage", err
}
// Store message
err = peer.StoreMessage(usermessage, filelist)
if err != nil {
return nil, "PrepareServerMessage : StoreMessage", err
}
return data, "", nil
}
func ReadAckMessageResponse() {
//! update the status in message store
}

View File

@ -5,7 +5,7 @@ import (
"forge.redroom.link/yves/meowlib/client"
)
func HttpSendMessage(serverUid string, message []byte) ([]byte, error) {
func HttpSendMessage(serverUid string, message []byte, timeout int) ([]byte, error) {
id := client.GetConfig().GetIdentity()
srv, err := id.MessageServers.LoadServer(serverUid)
if err != nil {
@ -22,7 +22,7 @@ func HttpSendMessage(serverUid string, message []byte) ([]byte, error) {
id.MessageServers.StoreServer(srv)
}
response, err := meowlib.HttpPostMessage(srv.Url, message)
response, err := meowlib.HttpPostMessage(srv.Url, message, timeout)
if err != nil {
return nil, err
}

View File

@ -4,9 +4,9 @@ import (
"forge.redroom.link/yves/meowlib/client"
)
func LoadMessagesHistory(peer_id int) ([]client.InternalUserMessage, string, error) {
func LoadMessagesHistory(peer_uid string) ([]client.InternalUserMessage, string, error) {
id := client.GetConfig().GetIdentity()
peer := id.Peers[peer_id]
peer := id.Peers.GetFromUid(peer_uid)
msgs, err := peer.LoadMessagesHistory(0, 0, 50)
if err != nil {
return nil, "LoadLastMessages: LoadMessagesHistory", err

View File

@ -18,10 +18,12 @@ const maxHiddenCount = 30
type Identity struct {
Nickname string `json:"nickname,omitempty"`
DefaultAvatar string `json:"default_avatar,omitempty"`
Avatars []Avatar `json:"avatars,omitempty"`
RootKp meowlib.KeyPair `json:"id_kp,omitempty"`
Status string `json:"status,omitempty"`
Peers PeerList `json:"peers,omitempty"`
Peers PeerStorage `json:"peers,omitempty"`
HiddenPeers [][]byte `json:"hidden_peers,omitempty"`
Personae PeerList `json:"faces,omitempty"`
Device meowlib.KeyPair `json:"device,omitempty"`
KnownServers ServerList `json:"known_servers,omitempty"`
MessageServers ServerStorage `json:"message_servers,omitempty"`
@ -94,7 +96,7 @@ func (id *Identity) InvitePeer(MyName string, ContactName string, MessageServerU
peer.MyPullServers = MessageServerUids
peer.MyName = MyName
peer.InvitationMessage = InvitationMessage
id.Peers = append(id.Peers, &peer)
id.Peers.StorePeer(&peer)
return &peer, nil
}
@ -102,14 +104,15 @@ func (id *Identity) InvitePeer(MyName string, ContactName string, MessageServerU
// Checks if the received contact card is an answer to an invitation, returns true if it is, and the proposed and received nicknames
func (id *Identity) CheckInvitation(ReceivedContact *meowlib.ContactCard) (isAnswer bool, proposedNick string, receivedNick string, invitationMessage string) {
// invitation Id found, this is an answer to an invitation
for _, p := range id.Peers {
/*for _, p := range id.Peers {
if p.InvitationId == ReceivedContact.InvitationId {
return true, p.Name, ReceivedContact.Name, ReceivedContact.InvitationMessage
}
}
// it's an invitation
return false, "", ReceivedContact.Name, ReceivedContact.InvitationMessage
return false, "", ReceivedContact.Name, ReceivedContact.InvitationMessage*/
return id.Peers.CheckInvitation(ReceivedContact)
}
// Answers an invitation, returns the newly created peer including infos to provide a ContactCard
@ -132,6 +135,7 @@ func (id *Identity) AnswerInvitation(MyName string, ContactName string, MessageS
peer.InvitationMessage = ReceivedContact.InvitationMessage
for srv := range ReceivedContact.PullServers {
peer.ContactPullServers = append(peer.ContactPullServers, ReceivedContact.PullServers[srv].GetUid())
id.MessageServers.StoreServerIfNotExists(CreateServerFromUid(ReceivedContact.PullServers[srv].GetUid()))
}
/* for _, i := range MessageServerIdxs {
srv := id.MessageServers.Servers[i].GetServerCard()
@ -144,14 +148,14 @@ func (id *Identity) AnswerInvitation(MyName string, ContactName string, MessageS
peer.MyPullServers = MessageServerIdxs
peer.MyName = MyName
peer.InvitationId = ReceivedContact.InvitationId
id.Peers = append(id.Peers, &peer)
id.Peers.StorePeer(&peer)
return &peer
}
// Finalizes an invitation, returns nil if successful
func (id *Identity) FinalizeInvitation(ReceivedContact *meowlib.ContactCard) error {
for i, p := range id.Peers {
/*for i, p := range id.Peers {
if p.InvitationId == ReceivedContact.InvitationId {
//id.Peers[i].Name = ReceivedContact.Name
id.Peers[i].ContactEncryption = ReceivedContact.EncryptionPublicKey
@ -165,7 +169,11 @@ func (id *Identity) FinalizeInvitation(ReceivedContact *meowlib.ContactCard) err
return nil
}
}
return errors.New("no matching contact found for invitationId " + ReceivedContact.InvitationId)
return errors.New("no matching contact found for invitationId " + ReceivedContact.InvitationId)*/
for srv := range ReceivedContact.PullServers {
id.MessageServers.StoreServerIfNotExists(CreateServerFromUid(ReceivedContact.PullServers[srv].GetUid()))
}
return id.Peers.FinalizeInvitation(ReceivedContact)
}
// LoadIdentity loads an identity from an encrypted file
@ -186,6 +194,9 @@ func LoadIdentity(filename string, password string) (*Identity, error) {
return nil, err
}
GetConfig().me = &id
if id.Peers.DbFile != "" {
id.Peers.LoadPeers(password)
}
return &id, err
}
@ -223,6 +234,7 @@ func (id *Identity) TryUnlockHidden(password string) error {
return errors.New("no peer found")
}
/*
func (id *Identity) HidePeer(peerIdx int, password string) error {
serializedPeer, err := json.Marshal(id.Peers[peerIdx])
if err != nil {
@ -237,13 +249,14 @@ func (id *Identity) HidePeer(peerIdx int, password string) error {
// remove clear text peer
id.Peers = append(id.Peers[:peerIdx], id.Peers[peerIdx+1:]...)
return nil
}
}*/
func (id *Identity) generateRandomHiddenStuff() {
r := rand.New(rand.NewSource(time.Now().UnixNano()))
count := r.Intn(maxHiddenCount) + 1
for i := 1; i < count; i++ {
var p Peer
p.Uid = uuid.New().String()
p.Name = randomLenString(4, 20)
p.MyEncryptionKp = meowlib.NewKeyPair()
p.MyIdentity = meowlib.NewKeyPair()
@ -252,9 +265,10 @@ func (id *Identity) generateRandomHiddenStuff() {
p.ContactPublicKey = p.MyLookupKp.Public
p.ContactEncryption = p.MyIdentity.Public
p.ContactLookupKey = p.MyEncryptionKp.Public
p.dbPassword = randomLenString(8, 14)
// p.Contact.AddUrls([]string{randomLenString(14, 60), randomLenString(14, 60)}) // todo add servers
id.Peers = append(id.Peers, &p)
id.HidePeer(0, randomLenString(8, 14))
id.Peers.StorePeer(&p)
//id.HidePeer(0, randomLenString(8, 14))
// TODO Add random conversations
}
}
@ -262,7 +276,7 @@ func (id *Identity) generateRandomHiddenStuff() {
type BackgroundJob struct {
RootPublic string `json:"root_public,omitempty"`
Device meowlib.KeyPair `json:"device,omitempty"`
Jobs []*RequestsJob `json:"jobs,omitempty"`
Jobs []RequestsJob `json:"jobs,omitempty"`
}
type RequestsJob struct {
@ -270,8 +284,8 @@ type RequestsJob struct {
LookupKeys []meowlib.KeyPair `json:"lookup_keys,omitempty"`
}
func (id *Identity) GetRequestJobs() []*RequestsJob {
var list []*RequestsJob
func (id *Identity) GetRequestJobs() []RequestsJob {
var list []RequestsJob
srvs := map[string]*RequestsJob{}
// get all servers
servers, err := id.MessageServers.LoadAllServers()
@ -283,7 +297,11 @@ func (id *Identity) GetRequestJobs() []*RequestsJob {
srvs[server.GetServerCard().GetUid()] = &rj
}
// add ids to the map
for _, peer := range id.Peers {
peers, err := id.Peers.GetPeers()
if err != nil {
return nil
}
for _, peer := range peers {
// check if peer inviation is accepted
for _, server := range peer.MyPullServers {
srvs[server].LookupKeys = append(srvs[server].LookupKeys, peer.MyLookupKp)
@ -302,7 +320,7 @@ func (id *Identity) GetRequestJobs() []*RequestsJob {
// build list
for _, srv := range srvs {
if len(srv.LookupKeys) > 0 {
list = append(list, srv)
list = append(list, *srv)
}
}
}

View File

@ -7,6 +7,7 @@ import (
"testing"
"forge.redroom.link/yves/meowlib"
"github.com/google/uuid"
"github.com/stretchr/testify/assert"
)
@ -32,17 +33,21 @@ func createId() *Identity {
if err != nil {
log.Fatal("Save failed")
}
var p Peer
p.Name = "testName"
p.MyEncryptionKp = meowlib.NewKeyPair()
p.MyIdentity = meowlib.NewKeyPair()
p.MyLookupKp = meowlib.NewKeyPair()
p.Name = "foo"
p.ContactPublicKey = p.MyLookupKp.Public
p.ContactEncryption = p.MyIdentity.Public
p.ContactLookupKey = p.MyEncryptionKp.Public
//p.Contact.AddUrls([]string{"http:/127.0.0.1/meow", "tcp://localhost:1234"}) //todo add servers
id.Peers = append(id.Peers, &p)
for i := range 10 {
var p Peer
p.Uid = uuid.New().String()
p.Name = "testName_" + strconv.Itoa(i)
p.MyEncryptionKp = meowlib.NewKeyPair()
p.MyIdentity = meowlib.NewKeyPair()
p.MyLookupKp = meowlib.NewKeyPair()
p.Name = "foo_" + strconv.Itoa(i)
p.ContactPublicKey = meowlib.NewKeyPair().Public
p.ContactEncryption = meowlib.NewKeyPair().Public
p.ContactLookupKey = meowlib.NewKeyPair().Public
p.MyPullServers = []string{"server1", "server2"}
//p.Contact.AddUrls([]string{"http:/127.0.0.1/meow", "tcp://localhost:1234"}) //todo add servers
id.Peers.StorePeer(&p)
}
return id
}
@ -72,42 +77,28 @@ func TestLoad(t *testing.T) {
}
func TestHidePeer(t *testing.T) {
id := createId()
name := id.Peers[0].Name
assert.Equal(t, len(id.Peers), 1)
h := len(id.HiddenPeers)
id.HidePeer(0, "mypassword")
assert.Equal(t, len(id.Peers), 0)
assert.Equal(t, len(id.HiddenPeers), h+1)
id.TryUnlockHidden("mypassword")
assert.Equal(t, len(id.unlockedHiddenPeers), 1)
assert.Equal(t, id.unlockedHiddenPeers[0].Name, name)
if exists("test.id") {
os.Remove("test.id")
}
/*
id := createId()
name := id.Peers[0].Name
assert.Equal(t, len(id.Peers), 1)
h := len(id.HiddenPeers)
id.HidePeer(0, "mypassword")
assert.Equal(t, len(id.Peers), 0)
assert.Equal(t, len(id.HiddenPeers), h+1)
id.TryUnlockHidden("mypassword")
assert.Equal(t, len(id.unlockedHiddenPeers), 1)
assert.Equal(t, id.unlockedHiddenPeers[0].Name, name)
if exists("test.id") {
os.Remove("test.id")
}
*/
}
// test GetRequestJobs
func TestGetRequestJobs(t *testing.T) {
// Create a mock Identity object
id := &Identity{
Peers: []*Peer{
{
MyPullServers: []string{"server1", "server2"},
MyLookupKp: meowlib.NewKeyPair(),
},
{
MyPullServers: []string{"server3", "server4"},
MyLookupKp: meowlib.NewKeyPair(),
},
},
unlockedHiddenPeers: []*Peer{
{
MyPullServers: []string{"server5", "server6"},
MyLookupKp: meowlib.NewKeyPair(),
},
},
}
id := createId()
id.MessageServers = ServerStorage{
DbFile: "test.db",
}

View File

@ -3,11 +3,13 @@ package client
import "forge.redroom.link/yves/meowlib"
type InternalUserMessage struct {
Outbound bool `json:"outbound"`
Messagetype string `json:"messagetype,omitempty"`
Message string `json:"message,omitempty"`
ConversationStatus *meowlib.ConversationStatus `json:"conversation_status,omitempty"`
Contact *meowlib.ContactCard `json:"contact,omitempty"`
Outbound bool `json:"outbound"`
Messagetype string `json:"messagetype,omitempty"`
Message string `json:"message,omitempty"`
Status *meowlib.ConversationStatus `json:"conversation_status,omitempty"`
Contact *meowlib.ContactCard `json:"contact,omitempty"`
ServerDeliveryUuid string `json:"server_delivery_uuid,omitempty"`
ServerDeliveryTimestamp int64 `json:"server_delivery_timestamp,omitempty"`
//Group group
FilePaths []string `json:"file_paths,omitempty"`
CurrentLocation *meowlib.Location `json:"current_location,omitempty"`
@ -26,7 +28,7 @@ func InternalUserMessageFromUserMessage(peer *Peer, msg *meowlib.UserMessage) *I
}
iu.Messagetype = msg.Type
iu.Message = string(msg.Data)
iu.ConversationStatus = msg.Status
iu.Status = msg.Status
iu.Contact = msg.Contact
return iu
}

12
client/logger.go Normal file
View File

@ -0,0 +1,12 @@
package client
import (
"github.com/rs/zerolog"
)
var logger zerolog.Logger
// AddLogger sets the logger for the sublibrary
func AddLogger(l zerolog.Logger) {
logger = l
}

View File

@ -22,7 +22,7 @@ func StoreMessage(peer *Peer, usermessage *meowlib.UserMessage, filenames []stri
dbid = uuid.NewString()
peer.DbIds = []string{dbid}
identity.Save()
identity.Peers.StorePeer(peer)
identity.CreateFolder()
file, err := os.Create(filepath.Join(cfg.StoragePath, identity.Uuid, dbid+GetConfig().DbSuffix))
if err != nil {
@ -95,7 +95,7 @@ func StoreMessage(peer *Peer, usermessage *meowlib.UserMessage, filenames []stri
}
ium := DbMessageToInternalUserMessage(id, dbid, dbm)
peer.LastMessage = ium
identity.Save()
identity.Peers.StorePeer(peer)
return nil
}
@ -225,9 +225,7 @@ func GetMessagesHistory(peer *Peer, inAppMsgCount int, lastDbId int, wantMore in
return messages, nil
}
// Get old messages from a peer
func GetMessagePreview(peer *Peer, dbFile string, dbId int64, password string) ([]byte, error) {
func GetDbMessage(dbFile string, dbId int64, password string) (*meowlib.DbMessage, error) {
// There fileidx should provide the db that we need (unless wantMore overlaps the next DB)
db, _ := sql.Open("sqlite3", filepath.Join(GetConfig().StoragePath, GetConfig().GetIdentity().Uuid, dbFile+GetConfig().DbSuffix)) // Open the created SQLite File
defer db.Close()
@ -261,9 +259,44 @@ func GetMessagePreview(peer *Peer, dbFile string, dbId int64, password string) (
}
}
return &dbm, nil
}
func UpdateDbMessage(dbm *meowlib.DbMessage, dbFile string, dbId int64, password string) error {
db, _ := sql.Open("sqlite3", filepath.Join(GetConfig().StoragePath, GetConfig().GetIdentity().Uuid, dbFile+GetConfig().DbSuffix)) // Open the created SQLite File
defer db.Close()
// Encrypt message
out, err := proto.Marshal(dbm)
if err != nil {
return err
}
encData, err := meowlib.SymEncrypt(password, out)
if err != nil {
return err
}
// Insert message
updateMessageSQL := `UPDATE message SET m=? WHERE id=?`
statement, err := db.Prepare(updateMessageSQL) // Prepare statement.
if err != nil {
return err
}
_, err = statement.Exec(encData, dbId)
if err != nil {
return err
}
return nil
}
// Get old messages from a peer
func GetMessagePreview(dbFile string, dbId int64, password string) ([]byte, error) {
dbm, err := GetDbMessage(dbFile, dbId, password)
if err != nil {
return nil, err
}
return FilePreview(dbm.FilePaths[0], password)
}
// decrypt the a file and returns the raw content
func FilePreview(filename string, password string) ([]byte, error) {
// get the hidden file
encData, err := os.ReadFile(filename)
@ -278,7 +311,7 @@ func FilePreview(filename string, password string) ([]byte, error) {
return data, nil
}
// make an image from the files content (loads the first image, or build a more complex view)
// return the raw content from the files content (loads the first image, or build a more complex view)
func InternalUserMessagePreview(msg *InternalUserMessage, password string) ([]byte, error) {
// get the hidden file name
if len(msg.FilePaths) == 0 {
@ -296,7 +329,6 @@ func getMessageCount(dbid string) (int, error) {
if err != nil {
return 0, err
}
return count, nil
}

View File

@ -14,11 +14,15 @@ func TestStoreMessage(t *testing.T) {
id := createId()
var um meowlib.UserMessage
um.Data = []byte("blabla")
err := StoreMessage(id.Peers[0], &um, []string{}, GetConfig().memoryPassword)
peers, err := id.Peers.GetPeers()
if err != nil {
log.Fatal(err)
}
messages, err := GetMessagesHistory(id.Peers[0], 0, 0, 10, GetConfig().memoryPassword)
err = StoreMessage(peers[0], &um, []string{}, GetConfig().memoryPassword)
if err != nil {
log.Fatal(err)
}
messages, err := GetMessagesHistory(peers[0], 0, 0, 10, GetConfig().memoryPassword)
if err != nil {
log.Fatal(err)
}
@ -42,8 +46,9 @@ func TestStoreMessage(t *testing.T) {
func TestManyStoreMessage(t *testing.T) {
id := createId()
peers, err := id.Peers.GetPeers()
// test with zero messages
messages, err := GetMessagesHistory(id.Peers[0], 0, 0, 10, GetConfig().memoryPassword)
messages, err := GetMessagesHistory(peers[0], 0, 0, 10, GetConfig().memoryPassword)
if err != nil {
log.Fatal(err)
}
@ -51,12 +56,12 @@ func TestManyStoreMessage(t *testing.T) {
for i := 1; i < 100; i++ {
var um meowlib.UserMessage
um.Data = []byte(randomLenString(20, 200))
err := StoreMessage(id.Peers[0], &um, []string{}, GetConfig().memoryPassword)
err := StoreMessage(peers[0], &um, []string{}, GetConfig().memoryPassword)
if err != nil {
log.Fatal(err)
}
}
messages, err = GetMessagesHistory(id.Peers[0], 0, 0, 10, GetConfig().memoryPassword)
messages, err = GetMessagesHistory(peers[0], 0, 0, 10, GetConfig().memoryPassword)
if err != nil {
log.Fatal(err)
}

View File

@ -1,7 +1,6 @@
package client
import (
"fmt"
"io"
"os"
"time"
@ -14,12 +13,14 @@ import (
// Peer manages the peer messaging functions
// - Building simple user messages
// - Utility functions for packing/unpacking, encrypting/decrypting messages for peer communication
// - Peer might be of type "contact" "group" "personnae" "channel" "device" "sensor"
type Peer struct {
Uid string `json:"uid,omitempty"`
Name string `json:"name,omitempty"`
Avatar string `json:"avatar,omitempty"`
MyName string `json:"my_name,omitempty"`
MyAvatar string `json:"my_avatar,omitempty"`
Uid string `json:"uid,omitempty"`
Name string `json:"name,omitempty"`
Avatar string `json:"avatar,omitempty"`
Avatars []Avatar `json:"avatars,omitempty"`
MyName string `json:"my_name,omitempty"`
MyAvatar string `json:"my_avatar,omitempty"`
// Conversation []InternalMessage `json:"conversation,omitempty"`
// My own keys for that peer
MyIdentity meowlib.KeyPair `json:"my_identity,omitempty"`
@ -44,9 +45,12 @@ type Peer struct {
Blocked bool `json:"blocked,omitempty"`
MessageNotification string `json:"message_notification,omitempty"`
MatriochkaMode bool `json:"matriochka_mode,omitempty"`
ServerDeliveryInfo bool `json:"server_delivery_info,omitempty"`
CallsAllowed bool `json:"calls_allowed,omitempty"`
DirectMode bool `json:"direct_mode,omitempty"`
DbIds []string `json:"db_ids,omitempty"`
IsDevice bool `json:"is_device,omitempty"`
Type string `json:"type,omitempty"`
PersonnaeDbId string `json:"personnae_db_id,omitempty"`
dbPassword string
}
@ -141,7 +145,7 @@ func (p *Peer) BuildSingleFileMessage(filename string, message []byte) ([]meowli
file.Data = b[:readTotal]
file.Size = uint64(fi.Size())
msg.Files = append(msg.Files, &file)
msg.Type = "2"
msg.Type = "1"
if chunk == 0 {
msg.Status = &meowlib.ConversationStatus{}
msg.Status.Uuid = uuid.New().String()
@ -201,7 +205,7 @@ func (p *Peer) AsymEncryptMessage(Message []byte) (*meowlib.EncryptedMessage, er
// fmt.Println("[AsymEncryptMessage] Signature should be verified with:", p.MyIdentity.Public)
enc, err := meowlib.AsymEncryptAndSign(p.ContactEncryption, p.MyIdentity.Private, Message)
if err != nil {
fmt.Println(err.Error())
logger.Error().Err(err).Msg("Peer.AsymEncryptMessage")
return enc, err
}
return enc, err
@ -214,7 +218,7 @@ func (p *Peer) AsymDecryptMessage(Message []byte, Signature []byte) (DecryptedMe
// fmt.Println("[AsymDecryptMessage] Signature will be verified with:", p.ContactPublicKey)
DecryptedMessage, err = meowlib.AsymDecryptAndCheck(p.MyEncryptionKp.Private, p.ContactPublicKey, Message, Signature)
if err != nil {
fmt.Println(err.Error())
logger.Error().Err(err).Msg("Peer.AsymDecryptMessage")
return nil, err
}
return DecryptedMessage, err
@ -226,6 +230,9 @@ func (p *Peer) PackUserMessage(message []byte, signature []byte) *meowlib.Packed
msg.Destination = p.ContactLookupKey
msg.Payload = message
msg.Signature = signature
if p.ServerDeliveryInfo {
msg.ServerDeliveryUuid = uuid.New().String()
}
return &msg
}

View File

@ -4,6 +4,7 @@ import (
"strconv"
"testing"
"github.com/google/uuid"
"github.com/stretchr/testify/assert"
)
@ -15,9 +16,13 @@ func TestGetFromPublicKey(t *testing.T) {
id.Save()
for i := 1; i < 10; i++ {
var p Peer
p.Uid = uuid.New().String()
p.Name = "test" + strconv.Itoa(i)
p.ContactPublicKey = "stringToFind" + strconv.Itoa(i)
id.Peers = append(id.Peers, &p)
err := id.Peers.StorePeer(&p)
if err != nil {
t.Fatal("StorePeer failed")
}
}
p5 := id.Peers.GetFromPublicKey("stringToFind5")
assert.Equal(t, p5.Name, "test5")

View File

@ -1,9 +1,5 @@
package client
import (
"forge.redroom.link/yves/meowlib"
)
type PeerList []*Peer
func (pl *PeerList) GetFromPublicKey(publickey string) *Peer {
@ -43,7 +39,7 @@ func (pl *PeerList) GetFromName(name string) *Peer {
}
// ! Wrong implementation, does not discriminate on different servers
func (pl *PeerList) GetConversationRequests() []*meowlib.ConversationRequest {
/*func (pl *PeerList) GetConversationRequests() []*meowlib.ConversationRequest {
var list []*meowlib.ConversationRequest
for _, peer := range *pl {
var cr meowlib.ConversationRequest
@ -52,4 +48,4 @@ func (pl *PeerList) GetConversationRequests() []*meowlib.ConversationRequest {
list = append(list, &cr)
}
return list
}
}*/

248
client/peerstorage.go Normal file
View File

@ -0,0 +1,248 @@
package client
//
// Storage
//
import (
"crypto/sha256"
"encoding/json"
"errors"
"path/filepath"
"sort"
"forge.redroom.link/yves/meowlib"
"github.com/dgraph-io/badger"
"github.com/google/uuid"
)
type PeerStorage struct {
DbFile string `json:"db_file,omitempty"`
db *badger.DB
cache map[string]*Peer
}
// Open the badger database from struct PeerStorage
func (ps *PeerStorage) open() error {
if ps.DbFile == "" {
ps.DbFile = uuid.New().String()
GetConfig().GetIdentity().Save()
}
if ps.cache == nil {
ps.cache = make(map[string]*Peer)
}
opts := badger.DefaultOptions(filepath.Join(GetConfig().StoragePath, GetConfig().GetIdentity().Uuid, ps.DbFile))
opts.Logger = nil
var err error
ps.db, err = badger.Open(opts)
if err != nil {
return err
}
return nil
}
// Store function StorePeer stores a peer in the badger database with Peer.Uid as key
func (ps *PeerStorage) StorePeer(peer *Peer) error {
err := ps.open()
if err != nil {
return err
}
defer ps.close()
// first marshal the Peer to bytes with protobuf
jsonsrv, err := json.Marshal(peer)
if err != nil {
return err
}
password := GetConfig().memoryPassword
if peer.dbPassword != "" {
password = peer.dbPassword
}
data, err := meowlib.SymEncrypt(password, jsonsrv)
if err != nil {
return err
}
shakey := sha256.Sum256([]byte(peer.Uid))
key := shakey[:]
// add it to cache
ps.cache[peer.Uid] = peer
// then store it in the database
return ps.db.Update(func(txn *badger.Txn) error {
return txn.Set(key, data)
})
}
// LoadPeer function loads a Peer from the badger database with Peer.GetUid() as key
func (ps *PeerStorage) LoadPeer(uid string, password string) (*Peer, error) {
var peer Peer
err := ps.open()
if err != nil {
return nil, err
}
defer ps.close()
shakey := sha256.Sum256([]byte(uid))
key := shakey[:]
err = ps.db.View(func(txn *badger.Txn) error {
item, err := txn.Get(key)
if err != nil {
return err
}
return item.Value(func(val []byte) error {
jsonsrv, err := meowlib.SymDecrypt(password, val)
if err != nil {
return err
}
return json.Unmarshal(jsonsrv, &peer)
})
})
return &peer, err
}
// DeletePeer function deletes a Peer from the badger database with Peer.GetUid() as key
func (ps *PeerStorage) DeletePeer(uid string) error {
err := ps.open()
if err != nil {
return err
}
defer ps.close()
shakey := sha256.Sum256([]byte(uid))
key := shakey[:]
return ps.db.Update(func(txn *badger.Txn) error {
return txn.Delete(key)
})
}
// LoadPeers function loads Peers from the badger database with a specific password
func (ps *PeerStorage) LoadPeers(password string) ([]*Peer, error) {
var peers []*Peer
err := ps.open()
if err != nil {
return nil, err
}
defer ps.close()
err = ps.db.View(func(txn *badger.Txn) error {
opts := badger.DefaultIteratorOptions
opts.PrefetchSize = 10
it := txn.NewIterator(opts)
defer it.Close()
for it.Rewind(); it.Valid(); it.Next() {
item := it.Item()
var sc Peer
err := item.Value(func(val []byte) error {
jsonsrv, err := meowlib.SymDecrypt(password, val)
if err != nil {
return err
}
return json.Unmarshal(jsonsrv, &sc)
})
if err == nil {
peers = append(peers, &sc)
ps.cache[sc.Uid] = &sc
}
}
return nil
})
// Sort peers based on peer.Name
sort.Slice(peers, func(i, j int) bool {
return peers[i].Name < peers[j].Name
})
return peers, err
}
// GetPeers function returns all peers from the cache as a sorted array
func (ps *PeerStorage) GetPeers() ([]*Peer, error) {
peers := make([]*Peer, 0, len(ps.cache))
for _, peer := range ps.cache {
peers = append(peers, peer)
}
// Sort peers based on peer.Name
sort.Slice(peers, func(i, j int) bool {
return peers[i].Name < peers[j].Name
})
return peers, nil
}
// close the badger database
func (ps *PeerStorage) close() {
ps.db.Close()
}
func (ps *PeerStorage) GetFromPublicKey(publickey string) *Peer {
for _, peer := range ps.cache {
if peer.ContactPublicKey == publickey {
return peer
}
}
return nil
}
func (ps *PeerStorage) GetFromInvitationId(invitationId string) *Peer {
for _, peer := range ps.cache {
if peer.InvitationId == invitationId {
return peer
}
}
return nil
}
func (ps *PeerStorage) GetFromMyLookupKey(publickey string) *Peer {
for _, peer := range ps.cache {
if peer.MyLookupKp.Public == publickey {
return peer
}
}
return nil
}
func (ps *PeerStorage) NameExists(name string) bool {
for _, peer := range ps.cache {
if peer.Name == name {
return true
}
}
return false
}
func (ps *PeerStorage) GetFromName(name string) *Peer {
for _, peer := range ps.cache {
if peer.Name == name {
return peer
}
}
return nil
}
func (ps *PeerStorage) GetFromUid(uid string) *Peer {
return ps.cache[uid]
}
// Checks if the received contact card is an answer to an invitation, returns true if it is, and the proposed and received nicknames
func (ps *PeerStorage) CheckInvitation(ReceivedContact *meowlib.ContactCard) (isAnswer bool, proposedNick string, receivedNick string, invitationMessage string) {
// invitation Id found, this is an answer to an invitation
for _, p := range ps.cache {
if p.InvitationId == ReceivedContact.InvitationId {
return true, p.Name, ReceivedContact.Name, ReceivedContact.InvitationMessage
}
}
// it's an invitation
return false, "", ReceivedContact.Name, ReceivedContact.InvitationMessage
}
// Finalizes an invitation, returns nil if successful
func (ps *PeerStorage) FinalizeInvitation(ReceivedContact *meowlib.ContactCard) error {
for i, p := range ps.cache {
if p.InvitationId == ReceivedContact.InvitationId {
//id.Peers[i].Name = ReceivedContact.Name
ps.cache[i].ContactEncryption = ReceivedContact.EncryptionPublicKey
ps.cache[i].ContactLookupKey = ReceivedContact.LookupPublicKey
ps.cache[i].ContactPublicKey = ReceivedContact.ContactPublicKey
srvs := []string{}
for srv := range ReceivedContact.PullServers {
srvs = append(srvs, ReceivedContact.PullServers[srv].GetUid())
}
ps.cache[i].ContactPullServers = srvs
ps.StorePeer(ps.cache[i])
return nil
}
}
return errors.New("no matching contact found for invitationId " + ReceivedContact.InvitationId)
}

View File

@ -0,0 +1,60 @@
package client
import (
"testing"
"github.com/google/uuid"
)
func TestOpen(t *testing.T) {
ps := &PeerStorage{
DbFile: "peerdb.test",
cache: nil,
db: nil,
}
err := ps.open()
if err != nil {
t.Errorf("Failed to open database: %v", err)
}
}
func TestStorePeer(t *testing.T) {
id := createId()
GetConfig().SetMemPass("test")
GetConfig().SetIdentity(id)
ps := &PeerStorage{
DbFile: "peerdb.test",
cache: nil,
db: nil,
}
peer := &Peer{
Uid: uuid.New().String(),
Name: "testName",
InvitationId: "testInvitationId",
MyName: "testMyName",
ContactPublicKey: "testContactPublicKey",
}
err := ps.StorePeer(peer)
if err != nil {
t.Errorf("Failed to store peer: %v", err)
}
// load the peer from the database
peers, err := ps.LoadPeers(GetConfig().GetMemPass())
if err != nil {
t.Errorf("Failed to load peers: %v", err)
}
if len(peers) != 1 {
t.Errorf("Expected 1 peer, got %d", len(peers))
}
if peers[0].Uid != peer.Uid {
t.Errorf("Expected peer to have uid %s, got %s", peer.Uid, peers[0].Uid)
}
if peers[0].MyName != peer.MyName {
t.Errorf("Expected peer to have MyName %s, got %s", peer.MyName, peers[0].MyName)
}
}

View File

@ -1,7 +1,6 @@
package client
import (
"fmt"
"strings"
"time"
@ -33,12 +32,15 @@ type Server struct {
Country string `json:"country,omitempty"`
AllowedDelay int `json:"allowed_delay,omitempty"`
Backup bool `json:"backup,omitempty"`
WebRTC bool `json:"webrtc,omitempty"`
}
// CreateServerFromUrl creates a server from a basic url, ex : https://my.meowserver.example:8443/meow/
func CreateServerFromUrl(url string) *Server {
var is Server
is.Name = url
is.Url = url
is.UserKp = meowlib.NewKeyPair()
return &is
}
@ -46,6 +48,8 @@ func CreateServerFromUrl(url string) *Server {
func CreateServerFromUid(uid string) *Server {
var is Server
uidTable := strings.Split(uid, "@") //! Weak test, use regexp
is.Name = uid
is.UserKp = meowlib.NewKeyPair()
if len(uidTable) == 2 {
loginpw := strings.Split(uidTable[0], ":")
is.Url = uidTable[1]
@ -59,7 +63,7 @@ func CreateServerFromUid(uid string) *Server {
// CreateServerFromMeowUrl creates a server from a meow url, ex : meow://mylogin:mypassword@https://my.meowserver.example:8443/meow/
func CreateServerFromMeowUrl(meowurl string) *Server {
uid := meowurl[7:]
uid := strings.Replace(meowurl[7:], "//", "://", 1)
return CreateServerFromUid(uid)
}
@ -116,7 +120,7 @@ func (ints *Server) AsymEncryptMessage(Message []byte) (*meowlib.EncryptedMessag
var enc *meowlib.EncryptedMessage
enc, err := meowlib.AsymEncryptAndSign(ints.PublicKey, ints.UserKp.Private, Message)
if err != nil {
fmt.Println(err.Error())
logger.Error().Err(err).Msg("Server.AsymEncryptMessage")
return nil, err
}
return enc, err
@ -126,7 +130,7 @@ func (ints *Server) AsymEncryptMessage(Message []byte) (*meowlib.EncryptedMessag
func (ints *Server) AsymDecryptMessage(Message []byte, Signature []byte) (DecryptedMessage []byte, err error) {
DecryptedMessage, err = meowlib.AsymDecryptAndCheck(ints.UserKp.Private, ints.PublicKey, Message, Signature)
if err != nil {
fmt.Println(err.Error())
logger.Error().Err(err).Msg("Server.AsymDecryptMessage")
return nil, err
}
return DecryptedMessage, err
@ -152,6 +156,7 @@ func (ints *Server) BuildMessageSendingMessage(usermsg *meowlib.PackedUserMessag
return out, nil
}
// ! Unfinished unused ?
// BuildMessageRequestMessage creates a message lookup message to server and returns it as protobuf serialized byte array
func (ints *Server) BuildMessageRequestMessage(lookupKeys []string) ([]byte, error) {
var msg meowlib.ToServerMessage
@ -165,6 +170,23 @@ func (ints *Server) BuildMessageRequestMessage(lookupKeys []string) ([]byte, err
return out, nil
}
// BuildVideoRoomRequestMessage creates a video room request to server and returns it as protobuf serialized byte array
func (ints *Server) BuildVideoRoomRequestMessage(users []string, expiry uint64) (*meowlib.ToServerMessage, error) {
var msg meowlib.ToServerMessage
msg.Uuid = uuid.New().String()
msg.Type = "1"
msg.From = ints.UserKp.Public
// declare an array of meow.VideoCredential
videocreds := make([]*meowlib.VideoCredential, len(users))
for idx := range users {
videocreds[idx] = &meowlib.VideoCredential{
Username: users[idx],
}
}
msg.VideoData.Credentials = videocreds
return &msg, nil
}
// BuildToServerMessageInvitation creates an invitation message to server and returns it as a meowlib.ToServerMessage
// it takes as input a contactcard generated by Identity.InvitePeer
func (ints *Server) BuildToServerMessageInvitationCreation(invitation *meowlib.ContactCard, password string, timeout int, shortCodeLen int) (*meowlib.ToServerMessage, error) {

View File

@ -55,6 +55,39 @@ func (ss *ServerStorage) StoreServer(sc *Server) error {
}
// Check if a server exists in a badger database with Server.GetUid() as key
func (ss *ServerStorage) ServerExists(sc *Server) (bool, error) {
err := ss.open()
if err != nil {
return false, err
}
defer ss.close()
shakey := sha256.Sum256([]byte(sc.GetServerCard().GetUid()))
key := shakey[:]
// check if key exists in badger database
err = ss.db.View(func(txn *badger.Txn) error {
_, err := txn.Get(key)
return err
}) // Add a comma here
if err != nil { // key does not exist
return false, nil
}
return true, nil
}
// Store a server in a badger database with Server.GetUid() as key if it is not already there
func (ss *ServerStorage) StoreServerIfNotExists(sc *Server) error {
exists, err := ss.ServerExists(sc)
if err != nil {
return err
}
if !exists {
return ss.StoreServer(sc)
}
return nil
}
// LoadServer function loads a Server from a badger database with Server.GetUid() as key
func (ss *ServerStorage) LoadServer(uid string) (*Server, error) {
var sc Server

View File

@ -21,7 +21,7 @@ func TestGetUid(t *testing.T) {
}
func TestStoreServer(t *testing.T) {
GetConfig().SetMemPass("test")
createId()
ss := ServerStorage{DbFile: "test.db"}
srv := Server{
Name: "test",
@ -49,6 +49,7 @@ func TestStoreServer(t *testing.T) {
}
func TestLoadServersFromUids(t *testing.T) {
createId()
GetConfig().SetMemPass("test")
ss := ServerStorage{DbFile: "test.db"}
srv := Server{
@ -76,7 +77,7 @@ func TestLoadServersFromUids(t *testing.T) {
}
func TestLoadServerCardsFromUids(t *testing.T) {
GetConfig().SetMemPass("test")
createId()
ss := ServerStorage{DbFile: "test.db"}
srv := Server{
Name: "test",
@ -101,3 +102,123 @@ func TestLoadServerCardsFromUids(t *testing.T) {
// recursively remove the test.db folder
os.RemoveAll("test.db")
}
func TestServerExists(t *testing.T) {
createId()
ss := ServerStorage{DbFile: "test.db"}
server := &Server{
Name: "test",
Url: "http://localhost:8080",
PublicKey: meowlib.NewKeyPair().Public,
}
// Check if server exists before storing it
exists, err := ss.ServerExists(server)
if err != nil {
t.Errorf("Failed to check if server exists: %v", err)
}
if exists {
t.Errorf("Server exists before storing it")
}
// Store the server
err = ss.StoreServer(server)
if err != nil {
t.Errorf("Failed to store server: %v", err)
}
// Check if server exists after storing it
exists, err = ss.ServerExists(server)
if err != nil {
t.Errorf("Failed to check if server exists: %v", err)
}
if !exists {
t.Errorf("Server does not exist after storing it")
}
// Clean up
// recursively remove the test.db folder
os.RemoveAll("test.db")
}
func TestStoreServerIfNotExists(t *testing.T) {
createId()
ss := ServerStorage{DbFile: "test.db"}
server := &Server{
Name: "test",
Url: "http://localhost:8080",
PublicKey: meowlib.NewKeyPair().Public,
}
// Check if server exists before storing it
exists, err := ss.ServerExists(server)
if err != nil {
t.Errorf("Failed to check if server exists: %v", err)
}
if exists {
t.Errorf("Server exists before storing it")
}
// Store the server if it does not exist
err = ss.StoreServerIfNotExists(server)
if err != nil {
t.Errorf("Failed to store server: %v", err)
}
// Check if server exists after storing it
exists, err = ss.ServerExists(server)
if err != nil {
t.Errorf("Failed to check if server exists: %v", err)
}
if !exists {
t.Errorf("Server does not exist after storing it")
}
// Clean up
// recursively remove the test.db folder
os.RemoveAll("test.db")
}
func TestStoreServerIfNotExists_ServerExists(t *testing.T) {
createId()
ss := ServerStorage{DbFile: "test.db"}
server := &Server{
Name: "test",
Url: "http://localhost:8080",
PublicKey: meowlib.NewKeyPair().Public,
}
// Store the server
err := ss.StoreServer(server)
if err != nil {
t.Errorf("Failed to store server: %v", err)
}
// Store the server again with a different public key
newServer := &Server{
Name: "test",
Url: "http://localhost:8080",
PublicKey: meowlib.NewKeyPair().Public,
}
err = ss.StoreServerIfNotExists(newServer)
if err != nil {
t.Errorf("Failed to store server: %v", err)
}
// Retrieve the server and check if the public key has not changed
storedServer, err := ss.LoadServer(server.GetServerCard().GetUid())
if err != nil {
t.Errorf("Failed to get server: %v", err)
}
if storedServer.PublicKey != server.PublicKey {
t.Errorf("Public key was modified")
}
// Clean up
// recursively remove the test.db folder
os.RemoveAll("test.db")
}

View File

@ -0,0 +1,7 @@
@startuml Company Company
Employee -> Company: Join company with provided credentials
Company -> Employee: provide a full featured validated peer
Company -> All: Publishes Employee ContactCard and info
Company -> Employee: notify publication done, service active
Employee -> Company: search for contacts
@enduml

View File

@ -0,0 +1,10 @@
@startuml Public endpoint (free for chat)
User -> Endpoint: Create & send invitation for endpoint (Generate User ContactCard and create endpoint pending contact)
Endpoint -> User: Auto-accept invitation and answer (Generate Endpoint ContactCard and create finalized User contact)
User -> Endpoint: [auto]validate Answer, invitation finalize (Finalize Endpoint contact and notify Endpoint that communication is possible)
Endpoint -> User: query mandatory/optional info for profile publication
User -> Endpoint: provide info
Endpoint -> All: Publishes User ContactCard and info
Endpoint -> User: notify publication done, service active
User -> Endpoint: search for contacts
@enduml

View File

@ -0,0 +1,7 @@
@startuml Server Invitation Step 01
Bob -> MeowBob: Create invitation for alice (Generate Bob ContactCard and create Alice pending contact)
Bob -> Alice: Send invitation (Bob ContactCard)
Alice -> MeowAlice: Accept Invitation and create answer (Generate Alice ContactCard and create finalized Bob contact)
Alice -> Bob: Send answer (Alice ContactCard)
Bob -> MeowBob: Review Answer, invitation finalize (Finalize Alice contact and notify Alice that communication is possible)
@enduml

2816
doc/meow.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 467 KiB

View File

@ -0,0 +1,10 @@
@startuml
Client1 -> Server: Send Message (PubKeyClient2 + Payload)
Server -> Client1: Ack Message (Server UUID + DateReceived)
Client1 --> Server: Message delivery ? (PubKeyClient2 + Payload)
Server --> Client1: Message delivered (Server UUID + DateReceived)
Client2 -> Server: Get Messages (PubKeyClient2)
Server -> Client2: Get Messages [](PubKeyClient2 + Payload)
Client2 --> Server: Ack Messages Processed
@enduml

View File

@ -0,0 +1,24 @@
@startuml
actor Sender
actor Receiver
component Server
component Router
queue msgch
queue dvych
collections msg
collections dvyrq
collections dvy
UserSender -> Server : mesg
Server -> Router : mesg
Router -> msg : store
Router -> dvyrq : store
Router -> msgch : publish
msgch -> Receiver : notifiaction
msg -> Receiver : mesg
@enduml

View File

@ -0,0 +1,20 @@
@startuml "Simple messaging"
actor Sender as snd
actor Receiver as rcv
control Server as srv
collections msg as msg
queue msgch as msgch
collections dvyrq as dvyrq
collections dvy as dvy
queue dvych as dvych
rcv->srv: Listen
srv->msgch: Subscribe
snd->srv: Send message
srv->msg: Store message
srv->msgch: Notify listening receivers
msgch->srv: Notify
msg->srv: Grab message
srv->rcv: Send message
@enduml

View File

@ -0,0 +1,30 @@
@startuml "Messaging with server delivery"
actor Sender as snd
actor Receiver as rcv
control Server as srv
collections msg as msg
queue msgch as msgch
collections dvyrq as dvyrq
collections dvy as dvy
queue dvych as dvych
rcv->srv: Listen for messages
srv->msgch: Subscribe
snd->srv: Send message with delivery uid
snd->msg: Listen for delivery
group storeMessage
srv->msg: Store message
srv->dvyrq: Store delivery request uid=>Receiver
srv->msgch: Notify listening receivers
end
msgch->srv: Notify
msg->srv: Grab message
srv->rcv: Cuts listening with message
srv->dvy: Store delivery done Receiver=>uid
srv->dvych: Notify listening Sender
dvych->srv: Notify
dvy->srv: Grab delivery
srv->snd: Cuts listening with delivery
@enduml

View File

@ -1,7 +0,0 @@
@startuml Server Invitation Step 01
Bob -> MeowBob: Create invitation for alice
Bob -> Alice: Send invitation
Alice -> MeowAlice: Accept Invitation and create answer
Alice -> Bob: Send answer
Bob -> MeowBob: Review Answer, invitation finalize
@enduml

View File

@ -1,8 +0,0 @@
@startuml
Client1 -> Server: Send Message (PubKeyClient2 + Payload)
Server --> Client1: Ack Message (Server UUID + DateReceived)
Client2 -> Server: Get Messages (PubKeyClient2 + IpPublish)
Server --> Client2: Available Messages list (UUID list cyphered with PubKeyClient2)
Client2 <- Server: Get Messages (decoded UUID signed with PK)
Server --> Client2: Messages [](PubKeyClient2 + Payload)
@enduml

View File

@ -85,7 +85,8 @@ func TestEndToEnd(t *testing.T) {
/////////////////////////////////////
// Create a message to that friend //
/////////////////////////////////////
MyFirstFriend := Me.Peers[0]
peers, _ := Me.Peers.GetPeers()
MyFirstFriend := peers[0]
textmessage := "Hello friend!"
// Creating User message
usermessage, err := MyFirstFriend.BuildSimpleUserMessage([]byte(textmessage))

50
go.mod
View File

@ -1,23 +1,49 @@
module forge.redroom.link/yves/meowlib
go 1.16
go 1.23.0
toolchain go1.24.2
require (
github.com/ProtonMail/go-crypto v1.0.0 // indirect
github.com/ProtonMail/gopenpgp/v2 v2.7.5
github.com/cloudflare/circl v1.3.7 // indirect
github.com/ProtonMail/gopenpgp/v2 v2.8.3
github.com/dgraph-io/badger v1.6.2
github.com/go-redis/redis v6.15.9+incompatible
github.com/google/uuid v1.6.0
github.com/livekit/protocol v1.16.0
github.com/makiuchi-d/gozxing v0.1.1
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-sqlite3 v1.14.16
github.com/onsi/ginkgo v1.16.5 // indirect
github.com/onsi/gomega v1.22.1 // indirect
github.com/pkg/errors v0.9.1
github.com/rs/zerolog v1.32.0
github.com/stretchr/testify v1.7.0
golang.org/x/crypto v0.21.0 // indirect
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect
google.golang.org/protobuf v1.33.0
github.com/rs/zerolog v1.34.0
github.com/stretchr/testify v1.9.0
google.golang.org/protobuf v1.36.6
)
require (
github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 // indirect
github.com/ProtonMail/go-crypto v1.2.0 // indirect
github.com/ProtonMail/go-mime v0.0.0-20230322103455-7d82a3887f2f // indirect
github.com/cespare/xxhash v1.1.0 // indirect
github.com/cloudflare/circl v1.6.1 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dgraph-io/ristretto v0.0.2 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/go-jose/go-jose/v3 v3.0.3 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/onsi/ginkgo v1.16.5 // indirect
github.com/onsi/gomega v1.30.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/twitchtv/twirp v8.1.3+incompatible // indirect
golang.org/x/crypto v0.37.0 // indirect
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 // indirect
golang.org/x/net v0.23.0 // indirect
golang.org/x/sys v0.32.0 // indirect
golang.org/x/text v0.24.0 // indirect
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240221002015-b0ce06bbee7c // indirect
google.golang.org/grpc v1.62.0 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

209
go.sum
View File

@ -6,25 +6,35 @@ github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAE
github.com/ProtonMail/go-crypto v0.0.0-20230717121422-5aa5874ade95/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0=
github.com/ProtonMail/go-crypto v1.0.0 h1:LRuvITjQWX+WIfr930YHG2HNfjR1uOfyf5vE0kC2U78=
github.com/ProtonMail/go-crypto v1.0.0/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0=
github.com/ProtonMail/go-crypto v1.2.0 h1:+PhXXn4SPGd+qk76TlEePBfOfivE0zkWFenhGhFLzWs=
github.com/ProtonMail/go-crypto v1.2.0/go.mod h1:9whxjD8Rbs29b4XWbB8irEcE8KHMqaR2e7GWU1R+/PE=
github.com/ProtonMail/go-mime v0.0.0-20230322103455-7d82a3887f2f h1:tCbYj7/299ekTTXpdwKYF8eBlsYsDVoggDAuAjoK66k=
github.com/ProtonMail/go-mime v0.0.0-20230322103455-7d82a3887f2f/go.mod h1:gcr0kNtGBqin9zDW9GOHcVntrwnjrK+qdJ06mWYBybw=
github.com/ProtonMail/gopenpgp/v2 v2.7.5 h1:STOY3vgES59gNgoOt2w0nyHBjKViB/qSg7NjbQWPJkA=
github.com/ProtonMail/gopenpgp/v2 v2.7.5/go.mod h1:IhkNEDaxec6NyzSI0PlxapinnwPVIESk8/76da3Ct3g=
github.com/ProtonMail/gopenpgp/v2 v2.8.3 h1:1jHlELwCR00qovx2B50DkL/FjYwt/P91RnlsqeOp2Hs=
github.com/ProtonMail/gopenpgp/v2 v2.8.3/go.mod h1:LiuOTbnJit8w9ZzOoLscj0kmdALY7hfoCVh5Qlb0bcg=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o=
github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU=
github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA=
github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0=
github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@ -34,11 +44,27 @@ github.com/dgraph-io/ristretto v0.0.2 h1:a5WaUrDa0qm0YrAAS1tUykT5El3kt62KNZZeMxQ
github.com/dgraph-io/ristretto v0.0.2/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E=
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA=
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/eapache/channels v1.1.0 h1:F1taHcn7/F0i8DYqKXJnyhJcVpp2kgFcNePxXtnyu4k=
github.com/eapache/channels v1.1.0/go.mod h1:jMm2qB5Ubtg9zLd+inMZd2/NUvXgzmWXsDaLyQIGfH0=
github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc=
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
github.com/frostbyte73/core v0.0.10 h1:D4DQXdPb8ICayz0n75rs4UYTXrUSdxzUfeleuNJORsU=
github.com/frostbyte73/core v0.0.10/go.mod h1:XsOGqrqe/VEV7+8vJ+3a8qnCIXNbKsoEiu/czs7nrcU=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/gammazero/deque v0.2.1 h1:qSdsbG6pgp6nL7A0+K/B7s12mcCY/5l5SIUpMOl+dC0=
github.com/gammazero/deque v0.2.1/go.mod h1:LFroj8x4cMYCukHJDbxFCkT+r9AndaJnFMuZDV34tuU=
github.com/go-jose/go-jose/v3 v3.0.3 h1:fFKWeig/irsp7XD2zBxvnmA/XaRWp5V3CBsZXJF7G7k=
github.com/go-jose/go-jose/v3 v3.0.3/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ=
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-redis/redis v6.15.9+incompatible h1:K0pv1D7EQUjfyoMql+r/jZqCLizCGKFlFgcHWWmHQjg=
github.com/go-redis/redis v6.15.9+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
@ -52,31 +78,49 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs=
github.com/jxskiss/base62 v1.1.0 h1:A5zbF8v8WXx2xixnAKD2w+abC+sIzYJX+nxmhA6HWFw=
github.com/jxskiss/base62 v1.1.0/go.mod h1:HhWAlUXvxKThfOlZbcuFzsqwtF5TcqS9ru3y5GfjWAc=
github.com/klauspost/compress v1.17.6 h1:60eq2E/jlfwQXtvZEeBUYADs+BwKBWURIY+Gj2eRGjI=
github.com/klauspost/compress v1.17.6/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM=
github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc=
github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/lithammer/shortuuid/v4 v4.0.0 h1:QRbbVkfgNippHOS8PXDkti4NaWeyYfcBTHtw7k08o4c=
github.com/lithammer/shortuuid/v4 v4.0.0/go.mod h1:Zs8puNcrvf2rV9rTH51ZLLcj7ZXqQI3lv67aw4KiB1Y=
github.com/livekit/mageutil v0.0.0-20230125210925-54e8a70427c1 h1:jm09419p0lqTkDaKb5iXdynYrzB84ErPPO4LbRASk58=
github.com/livekit/mageutil v0.0.0-20230125210925-54e8a70427c1/go.mod h1:Rs3MhFwutWhGwmY1VQsygw28z5bWcnEYmS1OG9OxjOQ=
github.com/livekit/protocol v1.16.0 h1:TkUuirvfF1xIfpo5szXqAEEgg7QyML8d0O7+4NQpM7w=
github.com/livekit/protocol v1.16.0/go.mod h1:pnn0Dv+/0K0OFqKHX6J6SreYO1dZxl6tDuAZ1ns8L/w=
github.com/livekit/psrpc v0.5.3-0.20240228172457-3724cb4adbc4 h1:253WtQ2VGVHzIIzW9MUZj7vUDDILESU3zsEbiRdxYF0=
github.com/livekit/psrpc v0.5.3-0.20240228172457-3724cb4adbc4/go.mod h1:CQUBSPfYYAaevg1TNCc6/aYsa8DJH4jSRFdCeSZk5u0=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/makiuchi-d/gozxing v0.1.1 h1:xxqijhoedi+/lZlhINteGbywIrewVdVv2wl9r5O9S1I=
github.com/makiuchi-d/gozxing v0.1.1/go.mod h1:eRIHbOjX7QWxLIDJoQuMLhuXg9LAuw6znsUtRkNw9DU=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
@ -85,35 +129,83 @@ github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwp
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/nats-io/nats.go v1.31.0 h1:/WFBHEc/dOKBF6qf1TZhrdEfTmOZ5JzdJ+Y3m6Y/p7E=
github.com/nats-io/nats.go v1.31.0/go.mod h1:di3Bm5MLsoB4Bx61CBTsxuarI36WbhAwOm8QrW39+i8=
github.com/nats-io/nkeys v0.4.6 h1:IzVe95ru2CT6ta874rt9saQRkWfe2nFj1NtvYSLqMzY=
github.com/nats-io/nkeys v0.4.6/go.mod h1:4DxZNzenSVd1cYQoAa8948QY3QDjrHfcfVADymtkpts=
github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU=
github.com/onsi/ginkgo/v2 v2.1.6/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk=
github.com/onsi/ginkgo/v2 v2.3.0/go.mod h1:Eew0uilEqZmIEZr8JrvYlvOM7Rr6xzTmMV8AyFNU9d0=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro=
github.com/onsi/gomega v1.20.1/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo=
github.com/onsi/gomega v1.21.1/go.mod h1:iYAIXgPSaDHak0LCMA+AWBpIKBr8WZicMxnE8luStNc=
github.com/onsi/gomega v1.22.1 h1:pY8O4lBfsHKZHM/6nrxkhVPUznOlIu3quZcKP/M20KI=
github.com/onsi/gomega v1.22.1/go.mod h1:x6n7VNe4hw0vkyYUM4mjIXx3JbLiPaBPNgB7PRQ1tuM=
github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8=
github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pion/datachannel v1.5.5 h1:10ef4kwdjije+M9d7Xm9im2Y3O6A6ccQb0zcqZcJew8=
github.com/pion/datachannel v1.5.5/go.mod h1:iMz+lECmfdCMqFRhXhcA/219B0SQlbpoR2V118yimL0=
github.com/pion/dtls/v2 v2.2.7 h1:cSUBsETxepsCSFSxC3mc/aDo14qQLMSL+O6IjG28yV8=
github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s=
github.com/pion/ice/v2 v2.3.13 h1:xOxP+4V9nSDlUaGFRf/LvAuGHDXRcjIdsbbXPK/w7c8=
github.com/pion/ice/v2 v2.3.13/go.mod h1:KXJJcZK7E8WzrBEYnV4UtqEZsGeWfHxsNqhVcVvgjxw=
github.com/pion/interceptor v0.1.25 h1:pwY9r7P6ToQ3+IF0bajN0xmk/fNw/suTgaTdlwTDmhc=
github.com/pion/interceptor v0.1.25/go.mod h1:wkbPYAak5zKsfpVDYMtEfWEy8D4zL+rpxCxPImLOg3Y=
github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY=
github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms=
github.com/pion/mdns v0.0.12 h1:CiMYlY+O0azojWDmxdNr7ADGrnZ+V6Ilfner+6mSVK8=
github.com/pion/mdns v0.0.12/go.mod h1:VExJjv8to/6Wqm1FXK+Ii/Z9tsVk/F5sD/N70cnYFbk=
github.com/pion/randutil v0.1.0 h1:CFG1UdESneORglEsnimhUjf33Rwjubwj6xfiOXBa3mA=
github.com/pion/randutil v0.1.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8=
github.com/pion/rtcp v1.2.12 h1:bKWiX93XKgDZENEXCijvHRU/wRifm6JV5DGcH6twtSM=
github.com/pion/rtcp v1.2.12/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4=
github.com/pion/rtp v1.8.3 h1:VEHxqzSVQxCkKDSHro5/4IUUG1ea+MFdqR2R3xSpNU8=
github.com/pion/rtp v1.8.3/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU=
github.com/pion/sctp v1.8.12 h1:2VX50pedElH+is6FI+OKyRTeN5oy4mrk2HjnGa3UCmY=
github.com/pion/sctp v1.8.12/go.mod h1:cMLT45jqw3+jiJCrtHVwfQLnfR0MGZ4rgOJwUOIqLkI=
github.com/pion/sdp/v3 v3.0.6 h1:WuDLhtuFUUVpTfus9ILC4HRyHsW6TdugjEX/QY9OiUw=
github.com/pion/sdp/v3 v3.0.6/go.mod h1:iiFWFpQO8Fy3S5ldclBkpXqmWy02ns78NOKoLLL0YQw=
github.com/pion/srtp/v2 v2.0.18 h1:vKpAXfawO9RtTRKZJbG4y0v1b11NZxQnxRl85kGuUlo=
github.com/pion/srtp/v2 v2.0.18/go.mod h1:0KJQjA99A6/a0DOVTu1PhDSw0CXF2jTkqOoMg3ODqdA=
github.com/pion/stun v0.6.1 h1:8lp6YejULeHBF8NmV8e2787BogQhduZugh5PdhDyyN4=
github.com/pion/stun v0.6.1/go.mod h1:/hO7APkX4hZKu/D0f2lHzNyvdkTGtIy3NDmLR7kSz/8=
github.com/pion/transport/v2 v2.2.3 h1:XcOE3/x41HOSKbl1BfyY1TF1dERx7lVvlMCbXU7kfvA=
github.com/pion/transport/v2 v2.2.3/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0=
github.com/pion/turn/v2 v2.1.3 h1:pYxTVWG2gpC97opdRc5IGsQ1lJ9O/IlNhkzj7MMrGAA=
github.com/pion/turn/v2 v2.1.3/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY=
github.com/pion/webrtc/v3 v3.2.28 h1:ienStxZ6HcjtH2UlmnFpMM0loENiYjaX437uIUpQSKo=
github.com/pion/webrtc/v3 v3.2.28/go.mod h1:PNRCEuQlibrmuBhOTnol9j6KkIbUG11aHLEfNpUYey0=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU=
github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k=
github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw=
github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI=
github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSzKKE=
github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc=
github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo=
github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo=
github.com/puzpuzpuz/xsync/v3 v3.1.0 h1:EewKT7/LNac5SLiEblJeUu8z5eERHrmRLnMQL2d7qX4=
github.com/puzpuzpuz/xsync/v3 v3.1.0/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA=
github.com/redis/go-redis/v9 v9.5.1 h1:H1X4D3yHPaYrkL5X06Wh6xNVM/pX0Ft4RV0vMGvLBh8=
github.com/redis/go-redis/v9 v9.5.1/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0=
github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0=
github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY=
github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
@ -128,13 +220,25 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/twitchtv/twirp v8.1.3+incompatible h1:+F4TdErPgSUbMZMwp13Q/KgDVuI7HJXP61mNV3/7iuU=
github.com/twitchtv/twirp v8.1.3+incompatible/go.mod h1:RRJoFSAmTEh2weEqWtpPE3vFK5YBhA6bqp2l1kfCC5A=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0=
github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA=
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
go.uber.org/zap/exp v0.2.0 h1:FtGenNNeCATRB3CmB/yEUnjEFeJWpB/pMcy7e2bKPYs=
go.uber.org/zap/exp v0.2.0/go.mod h1:t0gqAIdh1MfKv9EwN/dLwfZnJxe9ITAZN78HEWPFWDQ=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
@ -142,12 +246,14 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=
golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 h1:LfspQV/FYTatPTr/3HzIcmiUFH7PGP+OQ6mgDYo3yuQ=
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -156,23 +262,20 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -181,17 +284,11 @@ golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@ -201,22 +298,20 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
@ -224,10 +319,11 @@ golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0=
golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@ -236,6 +332,12 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU=
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90=
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da h1:noIWHXmPHxILtqtCOPIhSt0ABwskkZKjD3bXGnZGpNY=
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240221002015-b0ce06bbee7c h1:NUsgEN92SQQqzfA+YtqYNqYmB3DMMYLlIwUZAQFVFbo=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240221002015-b0ce06bbee7c/go.mod h1:H4O17MA/PE9BsGx3w+a+W2VOLLD1Qf7oJneAoU6WktY=
google.golang.org/grpc v1.62.0 h1:HQKZ/fa1bXkX1oFOvSjmZEUL8wLSaZTjCcLAlmZRtdk=
google.golang.org/grpc v1.62.0/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@ -244,19 +346,20 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@ -5,6 +5,7 @@ import (
"encoding/json"
"io"
"net/http"
"time"
)
func HttpGetId(url string) (response map[string]string, err error) {
@ -25,8 +26,11 @@ func HttpGetId(url string) (response map[string]string, err error) {
return srvId, nil
}
func HttpPostMessage(url string, msg []byte) (response []byte, err error) {
resp, err := http.Post(url+"/msg",
func HttpPostMessage(url string, msg []byte, timeout int) (response []byte, err error) {
client := http.Client{
Timeout: time.Duration(timeout) * time.Second,
}
resp, err := client.Post(url+"/msg",
"application/octet-stream", bytes.NewBuffer(msg))
if err != nil {
return nil, err

97
lokiwriter.go Normal file
View File

@ -0,0 +1,97 @@
package meowlib
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"time"
)
type LokiWriter struct {
url string
labels map[string]string
httpClient *http.Client
}
type LokiPayload struct {
Streams []LokiStream `json:"streams"`
}
type LokiStream struct {
Stream map[string]string `json:"stream"`
Values [][]string `json:"values"`
}
func NewLokiWriter(url string, labels map[string]string) *LokiWriter {
return &LokiWriter{
url: url,
labels: labels,
httpClient: &http.Client{},
}
}
func (w *LokiWriter) Write(p []byte) (n int, err error) {
// Use zerolog to parse the log level
var event map[string]interface{}
if err := json.Unmarshal(p, &event); err != nil {
return 0, fmt.Errorf("failed to unmarshal log event: %w", err)
}
level := ""
if l, ok := event["level"].(string); ok {
level = l
}
message := ""
if m, ok := event["message"].(string); ok {
message = m
}
// Add log level to labels
labels := make(map[string]string)
for k, v := range w.labels {
labels[k] = v
}
labels["level"] = level
// Format the timestamp in nanoseconds
timestamp := fmt.Sprintf("%d000000", time.Now().UnixNano()/int64(time.Millisecond))
stream := LokiStream{
Stream: labels,
Values: [][]string{
{timestamp, message},
},
}
payload := LokiPayload{
Streams: []LokiStream{stream},
}
payloadBytes, err := json.Marshal(payload)
if err != nil {
return 0, fmt.Errorf("failed to marshal payload: %w", err)
}
//fmt.Printf("Sending payload to Loki: %s\n", string(payloadBytes))
req, err := http.NewRequest("POST", w.url, bytes.NewReader(payloadBytes))
if err != nil {
return 0, fmt.Errorf("failed to create HTTP request: %w", err)
}
req.Header.Set("Content-Type", "application/json")
resp, err := w.httpClient.Do(req)
if err != nil {
return 0, fmt.Errorf("failed to send log to Loki: %w", err)
}
defer resp.Body.Close()
//fmt.Printf("Loki response status: %d\n", resp.StatusCode)
if resp.StatusCode != http.StatusNoContent {
return 0, fmt.Errorf("received non-204 response from Loki: %d", resp.StatusCode)
}
return len(p), nil
}

File diff suppressed because it is too large Load Diff

View File

@ -26,20 +26,19 @@ message Invitation {
int32 timeout = 2; // how long do I want the invitation to remain available on the server
int32 shortcodeLen = 3; // len of the shortcode you wish for short url transmission
string shortcode = 4; // shortcode that the friend shall request to get the invitation
string password = 5; // password tou set for accessin invitation (optional)
string password = 5; // password to set for accessing invitation (optional)
string uuid = 6; // id that the friend gave you, that you should include to your reply to get recognized
int64 expiry = 7; // the server allowed expiry date, it may be samller than the requested timeout according to server policy
int32 step = 8; // progress in the inviattion process : 1=invite friend, 2=friend requests invitation, 3=friend's answer
string from=9; // used in step 3 the answer public key to check the signature in user message
}
// structure for requesting incoming messages
message ConversationRequest {
string lookup_key = 1; // lookup key for a conversation
// removed string lastServerUuidOK = 2; // Last Server message UUID received (send me all after that one)
int64 send_timestamp = 2;
string lookup_signature = 3; // prove that I own the private key by signing that block
bool delivery_request = 2; // look for for delivery tracking, key is implicit, "from" field is used
int64 send_timestamp = 3;
string lookup_signature = 4; // prove that I own the private key by signing that block
}
message Meet {
@ -48,6 +47,13 @@ message Meet {
string message = 3; // short description
}
message Credentials {
string login = 1; // login
string password = 2; // password
string public_key = 3; // public key
string private_key = 4; // private key
}
// structure defining a message for a server, that will be encrypted, then sent in a "packedmessage" payload
message ToServerMessage {
string type = 1; // Type 1 : final destination / 2 : forward
@ -67,11 +73,14 @@ message ToServerMessage {
Invitation invitation = 9; // invitation for the 2 first steps of a "through server" invitation process
repeated PackedUserMessage device_messages = 10; // messages to another device belonging to the same user
int64 timeout = 11; // timeout expected by the client for the server to answer (long polling)
VideoData video_data = 12; // video call data
Credentials credentials = 13; // credentials for a new user or mandatory server creds
}
message ConversationResponse {
repeated string messageUuids = 1;
}
// structure defining a from server receiver message decrypted from a "packedmessage" payload
message FromServerMessage {
@ -89,7 +98,9 @@ message FromServerMessage {
repeated PackedUserMessage device_messages = 9; // messages from other devices belonging to the same user
VideoData video_data = 10; // video call data
repeated ContactCard contact_card = 11; // contact list for a personae
}
message MatriochkaServer {
@ -135,15 +146,16 @@ message PackedUserMessage {
bytes payload=2; // the message UserMessage encrypted with the destination peer's public key
bytes signature=3; // the payload signature with the client identity private key
repeated int64 serverTimestamp=4; // server time stamp, might be several in matriochka mode
string server_delivery_uuid=5; // message uuid, for server delivery tracking, omitted if not delivery tracking desired
}
message ConversationStatus {
string uuid = 1;
string answer_to_uuid=2; // message is an answer to another one, specify uuid here
uint64 localSequence = 3 ;
uint64 sent = 4 ;
uint64 received = 5;
uint64 processed = 6;
uint64 localSequence = 3 ; // seq number in local conversation for custom reordering
uint64 sent = 4 ; // timestamp of the message sent
uint64 received = 5; // timestamp of the message received
uint64 processed = 6; // timestamp of the message processed
ContactCard my_next_identity = 7;
int32 peer_next_identityAck = 8; // version of the new peer accepted id
}
@ -153,23 +165,32 @@ message Group{
repeated ContactCard members = 2;
}
// structure defining information that might be exchanged between two peers.
message UserMessage {
string destination = 1; // Lookupkey
string from = 2; // My public key for that contact
string type = 3;
string type = 3; // Message type
bytes data = 4;
ConversationStatus Status = 5;
ConversationStatus status = 5;
ContactCard contact = 6;
ServerCard knownServers = 7;
Group group = 8;
repeated File files = 9;
Location currentLocation = 10;
Location current_location = 10;
bytes appdata = 11;
Invitation invitation = 12;
VideoData video_data = 13;
}
// UserMessage types :
// 1 : normal message (test, image, video, audio, file, etc)
// 2 : status message (online, offline, busy, etc)
// 3 : send avatar as file[0]
// 4 : location request
// 5 : location response
message File {
string filename=1; // the proposed filename
uint64 size=2; // the file size
@ -195,4 +216,19 @@ message DbMessage {
Location current_location = 8;
bytes appdata = 9;
Invitation invitation = 10;
string from = 11; // source peer uid, used when storing group conversations with more than one peer
}
message VideoData {
string url = 1;
string room = 2;
uint64 duration = 3;
repeated VideoCredential credentials = 4;
repeated string media_query = 5;
}
message VideoCredential {
string username = 1;
string shared_key = 2;
string token = 3;
}

View File

@ -22,6 +22,7 @@ type Identity struct {
OwnerPublicKey string `json:"owner_public_key,omitempty"`
ArchiveClients []string `json:"archive_clients,omitempty"`
KnownServers []meowlib.ServerCard `json:"known_servers,omitempty"`
VideoServer VideoServer `json:"video_server,omitempty"`
}
func CreateIdentity(ServerName string, ServerDesc string) *Identity {

12
server/logger.go Normal file
View File

@ -0,0 +1,12 @@
package server
import (
"github.com/rs/zerolog"
)
var logger zerolog.Logger
// AddLogger sets the logger for the sublibrary
func AddLogger(l zerolog.Logger) {
logger = l
}

View File

@ -2,6 +2,7 @@ package server
import (
"context"
"sync"
"time"
"forge.redroom.link/yves/meowlib"
@ -37,7 +38,7 @@ func NewRedisRouter(server *Identity, redisUrl string, password string, db int,
}
func (r *RedisRouter) Route(msg *meowlib.ToServerMessage) (*meowlib.FromServerMessage, error) {
var from_server meowlib.FromServerMessage
var from_server *meowlib.FromServerMessage
// update messages counter
err := r.Client.Incr("statistics:messages:total").Err()
if err != nil {
@ -45,89 +46,43 @@ func (r *RedisRouter) Route(msg *meowlib.ToServerMessage) (*meowlib.FromServerMe
}
// user message => store
if len(msg.Messages) > 0 {
// update messages counter
err := r.Client.Incr("statistics:messages:usermessages").Err()
logger.Info().Msg("storing message")
from_server, err = r.storeMessage(msg)
if err != nil {
panic(err)
return nil, err
}
for _, usrmsg := range msg.Messages {
// serialize the message to store it as byte array into redis
out, err := proto.Marshal(usrmsg)
if err != nil {
return nil, err
}
r.Client.ZAdd(usrmsg.Destination, redis.Z{Score: float64(time.Now().Unix()), Member: out})
}
from_server.UuidAck = msg.Uuid
}
// check for messages
if len(msg.PullRequest) > 0 {
//dataFound := false
// update messages counter
err := r.Client.Incr("statistics:messages:messagelookups").Err()
logger.Info().Msg("checking for messages")
from_server, err = r.checkForMessage(msg)
if err != nil {
panic(err)
return nil, err
}
for _, rq := range msg.PullRequest {
// get messages from redis
msgcnt, err := r.Client.ZCount(rq.LookupKey, "-inf", "+inf").Result()
if msg.Timeout > 0 {
logger.Info().Msg("long poll, subscribing for messages")
// set timeout for the lookup
from_server, err = r.subscribe(msg, int(msg.Timeout))
if err != nil {
return nil, err
}
res, err := r.Client.ZPopMin(rq.LookupKey, msgcnt).Result()
if err != nil {
return nil, err
}
// iterate over messages
for _, redismsg := range res {
//println(redismsg.Score)
val := redismsg.Member
test := val.(string)
var usrmsg meowlib.PackedUserMessage
err := proto.Unmarshal([]byte(test), &usrmsg)
if err != nil {
return nil, err
}
// add server timestamp
usrmsg.ServerTimestamp = append(usrmsg.ServerTimestamp, int64(redismsg.Score))
from_server.Chat = append(from_server.Chat, &usrmsg)
}
// if no messages check for invitationanswer payload
if msgcnt == 0 {
// get invitation answer
var answer meowlib.Invitation
storedAnswer, _ := r.GetAnswerToInvitation(rq.LookupKey)
if storedAnswer != nil {
err := proto.Unmarshal(storedAnswer, &answer)
if err != nil {
from_server.Invitation.Payload = []byte("invitation answer corrupted")
}
from_server.Invitation = &answer
// exit loop if invitation found, cannot store several in a message
return &from_server, nil
}
// add invitation answer to the response
}
}
}
// initiate video
if msg.VideoData != nil {
logger.Info().Msg("handling video")
from_server, err = r.handleVideo(msg)
if err != nil {
return nil, err
}
}
// manage Matriochka
if msg.MatriochkaMessage != nil {
// update messages counter
err := r.Client.Incr("statistics:messages:matriochka").Err()
if err != nil {
panic(err)
}
out, err := proto.Marshal(msg)
logger.Info().Msg("handling matriochka")
from_server, err = r.handleMatriochka(msg)
if err != nil {
return nil, err
}
r.Client.ZAdd("mtk", redis.Z{Score: float64(time.Now().Unix()), Member: out})
if msg.MatriochkaMessage.LookupKey != "" {
//r.Client.ZAdd("trk:" + msg.MatriochkaMessage.Next.Uuid,{})
}
from_server.UuidAck = msg.Uuid
}
// Server list exchange
if len(msg.KnownServers) > 0 {
@ -135,64 +90,10 @@ func (r *RedisRouter) Route(msg *meowlib.ToServerMessage) (*meowlib.FromServerMe
}
// Through server invitation process
if msg.Invitation != nil {
// update messages counter
err := r.Client.Incr("statistics:messages:invitation").Err()
logger.Info().Msg("handling invitation")
from_server, err = r.handleInvitation(msg)
if err != nil {
panic(err)
}
switch msg.Invitation.Step {
// create invitation => provide shortcode and expiry
case 1:
url, expiry := r.StoreInvitation(msg.Invitation.Payload, int(msg.Invitation.Timeout), msg.Invitation.Password, r.InvitationTimeout, int(msg.Invitation.ShortcodeLen))
from_server.Invitation = &meowlib.Invitation{}
from_server.Invitation.Shortcode = url
from_server.Invitation.Expiry = expiry.UTC().Unix()
// get invitation => retrieve invitation from redis and send
case 2:
from_server.Invitation = &meowlib.Invitation{}
invitation, err := r.GetInvitation(msg.Invitation.Shortcode, msg.Invitation.Password)
if err != nil {
if err.Error() == "auth failed" {
from_server.Invitation.Payload = []byte("authentication failure")
} else {
from_server.Invitation.Payload = []byte("invitation expired")
}
} else {
from_server.Invitation.Payload = invitation // protobuf invitation
}
// accept invitation => store accepted invitation for initiator
case 3:
var usermsg meowlib.PackedUserMessage
err := proto.Unmarshal(msg.Invitation.Payload, &usermsg)
if err != nil {
return nil, err
}
data, err := proto.Marshal(msg.Invitation)
if err != nil {
return nil, err
}
expiry := r.StoreAnswerToInvitation(usermsg.Destination, int(msg.Invitation.Timeout), data, r.InvitationTimeout)
from_server.Invitation = &meowlib.Invitation{}
from_server.Invitation.Expiry = expiry.UTC().Unix()
// DONE IN NORMAL MESSAGE FLOW
// get accepted invitation => send accepted invitation to initiator
/* case 4:
from_server.Invitation = &meowlib.Invitation{}
var answer meowlib.Invitation
storedAanswer, err := r.GetAnswerToInvitation(msg.Invitation.Uuid)
if err != nil {
from_server.Invitation.Payload = []byte("invitation answer not found")
} else {
err := proto.Unmarshal(storedAanswer, &answer)
if err != nil {
from_server.Invitation.Payload = []byte("invitation answer corrupted")
}
from_server.Invitation = &answer
}
*/
return nil, err
}
}
/*
@ -208,5 +109,237 @@ func (r *RedisRouter) Route(msg *meowlib.ToServerMessage) (*meowlib.FromServerMe
break
}
*/
return from_server, nil
}
func (r *RedisRouter) storeMessage(msg *meowlib.ToServerMessage) (*meowlib.FromServerMessage, error) {
var from_server meowlib.FromServerMessage
// update messages counter
err := r.Client.Incr("statistics:messages:usermessages").Err()
if err != nil {
return nil, err
}
for _, usrmsg := range msg.Messages {
// serialize the message to store it as byte array into redis
out, err := proto.Marshal(usrmsg)
if err != nil {
return nil, err
}
r.Client.ZAdd("msg:"+usrmsg.Destination, redis.Z{Score: float64(time.Now().Unix()), Member: out})
r.Client.Publish("msgch:"+usrmsg.Destination, "!")
// if delivery tracking resquested, store the uid for the sender's key in delivery tracking
if usrmsg.ServerDeliveryUuid != "" {
r.Client.SAdd("dvyrq:"+usrmsg.ServerDeliveryUuid, redis.Z{Score: float64(time.Now().Unix()), Member: msg.From})
}
}
from_server.UuidAck = msg.Uuid
return &from_server, nil
}
func (r *RedisRouter) checkForMessage(msg *meowlib.ToServerMessage) (*meowlib.FromServerMessage, error) {
var from_server meowlib.FromServerMessage
//dataFound := false
// update messages counter
err := r.Client.Incr("statistics:messages:messagelookups").Err()
if err != nil {
return nil, err
}
// todo check pull requests signature
// iterate over pull requests
for _, rq := range msg.PullRequest {
// get messages from redis
msgcnt, err := r.Client.ZCount("msg:"+rq.LookupKey, "-inf", "+inf").Result()
if err != nil {
return nil, err
}
res, err := r.Client.ZPopMin("msg:"+rq.LookupKey, msgcnt).Result()
if err != nil {
return nil, err
}
// iterate over messages
for _, redismsg := range res {
//println(redismsg.Score)
val := redismsg.Member
test := val.(string)
var usrmsg meowlib.PackedUserMessage
err := proto.Unmarshal([]byte(test), &usrmsg)
if err != nil {
return nil, err
}
// add server timestamp
usrmsg.ServerTimestamp = append(usrmsg.ServerTimestamp, int64(redismsg.Score))
from_server.Chat = append(from_server.Chat, &usrmsg)
// if delivery for that pick up requested, create, store and publish delivery message
deliveryRequester, err := r.Client.SPop("msg:" + usrmsg.ServerDeliveryUuid).Result()
if err != nil {
if err != redis.Nil { // exit only if real error
return nil, err
}
}
if err != redis.Nil {
// create a delivery record
r.Client.ZAdd("dvy:"+deliveryRequester, redis.Z{Score: float64(time.Now().Unix()), Member: usrmsg.ServerDeliveryUuid})
// publish it in case of listener
r.Client.Publish("dvych:"+usrmsg.ServerDeliveryUuid, "!")
}
}
// if no messages check for invitationanswer payload
if msgcnt == 0 {
// get invitation answer
var answer meowlib.Invitation
storedAnswer, _ := r.GetAnswerToInvitation(rq.LookupKey)
if storedAnswer != nil {
err := proto.Unmarshal(storedAnswer, &answer)
if err != nil {
from_server.Invitation.Payload = []byte("invitation answer corrupted")
}
from_server.Invitation = &answer
// exit loop if invitation found, cannot store several in a message
return &from_server, nil
}
// add invitation answer to the response
}
}
return &from_server, nil
}
func goSubscribeAndListen(client *redis.Client, key string, messages chan<- string, wg *sync.WaitGroup, done <-chan struct{}) {
defer wg.Done()
pubsub := client.Subscribe("msgch:" + key)
defer pubsub.Close()
// Create a new channel for the messages from this subscription
myMessages := make(chan *redis.Message)
go func() {
for {
msg, err := pubsub.ReceiveMessage()
if err != nil {
close(myMessages)
return
}
myMessages <- msg
}
}()
// Wait for a message or for the done signal
select {
case msg := <-myMessages:
messages <- msg.Payload
case <-done:
return
}
}
func (r *RedisRouter) subscribe(msg *meowlib.ToServerMessage, timeout int) (*meowlib.FromServerMessage, error) {
var from_server meowlib.FromServerMessage
// update messages counter
err := r.Client.Incr("statistics:messages:messagessubscription").Err()
if err != nil {
return nil, err
}
messages := make(chan string)
var wg sync.WaitGroup
done := make(chan struct{})
// extract lookup keys and subscribe
// iterate over pull requests
for _, rq := range msg.PullRequest {
wg.Add(1)
// subscribe to the lookup key
go goSubscribeAndListen(r.Client, rq.LookupKey, messages, &wg, done)
}
// wait for timeout or message
select {
case <-messages:
close(done)
return r.checkForMessage(msg)
case <-time.After(time.Duration(timeout) * time.Second): // 10 seconds timeout
close(done)
}
wg.Wait()
return &from_server, nil
}
func (r *RedisRouter) handleInvitation(msg *meowlib.ToServerMessage) (*meowlib.FromServerMessage, error) {
var from_server meowlib.FromServerMessage
// update messages counter
err := r.Client.Incr("statistics:messages:invitation").Err()
if err != nil {
return nil, err
}
switch msg.Invitation.Step {
// create invitation => provide shortcode and expiry
case 1:
url, expiry := r.StoreInvitation(msg.Invitation.Payload, int(msg.Invitation.Timeout), msg.Invitation.Password, r.InvitationTimeout, int(msg.Invitation.ShortcodeLen))
from_server.Invitation = &meowlib.Invitation{}
from_server.Invitation.Shortcode = url
from_server.Invitation.Expiry = expiry.UTC().Unix()
// get invitation => retrieve invitation from redis and send
case 2:
from_server.Invitation = &meowlib.Invitation{}
invitation, err := r.GetInvitation(msg.Invitation.Shortcode, msg.Invitation.Password)
if err != nil {
if err.Error() == "auth failed" {
from_server.Invitation.Payload = []byte("authentication failure")
} else {
from_server.Invitation.Payload = []byte("invitation expired")
}
} else {
from_server.Invitation.Payload = invitation // protobuf invitation
}
// accept invitation => store accepted invitation for initiator
case 3:
var usermsg meowlib.PackedUserMessage
err := proto.Unmarshal(msg.Invitation.Payload, &usermsg)
if err != nil {
return nil, err
}
data, err := proto.Marshal(msg.Invitation)
if err != nil {
return nil, err
}
expiry := r.StoreAnswerToInvitation(usermsg.Destination, int(msg.Invitation.Timeout), data, r.InvitationTimeout)
from_server.Invitation = &meowlib.Invitation{}
from_server.Invitation.Expiry = expiry.UTC().Unix()
}
return &from_server, nil
}
func (r *RedisRouter) handleVideo(msg *meowlib.ToServerMessage) (*meowlib.FromServerMessage, error) {
var from_server meowlib.FromServerMessage
// update messages counter
err := r.Client.Incr("statistics:messages:video").Err()
if err != nil {
return nil, err
}
videoData, err := r.ServerIdentity.VideoServer.UpdateVideoData(msg.VideoData)
if err != nil {
return nil, err
}
from_server.VideoData = videoData
from_server.UuidAck = msg.Uuid
return &from_server, nil
}
func (r *RedisRouter) handleMatriochka(msg *meowlib.ToServerMessage) (*meowlib.FromServerMessage, error) {
var from_server meowlib.FromServerMessage
// update messages counter
err := r.Client.Incr("statistics:messages:matriochka").Err()
if err != nil {
return nil, err
}
out, err := proto.Marshal(msg)
if err != nil {
return nil, err
}
r.Client.ZAdd("mtk", redis.Z{Score: float64(time.Now().Unix()), Member: out})
if msg.MatriochkaMessage.LookupKey != "" {
//r.Client.ZAdd("trk:" + msg.MatriochkaMessage.Next.Uuid,{})
}
from_server.UuidAck = msg.Uuid
return &from_server, nil
}

41
server/videoserver.go Normal file
View File

@ -0,0 +1,41 @@
package server
import (
"time"
"forge.redroom.link/yves/meowlib"
"github.com/livekit/protocol/auth"
)
type VideoServer struct {
Url string `json:"url,omitempty"`
ApiKey string `json:"api_key,omitempty"`
ApiSecret string `json:"api_secret,omitempty"`
}
func (s *VideoServer) GetJoinToken(room, username string, validity time.Duration) (string, error) {
at := auth.NewAccessToken(s.ApiKey, s.ApiSecret)
grant := &auth.VideoGrant{
RoomJoin: true,
Room: room,
}
at.AddGrant(grant).
SetIdentity(username).
SetValidFor(validity)
return at.ToJWT()
}
func (s *VideoServer) UpdateVideoData(vd *meowlib.VideoData) (*meowlib.VideoData, error) {
vd.Url = s.Url
vd.Credentials = []*meowlib.VideoCredential{}
for idx := range len(vd.Credentials) {
token, err := s.GetJoinToken(vd.Room, vd.Credentials[idx].Username, time.Duration(vd.Duration*uint64(time.Second)))
if err != nil {
return nil, err
}
vd.Credentials[idx].Token = token
vd.Credentials[idx].SharedKey = s.ApiKey
}
return vd, nil
}