Compare commits
394 Commits
18a4321685
...
master
Author | SHA1 | Date | |
---|---|---|---|
ef20829b2e | |||
e716f5700c | |||
b327e08062 | |||
6ada023cea | |||
7389f70128 | |||
cc7c96311f | |||
d3d7c4b573 | |||
3d58ff2391 | |||
9cda542b01 | |||
e1d7b4e20b | |||
a4c6e9a905 | |||
c8e8104d5d | |||
de28ae027f | |||
a5033c0fb0 | |||
742edaa9e2 | |||
9712119238 | |||
f8a4924d56 | |||
fa3561ae58 | |||
548bd6984b | |||
27e1196130 | |||
173ef92c01 | |||
23e5ba432b | |||
2ead62ecce | |||
b18dd5ef82 | |||
c4758c6217 | |||
f9aa4e3c10 | |||
34c2d0d5e7 | |||
82fa877cad | |||
73683d66e8 | |||
ecaace5616 | |||
db018b35f9 | |||
45dd50ccba | |||
bcb2cd2f9c | |||
32e91e2601 | |||
35e5eadb05 | |||
651a738646 | |||
e43b9c9341 | |||
dfc85c5913 | |||
879cd7991b | |||
84c1a8f836 | |||
0f9bde2533 | |||
1ed9816b12 | |||
8ca5573b86 | |||
8c600daf86 | |||
bdef101bc0 | |||
d6c364ceb3 | |||
0c0164c2e8 | |||
53d856c7a7 | |||
bc31a94c98 | |||
0fac34edfb | |||
5979fd5b2c | |||
4616f7cc93 | |||
378c60cef8 | |||
af2bc29068 | |||
07d9335180 | |||
e737d31fd9 | |||
701d9b1929 | |||
e2e0cdc9b0 | |||
e65713a5b2 | |||
816ee07947 | |||
6db14a71af | |||
a649f468fc | |||
2f541f2346 | |||
bac655c1cf | |||
a2d033b56c | |||
76cc34c90a | |||
160fc79a07 | |||
59e1bf1ddf | |||
badae3aa0d | |||
11ca7c0ba6 | |||
09dddf7721 | |||
4fa155cafb | |||
1bb73c996b | |||
76682ab27f | |||
64fd2f3cd9 | |||
497c0692ca | |||
a08372d4d2 | |||
271e61510e | |||
4bf28e5298 | |||
7ff93f1344 | |||
a40ab9efdb | |||
bf7c10d195 | |||
17a99cce61 | |||
7dbb552dd2 | |||
7d1165b87b | |||
eaa8fb5225 | |||
ec0048042a | |||
62a3168190 | |||
79844c414b | |||
cd01657857 | |||
b68aed0284 | |||
d7ee87433f | |||
820d96f6b0 | |||
509390b38a | |||
78d624697c | |||
5b1c0784ec | |||
e115374589 | |||
09010d5867 | |||
867a556204 | |||
71e959805f | |||
fabde24734 | |||
123342b13b | |||
dd9a44d126 | |||
dc2de65245 | |||
a43e89a5a3 | |||
0db2967214 | |||
0dbc30d53c | |||
e4ba72725e | |||
144219f0aa | |||
72d0cbb7be | |||
1f75a9e64b | |||
2dac1759d9 | |||
5b516094a0 | |||
6a4f2b6869 | |||
5bdc59b4af | |||
5273498af1 | |||
fcd3b56f89 | |||
61976f6c47 | |||
9c0abdb46f | |||
f33497d002 | |||
94e55a6d4e | |||
afc2ec80e9 | |||
573ccc0478 | |||
fdf2d28f51 | |||
0115e6723a | |||
02f122328a | |||
77c543f88e | |||
50498976af | |||
bede9716f1 | |||
3074cd93d8 | |||
87c3b81ad4 | |||
20ff541ab4 | |||
e0c9646c98 | |||
d3a1382711 | |||
f8492ea1af | |||
10e9813bea | |||
192a03e9d1 | |||
08c639497d | |||
312cf820ab | |||
55b3a6f164 | |||
659548a544 | |||
c16019341f | |||
1515e29d5b | |||
668d9805e2 | |||
7081cb8885 | |||
bc2e7df574 | |||
bc5a0ea966 | |||
f89a2244ea | |||
bf733da247 | |||
ca9bd7ac14 | |||
3f4fe68105 | |||
7a2ce20460 | |||
720f9690f6 | |||
663b563b39 | |||
8e1ed67c48 | |||
4695a617d7 | |||
f91be512f3 | |||
40b64a3559 | |||
808e7998dd | |||
40a0403521 | |||
b4da8ce78b | |||
d1f1183beb | |||
c3619f6d25 | |||
2b4f71e732 | |||
39ac016b46 | |||
8326c716e3 | |||
8ff2648e4c | |||
e6f6389eb0 | |||
2fcc784bc4 | |||
69c6ac6581 | |||
2d322f070a | |||
d7b1913bc3 | |||
8fbb79607b | |||
14baee03fe | |||
7a0756a5e8 | |||
4c44af74b5 | |||
b4fb7b53af | |||
e412d5e742 | |||
e83e92b054 | |||
10d977ab23 | |||
29629cead6 | |||
df8058e794 | |||
be32ad1522 | |||
8e3ce09734 | |||
974c5d9700 | |||
a4a139c56e | |||
06bd632f37 | |||
68b4390edf | |||
6ea4850459 | |||
bee9799415 | |||
821e0c3e60 | |||
39c3799d82 | |||
9287e6c5cc | |||
0f18c6ff16 | |||
94c15f58ec | |||
cb3cc3f540 | |||
cec234bc53 | |||
27b625e0c8 | |||
bbceb65dbf | |||
648f10b25a | |||
0a362dadec | |||
9174767d80 | |||
53c6b2a636 | |||
10e4a67835 | |||
ba32925b58 | |||
3031f61ea4 | |||
02bffc062f | |||
817c60c4e0 | |||
5bcce9d44e | |||
7a9e31fd86 | |||
4b4eb3e581 | |||
5203234c4a | |||
f287e295e5 | |||
df9fb0a92a | |||
ea3d6c20d3 | |||
313f6b8d4f | |||
582e6cdb61 | |||
d4ed047ed7 | |||
3ce5ef6617 | |||
a23c51f483 | |||
bfddfa2201 | |||
bee5b676fa | |||
99f8e4c891 | |||
f240226563 | |||
d205a41614 | |||
51a53a25da | |||
1bdeba58bc | |||
46c7b6dff1 | |||
b097dab9e1 | |||
52c06d9826 | |||
4b0910f6eb | |||
2b2e7b5a89 | |||
476ef57236 | |||
0f2b45352c | |||
a6b0170b1d | |||
876cfa9956 | |||
7a585ec5b9 | |||
b22657d09f | |||
8f61253bd3 | |||
516f5593de | |||
5e76fa07b7 | |||
31fcfa2bf5 | |||
9d075f862c | |||
0285b82ca2 | |||
dd3586b241 | |||
bdcc8de59b | |||
0ee3f1bc97 | |||
a97615b6c7 | |||
fe5e9c66b9 | |||
e4d73b1d31 | |||
142e7c3434 | |||
7a072988ce | |||
817c573048 | |||
c51af61820 | |||
688d026d75 | |||
ed13d62110 | |||
d2beaa67b4 | |||
e97f3b6047 | |||
57b4b314fe | |||
7c09138ef7 | |||
6ef46d984d | |||
94aed49092 | |||
ebbfd7450c | |||
c458123d9e | |||
7737d9fd08 | |||
f113719e79 | |||
2d181bfdaf | |||
24395b698e | |||
cb0fefecfb | |||
3cab122b76 | |||
e56c48362d | |||
d08b7a273d | |||
6350ec1e43 | |||
27d501d7a7 | |||
6643d31b1a | |||
b3bb7cb582 | |||
8fcaf99103 | |||
282a0891d0 | |||
7436d4b2cc | |||
7b9aebd5d7 | |||
cef0a552f4 | |||
c912271610 | |||
1ce04f7067 | |||
14bcea02d0 | |||
4795da84f9 | |||
a8d919dc5b | |||
4143a7b2c8 | |||
69fb9531cb | |||
a60be78ce6 | |||
0e7e7e6d55 | |||
d405b34747 | |||
e049b2c566 | |||
681eb3cf7f | |||
e5bdb23c09 | |||
77c1a029bd | |||
f7063fc109 | |||
3216547d46 | |||
8c7f255473 | |||
13c26486b6 | |||
46468fae5f | |||
da15c72fb3 | |||
182a389180 | |||
74819c1c2b | |||
8c89d89382 | |||
5200e00c9b | |||
a4ccf12b7a | |||
e5d8f1ab3b | |||
7e334222ee | |||
133bbcc6bc | |||
659fc8375c | |||
78604db54e | |||
0276a9b0bf | |||
9f7205ba14 | |||
17e0fa3b18 | |||
7fed35dd04 | |||
b2b8aa467b | |||
3f0d3fc69e | |||
0bce0d45c8 | |||
203465f0bb | |||
4281952c87 | |||
e36b40614d | |||
f2b8401746 | |||
feabff16ec | |||
9519497887 | |||
b1f6cf8f6e | |||
8c2649e29d | |||
7c0713a12f | |||
132d301aeb | |||
38ee30f455 | |||
ebdb6f5688 | |||
ab5130de2a | |||
7aef153bf3 | |||
f69f1026d8 | |||
7e4ca530fa | |||
d540e86603 | |||
200a1f9dfc | |||
1c1b287650 | |||
ea33857afb | |||
880ed9a999 | |||
8044a1e5f2 | |||
6667bff188 | |||
21d3d71936 | |||
0d02eca76e | |||
3f64747839 | |||
1cf675b23a | |||
86b2cd8140 | |||
7ddbea8bcb | |||
b919e100e0 | |||
18ae5f12e2 | |||
4537bc9f28 | |||
d654931483 | |||
a4ec986b77 | |||
7007cda8f2 | |||
c37a55b88b | |||
d9aa478d10 | |||
5a3c6fcada | |||
d2fdb5a72b | |||
9c3b42f078 | |||
80ee964afa | |||
69fdee72f5 | |||
45048ea814 | |||
0695338fa1 | |||
ef055e1144 | |||
6d035c1147 | |||
5b06b2dccb | |||
3010d4f2a4 | |||
bcab6dfc51 | |||
daaac3667c | |||
b76e7d41cf | |||
533745e0e4 | |||
b44786ae9a | |||
332557778d | |||
b925d54000 | |||
6a37ee4487 | |||
f1ab0f203f | |||
1c36b429ea | |||
61eff6ea49 | |||
c7ba566c48 | |||
727b259ca7 | |||
4fb4abda89 | |||
31139e943f | |||
a502f11ebc | |||
ee4f929d6c | |||
fd5bbd732f | |||
ebef35a619 | |||
1e2d5e9f9d | |||
73b57164ab | |||
8ae6292bf0 | |||
4e4fbb8ba9 | |||
7d3b804516 | |||
0e89e325d4 | |||
07dbdd80ec | |||
bcfe1d3927 | |||
3ba152252e |
5
.gitignore
vendored
5
.gitignore
vendored
@ -1,2 +1,7 @@
|
|||||||
/dist
|
/dist
|
||||||
/uploads
|
/uploads
|
||||||
|
/keys
|
||||||
|
|
||||||
|
geoip.mmdb
|
||||||
|
|
||||||
|
.DS_Store
|
||||||
|
12
.idea/Passport.iml
generated
12
.idea/Passport.iml
generated
@ -1,12 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<module type="WEB_MODULE" version="4">
|
|
||||||
<component name="Go" enabled="true" />
|
|
||||||
<component name="NewModuleRootManager">
|
|
||||||
<content url="file://$MODULE_DIR$" />
|
|
||||||
<orderEntry type="inheritedJdk" />
|
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
|
||||||
<orderEntry type="library" name="animate.css" level="application" />
|
|
||||||
<orderEntry type="library" name="tailwindcss" level="application" />
|
|
||||||
<orderEntry type="library" name="@tailwindcss/typography" level="application" />
|
|
||||||
</component>
|
|
||||||
</module>
|
|
38
.idea/dataSources.local.xml
generated
38
.idea/dataSources.local.xml
generated
@ -1,38 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="dataSourceStorageLocal" created-in="GO-241.14494.238">
|
|
||||||
<data-source name="hy_passport@localhost" uuid="74bcf3ef-a2b9-435b-b9e5-f32902a33b25">
|
|
||||||
<database-info product="PostgreSQL" version="16.2 (Homebrew)" jdbc-version="4.2" driver-name="PostgreSQL JDBC Driver" driver-version="42.6.0" dbms="POSTGRES" exact-version="16.2" exact-driver-version="42.6">
|
|
||||||
<identifier-quote-string>"</identifier-quote-string>
|
|
||||||
</database-info>
|
|
||||||
<case-sensitivity plain-identifiers="lower" quoted-identifiers="exact" />
|
|
||||||
<secret-storage>master_key</secret-storage>
|
|
||||||
<user-name>postgres</user-name>
|
|
||||||
<schema-mapping>
|
|
||||||
<introspection-scope>
|
|
||||||
<node negative="1">
|
|
||||||
<node kind="database" qname="@">
|
|
||||||
<node kind="schema" qname="@" />
|
|
||||||
</node>
|
|
||||||
<node kind="database" qname="hy_passport" />
|
|
||||||
</node>
|
|
||||||
</introspection-scope>
|
|
||||||
</schema-mapping>
|
|
||||||
</data-source>
|
|
||||||
<data-source name="passport@id.solsynth.dev" uuid="723637bc-6ce3-4bbe-afb3-d88730c75a1b">
|
|
||||||
<database-info product="PostgreSQL" version="16.2 (Ubuntu 16.2-1.pgdg22.04+1)" jdbc-version="4.2" driver-name="PostgreSQL JDBC Driver" driver-version="42.6.0" dbms="POSTGRES" exact-version="16.2" exact-driver-version="42.6">
|
|
||||||
<identifier-quote-string>"</identifier-quote-string>
|
|
||||||
</database-info>
|
|
||||||
<case-sensitivity plain-identifiers="lower" quoted-identifiers="exact" />
|
|
||||||
<secret-storage>master_key</secret-storage>
|
|
||||||
<user-name>postgres</user-name>
|
|
||||||
<schema-mapping>
|
|
||||||
<introspection-scope>
|
|
||||||
<node kind="database" qname="@">
|
|
||||||
<node kind="schema" qname="@" />
|
|
||||||
</node>
|
|
||||||
</introspection-scope>
|
|
||||||
</schema-mapping>
|
|
||||||
</data-source>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
19
.idea/dataSources.xml
generated
19
.idea/dataSources.xml
generated
@ -1,19 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
|
|
||||||
<data-source source="LOCAL" name="hy_passport@localhost" uuid="74bcf3ef-a2b9-435b-b9e5-f32902a33b25">
|
|
||||||
<driver-ref>postgresql</driver-ref>
|
|
||||||
<synchronize>true</synchronize>
|
|
||||||
<jdbc-driver>org.postgresql.Driver</jdbc-driver>
|
|
||||||
<jdbc-url>jdbc:postgresql://localhost:5432/hy_passport</jdbc-url>
|
|
||||||
<working-dir>$ProjectFileDir$</working-dir>
|
|
||||||
</data-source>
|
|
||||||
<data-source source="LOCAL" name="passport@id.solsynth.dev" uuid="723637bc-6ce3-4bbe-afb3-d88730c75a1b">
|
|
||||||
<driver-ref>postgresql</driver-ref>
|
|
||||||
<synchronize>true</synchronize>
|
|
||||||
<jdbc-driver>org.postgresql.Driver</jdbc-driver>
|
|
||||||
<jdbc-url>jdbc:postgresql://id.solsynth.dev:5432/passport</jdbc-url>
|
|
||||||
<working-dir>$ProjectFileDir$</working-dir>
|
|
||||||
</data-source>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
6597
.idea/dataSources/723637bc-6ce3-4bbe-afb3-d88730c75a1b.xml
generated
6597
.idea/dataSources/723637bc-6ce3-4bbe-afb3-d88730c75a1b.xml
generated
File diff suppressed because it is too large
Load Diff
@ -1 +0,0 @@
|
|||||||
#n:passport
|
|
@ -1,2 +0,0 @@
|
|||||||
#n:public
|
|
||||||
!<md> [41831, 0, null, null, -2147483648, -2147483648]
|
|
5814
.idea/dataSources/74bcf3ef-a2b9-435b-b9e5-f32902a33b25.xml
generated
5814
.idea/dataSources/74bcf3ef-a2b9-435b-b9e5-f32902a33b25.xml
generated
File diff suppressed because it is too large
Load Diff
@ -1 +0,0 @@
|
|||||||
#n:hy_passport
|
|
@ -1,2 +0,0 @@
|
|||||||
#n:public
|
|
||||||
!<md> [6992, 0, null, null, -2147483648, -2147483648]
|
|
6
.idea/inspectionProfiles/Project_Default.xml
generated
6
.idea/inspectionProfiles/Project_Default.xml
generated
@ -1,6 +0,0 @@
|
|||||||
<component name="InspectionProjectProfileManager">
|
|
||||||
<profile version="1.0">
|
|
||||||
<option name="myName" value="Project Default" />
|
|
||||||
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
|
|
||||||
</profile>
|
|
||||||
</component>
|
|
6
.idea/jsLibraryMappings.xml
generated
6
.idea/jsLibraryMappings.xml
generated
@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="JavaScriptLibraryMappings">
|
|
||||||
<file url="PROJECT" libraries="{@tailwindcss/typography, animate.css, tailwindcss}" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
8
.idea/modules.xml
generated
8
.idea/modules.xml
generated
@ -1,8 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="ProjectModuleManager">
|
|
||||||
<modules>
|
|
||||||
<module fileurl="file://$PROJECT_DIR$/.idea/Passport.iml" filepath="$PROJECT_DIR$/.idea/Passport.iml" />
|
|
||||||
</modules>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
6
.idea/vcs.xml
generated
6
.idea/vcs.xml
generated
@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="VcsDirectoryMappings">
|
|
||||||
<mapping directory="" vcs="Git" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
160
.idea/workspace.xml
generated
160
.idea/workspace.xml
generated
@ -1,160 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="AutoImportSettings">
|
|
||||||
<option name="autoReloadType" value="ALL" />
|
|
||||||
</component>
|
|
||||||
<component name="ChangeListManager">
|
|
||||||
<list default="true" id="3fefb2c4-b6f9-466b-a523-53352e8d6f95" name="更改" comment=":zap: Use map to improve message delivery time">
|
|
||||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/pkg/models/notifications.go" beforeDir="false" afterPath="$PROJECT_DIR$/pkg/models/notifications.go" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/pkg/server/notifications_api.go" beforeDir="false" afterPath="$PROJECT_DIR$/pkg/server/notifications_api.go" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/pkg/services/notifications.go" beforeDir="false" afterPath="$PROJECT_DIR$/pkg/services/notifications.go" afterDir="false" />
|
|
||||||
</list>
|
|
||||||
<option name="SHOW_DIALOG" value="false" />
|
|
||||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
|
||||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
|
||||||
<option name="LAST_RESOLUTION" value="IGNORE" />
|
|
||||||
</component>
|
|
||||||
<component name="FileTemplateManagerImpl">
|
|
||||||
<option name="RECENT_TEMPLATES">
|
|
||||||
<list>
|
|
||||||
<option value="Go File" />
|
|
||||||
</list>
|
|
||||||
</option>
|
|
||||||
</component>
|
|
||||||
<component name="GOROOT" url="file:///opt/homebrew/opt/go/libexec" />
|
|
||||||
<component name="Git.Settings">
|
|
||||||
<option name="RECENT_BRANCH_BY_REPOSITORY">
|
|
||||||
<map>
|
|
||||||
<entry key="$PROJECT_DIR$" value="master" />
|
|
||||||
</map>
|
|
||||||
</option>
|
|
||||||
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
|
||||||
</component>
|
|
||||||
<component name="ProblemsViewState">
|
|
||||||
<option name="selectedTabId" value="ProjectErrors" />
|
|
||||||
</component>
|
|
||||||
<component name="ProjectColorInfo">{
|
|
||||||
"customColor": "",
|
|
||||||
"associatedIndex": 6
|
|
||||||
}</component>
|
|
||||||
<component name="ProjectId" id="2fLXu43fjlLYVIGNrhGhOgBFq2O" />
|
|
||||||
<component name="ProjectViewState">
|
|
||||||
<option name="hideEmptyMiddlePackages" value="true" />
|
|
||||||
<option name="showLibraryContents" value="true" />
|
|
||||||
</component>
|
|
||||||
<component name="PropertiesComponent">{
|
|
||||||
"keyToString": {
|
|
||||||
"DefaultGoTemplateProperty": "Go File",
|
|
||||||
"Go 构建.Backend.executor": "Run",
|
|
||||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
|
||||||
"RunOnceActivity.go.formatter.settings.were.checked": "true",
|
|
||||||
"RunOnceActivity.go.migrated.go.modules.settings": "true",
|
|
||||||
"RunOnceActivity.go.modules.automatic.dependencies.download": "true",
|
|
||||||
"RunOnceActivity.go.modules.go.list.on.any.changes.was.set": "true",
|
|
||||||
"git-widget-placeholder": "master",
|
|
||||||
"go.import.settings.migrated": "true",
|
|
||||||
"go.sdk.automatically.set": "true",
|
|
||||||
"last_opened_file_path": "/Users/littlesheep/Documents/Projects/Hydrogen/Passport/pkg/server/ui",
|
|
||||||
"node.js.detected.package.eslint": "true",
|
|
||||||
"node.js.selected.package.eslint": "(autodetect)",
|
|
||||||
"nodejs_package_manager_path": "npm",
|
|
||||||
"run.code.analysis.last.selected.profile": "pProject Default",
|
|
||||||
"settings.editor.selected.configurable": "preferences.lookFeel",
|
|
||||||
"vue.rearranger.settings.migration": "true"
|
|
||||||
},
|
|
||||||
"keyToStringList": {
|
|
||||||
"DatabaseDriversLRU": [
|
|
||||||
"postgresql"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}</component>
|
|
||||||
<component name="RecentsManager">
|
|
||||||
<key name="CopyFile.RECENT_KEYS">
|
|
||||||
<recent name="$PROJECT_DIR$/pkg/server/ui" />
|
|
||||||
<recent name="$PROJECT_DIR$/pkg/views/users" />
|
|
||||||
<recent name="$PROJECT_DIR$/pkg/views" />
|
|
||||||
<recent name="$PROJECT_DIR$/pkg" />
|
|
||||||
</key>
|
|
||||||
<key name="MoveFile.RECENT_KEYS">
|
|
||||||
<recent name="$PROJECT_DIR$/pkg/views/users/directory" />
|
|
||||||
<recent name="$PROJECT_DIR$/pkg/views/users" />
|
|
||||||
<recent name="$PROJECT_DIR$/pkg/utils" />
|
|
||||||
<recent name="$PROJECT_DIR$/pkg/services" />
|
|
||||||
</key>
|
|
||||||
</component>
|
|
||||||
<component name="RunAnythingCache">
|
|
||||||
<myKeys>
|
|
||||||
<visibility group="Grunt" flag="true" />
|
|
||||||
<visibility group="Gulp" flag="true" />
|
|
||||||
<visibility group="HTTP 请求" flag="true" />
|
|
||||||
<visibility group="Recent projects" flag="true" />
|
|
||||||
<visibility group="Run configurations" flag="true" />
|
|
||||||
<visibility group="npm" flag="true" />
|
|
||||||
<visibility group="yarn" flag="true" />
|
|
||||||
</myKeys>
|
|
||||||
</component>
|
|
||||||
<component name="RunManager">
|
|
||||||
<configuration name="Backend" type="GoApplicationRunConfiguration" factoryName="Go Application">
|
|
||||||
<module name="Passport" />
|
|
||||||
<working_directory value="$PROJECT_DIR$" />
|
|
||||||
<kind value="FILE" />
|
|
||||||
<directory value="$PROJECT_DIR$" />
|
|
||||||
<filePath value="$PROJECT_DIR$/pkg/cmd/main.go" />
|
|
||||||
<output_directory value="$PROJECT_DIR$/dist" />
|
|
||||||
<method v="2" />
|
|
||||||
</configuration>
|
|
||||||
</component>
|
|
||||||
<component name="SharedIndexes">
|
|
||||||
<attachedChunks>
|
|
||||||
<set>
|
|
||||||
<option value="bundled-gosdk-33c477a475b1-b97fc8a1e17c-org.jetbrains.plugins.go.sharedIndexes.bundled-GO-241.14494.238" />
|
|
||||||
<option value="bundled-js-predefined-1d06a55b98c1-74d2a5396914-JavaScript-GO-241.14494.238" />
|
|
||||||
</set>
|
|
||||||
</attachedChunks>
|
|
||||||
</component>
|
|
||||||
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="应用程序级" UseSingleDictionary="true" transferred="true" />
|
|
||||||
<component name="TypeScriptGeneratedFilesManager">
|
|
||||||
<option name="version" value="3" />
|
|
||||||
</component>
|
|
||||||
<component name="Vcs.Log.Tabs.Properties">
|
|
||||||
<option name="TAB_STATES">
|
|
||||||
<map>
|
|
||||||
<entry key="MAIN">
|
|
||||||
<value>
|
|
||||||
<State />
|
|
||||||
</value>
|
|
||||||
</entry>
|
|
||||||
</map>
|
|
||||||
</option>
|
|
||||||
</component>
|
|
||||||
<component name="VcsManagerConfiguration">
|
|
||||||
<MESSAGE value=":recycle: Refactor frontend" />
|
|
||||||
<MESSAGE value=":sparkles: New ticket ways" />
|
|
||||||
<MESSAGE value=":sparkles: Sign up & Sign in" />
|
|
||||||
<MESSAGE value=":sparkles: An entire complete sign in user flow" />
|
|
||||||
<MESSAGE value=":sparkles: User center page" />
|
|
||||||
<MESSAGE value=":sparkles: Personalize" />
|
|
||||||
<MESSAGE value=":sparkles: OAuth" />
|
|
||||||
<MESSAGE value=":truck: Update well known" />
|
|
||||||
<MESSAGE value=":sparkles: Others userinfo" />
|
|
||||||
<MESSAGE value=":lipstick: Fix ui design" />
|
|
||||||
<MESSAGE value=":bug: Bug fixes of design" />
|
|
||||||
<MESSAGE value=":sparkles: Bug fixes" />
|
|
||||||
<MESSAGE value=":sparkles: Batch mark notify as read API" />
|
|
||||||
<MESSAGE value=":bug: Bug fixes of risk detection :lipstick: Optimized UI" />
|
|
||||||
<MESSAGE value=":sparkles: Realm in passport" />
|
|
||||||
<MESSAGE value=":sparkles: Realm GRPC" />
|
|
||||||
<MESSAGE value=":sparkles: Realm Member GRPC" />
|
|
||||||
<MESSAGE value=":bug: Bug fixes on forgot add realm members for account" />
|
|
||||||
<MESSAGE value=":bug: Bug fix on missing id in realm" />
|
|
||||||
<MESSAGE value=":bug: Bug fixes on realm missing member on creation" />
|
|
||||||
<MESSAGE value=":bug: Dumb man make dumb mistake again" />
|
|
||||||
<MESSAGE value=":bug: Fix new realm owner missing permissions" />
|
|
||||||
<MESSAGE value=":zap: Use map to improve message delivery time" />
|
|
||||||
<option name="LAST_COMMIT_MESSAGE" value=":zap: Use map to improve message delivery time" />
|
|
||||||
</component>
|
|
||||||
<component name="VgoProject">
|
|
||||||
<settings-migrated>true</settings-migrated>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
@ -1,16 +1,16 @@
|
|||||||
# Building Backend
|
# Building Backend
|
||||||
FROM golang:alpine as passport-server
|
FROM golang:alpine as passport-server
|
||||||
|
|
||||||
RUN apk add nodejs npm
|
|
||||||
|
|
||||||
WORKDIR /source
|
WORKDIR /source
|
||||||
COPY . .
|
COPY . .
|
||||||
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -buildvcs -o /dist ./pkg/cmd/main.go
|
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -buildvcs -o /dist ./pkg/main.go
|
||||||
|
|
||||||
# Runtime
|
# Runtime
|
||||||
FROM golang:alpine
|
FROM golang:alpine
|
||||||
|
|
||||||
COPY --from=passport-server /dist /passport/server
|
COPY --from=passport-server /dist /passport/server
|
||||||
|
COPY ./templates /templates
|
||||||
|
COPY ./locales /locales
|
||||||
|
|
||||||
EXPOSE 8444
|
EXPOSE 8444
|
||||||
|
|
||||||
|
138
go.mod
138
go.mod
@ -1,104 +1,100 @@
|
|||||||
module git.solsynth.dev/hydrogen/passport
|
module git.solsynth.dev/hypernet/passport
|
||||||
|
|
||||||
go 1.21.5
|
go 1.23.2
|
||||||
|
|
||||||
require (
|
require (
|
||||||
firebase.google.com/go v3.13.0+incompatible
|
git.solsynth.dev/hypernet/nexus v0.0.0-20250330063116-4350d197f9c6
|
||||||
github.com/go-playground/validator/v10 v10.17.0
|
git.solsynth.dev/hypernet/paperclip v0.0.0-20250310151112-1d866f317f47
|
||||||
github.com/gofiber/contrib/websocket v1.3.0
|
git.solsynth.dev/hypernet/pusher v0.0.0-20250216145944-5fb769823a88
|
||||||
github.com/gofiber/fiber/v2 v2.52.4
|
git.solsynth.dev/hypernet/wallet v0.0.0-20250323095812-468cd655f886
|
||||||
github.com/gofiber/template/html/v2 v2.1.1
|
github.com/fatih/color v1.18.0
|
||||||
github.com/golang-jwt/jwt/v5 v5.2.0
|
github.com/go-playground/validator/v10 v10.22.1
|
||||||
|
github.com/goccy/go-json v0.10.3
|
||||||
|
github.com/gofiber/contrib/fiberzerolog v1.0.2
|
||||||
|
github.com/gofiber/fiber/v2 v2.52.6
|
||||||
|
github.com/golang-jwt/jwt/v5 v5.2.1
|
||||||
github.com/google/uuid v1.6.0
|
github.com/google/uuid v1.6.0
|
||||||
github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible
|
|
||||||
github.com/json-iterator/go v1.1.12
|
github.com/json-iterator/go v1.1.12
|
||||||
|
github.com/oschwald/geoip2-golang v1.11.0
|
||||||
|
github.com/pquerna/otp v1.4.0
|
||||||
github.com/robfig/cron/v3 v3.0.1
|
github.com/robfig/cron/v3 v3.0.1
|
||||||
github.com/rs/zerolog v1.31.0
|
github.com/rs/zerolog v1.33.0
|
||||||
github.com/samber/lo v1.39.0
|
github.com/samber/lo v1.47.0
|
||||||
github.com/spf13/viper v1.18.1
|
github.com/spf13/viper v1.19.0
|
||||||
go.etcd.io/bbolt v1.3.9
|
github.com/sujit-baniya/flash v0.1.8
|
||||||
golang.org/x/crypto v0.21.0
|
golang.org/x/crypto v0.33.0
|
||||||
google.golang.org/api v0.153.0
|
google.golang.org/grpc v1.70.0
|
||||||
google.golang.org/grpc v1.59.0
|
google.golang.org/protobuf v1.36.4
|
||||||
google.golang.org/protobuf v1.31.0
|
gorm.io/datatypes v1.2.4
|
||||||
gorm.io/datatypes v1.2.0
|
gorm.io/driver/postgres v1.5.9
|
||||||
gorm.io/driver/postgres v1.5.4
|
gorm.io/gorm v1.25.12
|
||||||
gorm.io/gorm v1.25.5
|
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
cloud.google.com/go v0.110.10 // indirect
|
filippo.io/edwards25519 v1.1.0 // indirect
|
||||||
cloud.google.com/go/compute v1.23.3 // indirect
|
github.com/andybalholm/brotli v1.1.1 // indirect
|
||||||
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
cloud.google.com/go/firestore v1.14.0 // indirect
|
github.com/boombuler/barcode v1.0.2 // indirect
|
||||||
cloud.google.com/go/iam v1.1.5 // indirect
|
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||||
cloud.google.com/go/longrunning v0.5.4 // indirect
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||||
cloud.google.com/go/storage v1.35.1 // indirect
|
github.com/eko/gocache/lib/v4 v4.2.0 // indirect
|
||||||
github.com/andybalholm/brotli v1.1.0 // indirect
|
github.com/eko/gocache/store/redis/v4 v4.2.2 // indirect
|
||||||
github.com/fasthttp/websocket v1.5.8 // indirect
|
github.com/fsnotify/fsnotify v1.8.0 // indirect
|
||||||
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
|
||||||
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
|
|
||||||
github.com/go-playground/locales v0.14.1 // indirect
|
github.com/go-playground/locales v0.14.1 // indirect
|
||||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||||
github.com/go-sql-driver/mysql v1.7.1 // indirect
|
github.com/go-sql-driver/mysql v1.8.1 // indirect
|
||||||
github.com/gofiber/template v1.8.3 // indirect
|
github.com/golang/mock v1.6.0 // indirect
|
||||||
github.com/gofiber/utils v1.1.0 // indirect
|
|
||||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
|
||||||
github.com/golang/protobuf v1.5.3 // indirect
|
|
||||||
github.com/gomarkdown/markdown v0.0.0-20240419095408-642f0ee99ae2 // indirect
|
|
||||||
github.com/google/s2a-go v0.1.7 // indirect
|
|
||||||
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
|
|
||||||
github.com/googleapis/gax-go/v2 v2.12.0 // indirect
|
|
||||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||||
github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 // indirect
|
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
|
||||||
github.com/jackc/pgx/v5 v5.5.1 // indirect
|
github.com/jackc/pgx/v5 v5.7.1 // indirect
|
||||||
github.com/jackc/puddle/v2 v2.2.1 // indirect
|
github.com/jackc/puddle/v2 v2.2.2 // indirect
|
||||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||||
github.com/jinzhu/now v1.1.5 // indirect
|
github.com/jinzhu/now v1.1.5 // indirect
|
||||||
github.com/klauspost/compress v1.17.8 // indirect
|
github.com/klauspost/compress v1.18.0 // indirect
|
||||||
github.com/leodido/go-urn v1.2.4 // indirect
|
github.com/leodido/go-urn v1.4.0 // indirect
|
||||||
github.com/magiconair/properties v1.8.7 // indirect
|
github.com/magiconair/properties v1.8.7 // indirect
|
||||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
github.com/mattn/go-runewidth v0.0.15 // indirect
|
github.com/mattn/go-runewidth v0.0.16 // indirect
|
||||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
github.com/nicksnyder/go-i18n/v2 v2.4.0 // indirect
|
github.com/nats-io/nats.go v1.37.0 // indirect
|
||||||
github.com/pelletier/go-toml/v2 v2.1.1 // indirect
|
github.com/nats-io/nkeys v0.4.7 // indirect
|
||||||
github.com/philhofer/fwd v1.1.2 // indirect
|
github.com/nats-io/nuid v1.0.1 // indirect
|
||||||
|
github.com/nicksnyder/go-i18n/v2 v2.5.0 // indirect
|
||||||
|
github.com/oschwald/maxminddb-golang v1.13.0 // indirect
|
||||||
|
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
|
||||||
|
github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c // indirect
|
||||||
|
github.com/prometheus/client_golang v1.19.0 // indirect
|
||||||
|
github.com/prometheus/client_model v0.6.1 // indirect
|
||||||
|
github.com/prometheus/common v0.52.3 // indirect
|
||||||
|
github.com/prometheus/procfs v0.13.0 // indirect
|
||||||
|
github.com/redis/go-redis/v9 v9.7.3 // indirect
|
||||||
github.com/rivo/uniseg v0.4.7 // indirect
|
github.com/rivo/uniseg v0.4.7 // indirect
|
||||||
github.com/sagikazarmark/locafero v0.4.0 // indirect
|
github.com/sagikazarmark/locafero v0.6.0 // indirect
|
||||||
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
|
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
|
||||||
github.com/savsgio/gotils v0.0.0-20240303185622-093b76447511 // indirect
|
|
||||||
github.com/sourcegraph/conc v0.3.0 // indirect
|
github.com/sourcegraph/conc v0.3.0 // indirect
|
||||||
github.com/spf13/afero v1.11.0 // indirect
|
github.com/spf13/afero v1.11.0 // indirect
|
||||||
github.com/spf13/cast v1.6.0 // indirect
|
github.com/spf13/cast v1.7.0 // indirect
|
||||||
github.com/spf13/pflag v1.0.5 // indirect
|
github.com/spf13/pflag v1.0.5 // indirect
|
||||||
github.com/subosito/gotenv v1.6.0 // indirect
|
github.com/subosito/gotenv v1.6.0 // indirect
|
||||||
github.com/sujit-baniya/flash v0.1.8 // indirect
|
github.com/tinylib/msgp v1.2.5 // indirect
|
||||||
github.com/tinylib/msgp v1.1.8 // indirect
|
|
||||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||||
github.com/valyala/fasthttp v1.52.0 // indirect
|
github.com/valyala/fasthttp v1.59.0 // indirect
|
||||||
github.com/valyala/tcplisten v1.0.0 // indirect
|
go.uber.org/mock v0.4.0 // indirect
|
||||||
go.opencensus.io v0.24.0 // indirect
|
|
||||||
go.uber.org/multierr v1.11.0 // indirect
|
go.uber.org/multierr v1.11.0 // indirect
|
||||||
golang.org/x/exp v0.0.0-20231219180239-dc181d75b848 // indirect
|
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c // indirect
|
||||||
golang.org/x/net v0.22.0 // indirect
|
golang.org/x/net v0.35.0 // indirect
|
||||||
golang.org/x/oauth2 v0.15.0 // indirect
|
golang.org/x/sync v0.11.0 // indirect
|
||||||
golang.org/x/sync v0.5.0 // indirect
|
golang.org/x/sys v0.30.0 // indirect
|
||||||
golang.org/x/sys v0.19.0 // indirect
|
golang.org/x/text v0.22.0 // indirect
|
||||||
golang.org/x/text v0.14.0 // indirect
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20250127172529-29210b9bc287 // indirect
|
||||||
golang.org/x/time v0.5.0 // indirect
|
|
||||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
|
|
||||||
google.golang.org/appengine v1.6.7 // indirect
|
|
||||||
google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 // indirect
|
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17 // indirect
|
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f // indirect
|
|
||||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
gorm.io/driver/mysql v1.5.2 // indirect
|
gorm.io/driver/mysql v1.5.7 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
replace git.solsynth.dev/hydrogen/bus => ../Bus
|
replace git.solsynth.dev/hydrogen/bus => ../Bus
|
||||||
|
418
go.sum
418
go.sum
@ -1,154 +1,129 @@
|
|||||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
|
||||||
cloud.google.com/go v0.110.10 h1:LXy9GEO+timppncPIAZoOj3l58LIU9k+kn48AN7IO3Y=
|
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
||||||
cloud.google.com/go v0.110.10/go.mod h1:v1OoFqYxiBkUrruItNM3eT4lLByNjxmJSV/xDKJNnic=
|
git.solsynth.dev/hypernet/nexus v0.0.0-20250329072130-f113ae6cbaf7 h1:0OitkUQJ3hrobm71UHETLB9N6jTgm6jKTeGRJuBI/6E=
|
||||||
cloud.google.com/go/compute v1.23.3 h1:6sVlXXBmbd7jNX0Ipq0trII3e4n1/MsADLK6a+aiVlk=
|
git.solsynth.dev/hypernet/nexus v0.0.0-20250329072130-f113ae6cbaf7/go.mod h1:5tk62VQ1DcbR0EAN2jAOqYxHiegUPEC805JlfQ/G19I=
|
||||||
cloud.google.com/go/compute v1.23.3/go.mod h1:VCgBUoMnIVIR0CscqQiPJLAG25E3ZRZMzcFZeQ+h8CI=
|
git.solsynth.dev/hypernet/nexus v0.0.0-20250329072729-4a08fd8f1c46 h1:oH2jq7ZG5cslCULUMWqv4dS/YNvd+Xcuv4rBPj0uGA8=
|
||||||
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
|
git.solsynth.dev/hypernet/nexus v0.0.0-20250329072729-4a08fd8f1c46/go.mod h1:5tk62VQ1DcbR0EAN2jAOqYxHiegUPEC805JlfQ/G19I=
|
||||||
cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
|
git.solsynth.dev/hypernet/nexus v0.0.0-20250329075932-d5422ab5b04c h1:XgdTgJxSAQuCbiG15hN5pY6chzcz8sX3Onm2itS+Ufs=
|
||||||
cloud.google.com/go/firestore v1.14.0 h1:8aLcKnMPoldYU3YHgu4t2exrKhLQkqaXAGqT0ljrFVw=
|
git.solsynth.dev/hypernet/nexus v0.0.0-20250329075932-d5422ab5b04c/go.mod h1:5tk62VQ1DcbR0EAN2jAOqYxHiegUPEC805JlfQ/G19I=
|
||||||
cloud.google.com/go/firestore v1.14.0/go.mod h1:96MVaHLsEhbvkBEdZgfN+AS/GIkco1LRpH9Xp9YZfzQ=
|
git.solsynth.dev/hypernet/nexus v0.0.0-20250330063116-4350d197f9c6 h1:K7dYn7/rAXry3dSghFVd4aHOt2+8nTbhdav6DTW8sP8=
|
||||||
cloud.google.com/go/iam v1.1.5 h1:1jTsCu4bcsNsE4iiqNT5SHwrDRCfRmIaaaVFhRveTJI=
|
git.solsynth.dev/hypernet/nexus v0.0.0-20250330063116-4350d197f9c6/go.mod h1:5tk62VQ1DcbR0EAN2jAOqYxHiegUPEC805JlfQ/G19I=
|
||||||
cloud.google.com/go/iam v1.1.5/go.mod h1:rB6P/Ic3mykPbFio+vo7403drjlgvoWfYpJhMXEbzv8=
|
git.solsynth.dev/hypernet/paperclip v0.0.0-20250310151112-1d866f317f47 h1:fvu+bNKPTNtQocssnKbEZ66MqR0iBfAxY3HwlqnmYyE=
|
||||||
cloud.google.com/go/longrunning v0.5.4 h1:w8xEcbZodnA2BbW6sVirkkoC+1gP8wS57EUUgGS0GVg=
|
git.solsynth.dev/hypernet/paperclip v0.0.0-20250310151112-1d866f317f47/go.mod h1:jvxq2qftz2v72x+24+cTFJdQKr9eHQTdk3KVR7cx36s=
|
||||||
cloud.google.com/go/longrunning v0.5.4/go.mod h1:zqNVncI0BOP8ST6XQD1+VcvuShMmq7+xFSzOL++V0dI=
|
git.solsynth.dev/hypernet/pusher v0.0.0-20250216145944-5fb769823a88 h1:2HEENe9KUrdaJeNBzx9lsuXQGyzWqCgnLTKQnr8xFr8=
|
||||||
cloud.google.com/go/storage v1.35.1 h1:B59ahL//eDfx2IIKFBeT5Atm9wnNmj3+8xG/W4WB//w=
|
git.solsynth.dev/hypernet/pusher v0.0.0-20250216145944-5fb769823a88/go.mod h1:ildzMtLagNsLK0Rkw4Hgk2TrrwqZnjwJIUx0MNZwcDY=
|
||||||
cloud.google.com/go/storage v1.35.1/go.mod h1:M6M/3V/D3KpzMTJyPOR/HU6n2Si5QdaXYEsng2xgOs8=
|
git.solsynth.dev/hypernet/wallet v0.0.0-20250323095812-468cd655f886 h1:rVssXF8jZ64ctAfzlCgIgF22NCT9VAPAVxrwlcItx3s=
|
||||||
firebase.google.com/go v3.13.0+incompatible h1:3TdYC3DDi6aHn20qoRkxwGqNgdjtblwVAyRLQwGn/+4=
|
git.solsynth.dev/hypernet/wallet v0.0.0-20250323095812-468cd655f886/go.mod h1:rmomNGQ6RBSp8TpZGA8tFr5M54AL2NADJ/1n0MfrIRM=
|
||||||
firebase.google.com/go v3.13.0+incompatible/go.mod h1:xlah6XbEyW6tbfSklcfe5FHJIwjt8toICdV5Wh9ptHs=
|
github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
||||||
github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||||
github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
|
github.com/andybalholm/brotli v1.1.1 h1:PR2pgnyFznKEugtsUo0xLdDop5SKXd5Qf5ysW+7XdTA=
|
||||||
github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
|
github.com/andybalholm/brotli v1.1.1/go.mod h1:05ib4cKhjx3OQYUY22hTVd34Bc8upXjOLL2rKwwZBoA=
|
||||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
|
||||||
|
github.com/boombuler/barcode v1.0.2 h1:79yrbttoZrLGkL/oOI8hBrUKucwOL0oOjUgEguGMcJ4=
|
||||||
|
github.com/boombuler/barcode v1.0.2/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
|
||||||
|
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
|
||||||
|
github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
|
||||||
|
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
|
||||||
|
github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
|
||||||
|
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||||
|
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
github.com/eko/gocache/lib/v4 v4.2.0 h1:MNykyi5Xw+5Wu3+PUrvtOCaKSZM1nUSVftbzmeC7Yuw=
|
||||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
github.com/eko/gocache/lib/v4 v4.2.0/go.mod h1:7ViVmbU+CzDHzRpmB4SXKyyzyuJ8A3UW3/cszpcqB4M=
|
||||||
github.com/fasthttp/websocket v1.5.8 h1:k5DpirKkftIF/w1R8ZzjSgARJrs54Je9YJK37DL/Ah8=
|
github.com/eko/gocache/store/redis/v4 v4.2.2 h1:Thw31fzGuH3WzJywsdbMivOmP550D6JS7GDHhvCJPA0=
|
||||||
github.com/fasthttp/websocket v1.5.8/go.mod h1:d08g8WaT6nnyvg9uMm8K9zMYyDjfKyj3170AtPRuVU0=
|
github.com/eko/gocache/store/redis/v4 v4.2.2/go.mod h1:LaTxLKx9TG/YUEybQvPMij++D7PBTIJ4+pzvk0ykz0w=
|
||||||
|
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
|
||||||
|
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
|
||||||
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
|
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
|
||||||
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
||||||
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M=
|
||||||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
|
||||||
github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
|
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
|
||||||
github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=
|
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
|
||||||
|
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||||
|
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||||
|
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||||
|
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||||
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||||
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||||
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||||
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||||
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||||
github.com/go-playground/validator/v10 v10.17.0 h1:SmVVlfAOtlZncTxRuinDPomC2DkXJ4E5T9gDA0AIH74=
|
github.com/go-playground/validator/v10 v10.22.1 h1:40JcKH+bBNGFczGuoBYgX4I6m/i27HYW8P9FDk5PbgA=
|
||||||
github.com/go-playground/validator/v10 v10.17.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
|
github.com/go-playground/validator/v10 v10.22.1/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
|
||||||
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
||||||
github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI=
|
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
|
||||||
github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
|
||||||
|
github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA=
|
||||||
|
github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||||
github.com/gofiber/contrib/websocket v1.3.0 h1:XADFAGorer1VJ1bqC4UkCjqS37kwRTV0415+050NrMk=
|
github.com/gofiber/contrib/fiberzerolog v1.0.2 h1:LMa/luarQVeINoRwZLHtLQYepLPDIwUNB5OmdZKk+s8=
|
||||||
github.com/gofiber/contrib/websocket v1.3.0/go.mod h1:xguaOzn2ZZ759LavtosEP+rcxIgBEE/rdumPINhR+Xo=
|
github.com/gofiber/contrib/fiberzerolog v1.0.2/go.mod h1:aTPsgArSgxRWcUeJ/K6PiICz3mbQENR1QOR426QwOoQ=
|
||||||
github.com/gofiber/fiber/v2 v2.36.0/go.mod h1:tgCr+lierLwLoVHHO/jn3Niannv34WRkQETU8wiL9fQ=
|
github.com/gofiber/fiber/v2 v2.36.0/go.mod h1:tgCr+lierLwLoVHHO/jn3Niannv34WRkQETU8wiL9fQ=
|
||||||
github.com/gofiber/fiber/v2 v2.52.4 h1:P+T+4iK7VaqUsq2PALYEfBBo6bJZ4q3FP8cZ84EggTM=
|
github.com/gofiber/fiber/v2 v2.52.6 h1:Rfp+ILPiYSvvVuIPvxrBns+HJp8qGLDnLJawAu27XVI=
|
||||||
github.com/gofiber/fiber/v2 v2.52.4/go.mod h1:KEOE+cXMhXG0zHc9d8+E38hoX+ZN7bhOtgeF2oT6jrQ=
|
github.com/gofiber/fiber/v2 v2.52.6/go.mod h1:YEcBbO/FB+5M1IZNBP9FO3J9281zgPAreiI1oqg8nDw=
|
||||||
github.com/gofiber/template v1.8.3 h1:hzHdvMwMo/T2kouz2pPCA0zGiLCeMnoGsQZBTSYgZxc=
|
github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk=
|
||||||
github.com/gofiber/template v1.8.3/go.mod h1:bs/2n0pSNPOkRa5VJ8zTIvedcI/lEYxzV3+YPXdBvq8=
|
github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||||
github.com/gofiber/template/html/v2 v2.1.1 h1:QEy3O3EBkvwDthy5bXVGUseOyO6ldJoiDxlF4+MJiV8=
|
|
||||||
github.com/gofiber/template/html/v2 v2.1.1/go.mod h1:2G0GHHOUx70C1LDncoBpe4T6maQbNa4x1CVNFW0wju0=
|
|
||||||
github.com/gofiber/utils v1.1.0 h1:vdEBpn7AzIUJRhe+CiTOJdUcTg4Q9RK+pEa0KPbLdrM=
|
|
||||||
github.com/gofiber/utils v1.1.0/go.mod h1:poZpsnhBykfnY1Mc0KeEa6mSHrS3dV0+oBWyeQmb2e0=
|
|
||||||
github.com/golang-jwt/jwt/v5 v5.2.0 h1:d/ix8ftRUorsN+5eMIlF4T6J8CAt9rch3My2winC1Jw=
|
|
||||||
github.com/golang-jwt/jwt/v5 v5.2.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
|
||||||
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA=
|
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA=
|
||||||
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
||||||
github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A=
|
github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A=
|
||||||
github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI=
|
github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI=
|
||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
|
||||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
|
||||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
|
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
|
||||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
|
||||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
|
||||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
|
||||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
|
||||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
|
||||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
|
||||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
|
||||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
|
||||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
|
||||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
|
||||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
|
||||||
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/gomarkdown/markdown v0.0.0-20240419095408-642f0ee99ae2 h1:yEt5djSYb4iNtmV9iJGVday+i4e9u6Mrn5iP64HH5QM=
|
|
||||||
github.com/gomarkdown/markdown v0.0.0-20240419095408-642f0ee99ae2/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA=
|
|
||||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
|
||||||
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.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
github.com/google/go-cmp v0.5.3/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.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
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/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw=
|
|
||||||
github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk=
|
|
||||||
github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o=
|
|
||||||
github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw=
|
|
||||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
|
||||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
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/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs=
|
|
||||||
github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0=
|
|
||||||
github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas=
|
|
||||||
github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU=
|
|
||||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||||
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
||||||
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
||||||
github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 h1:L0QtFUgDarD7Fpv9jeVMgy/+Ec0mtnmYuImjTz6dtDA=
|
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
|
||||||
github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
||||||
github.com/jackc/pgx/v5 v5.5.1 h1:5I9etrGkLrN+2XPCsi6XLlV5DITbSL/xBZdmAxFcXPI=
|
github.com/jackc/pgx/v5 v5.7.1 h1:x7SYsPBYDkHDksogeSmZZ5xzThcTgRz++I5E+ePFUcs=
|
||||||
github.com/jackc/pgx/v5 v5.5.1/go.mod h1:Ig06C2Vu0t5qXC60W8sqIthScaEnFvojjj9dSljmHRA=
|
github.com/jackc/pgx/v5 v5.7.1/go.mod h1:e7O26IywZZ+naJtWWos6i6fvWK+29etgITqrqHLfoZA=
|
||||||
github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk=
|
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
|
||||||
github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
||||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||||
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
||||||
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||||
github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible h1:jdpOPRN1zP63Td1hDQbZW73xKmzDvZHzVdNYxhnTMDA=
|
|
||||||
github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible/go.mod h1:1c7szIrayyPPB/987hsnvNzLushdWf4o/79s3P08L8A=
|
|
||||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||||
github.com/klauspost/compress v1.15.0/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
github.com/klauspost/compress v1.15.0/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||||
github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
|
github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
|
||||||
github.com/klauspost/compress v1.17.7 h1:ehO88t2UGzQK66LMdE8tibEd1ErmzZjNEqWkjLAKQQg=
|
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
|
||||||
github.com/klauspost/compress v1.17.7/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
|
||||||
github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU=
|
|
||||||
github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
|
||||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||||
github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
|
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
|
||||||
github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
|
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
|
||||||
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
|
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
|
||||||
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
|
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
|
||||||
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.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.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.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||||
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
|
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
|
||||||
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||||
github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI=
|
github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI=
|
||||||
github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||||
github.com/microsoft/go-mssqldb v0.17.0 h1:Fto83dMZPnYv1Zwx5vHHxpNraeEaUlQ/hhHLgZiaenE=
|
github.com/microsoft/go-mssqldb v0.17.0 h1:Fto83dMZPnYv1Zwx5vHHxpNraeEaUlQ/hhHLgZiaenE=
|
||||||
@ -160,194 +135,151 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w
|
|||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||||
github.com/nicksnyder/go-i18n/v2 v2.4.0 h1:3IcvPOAvnCKwNm0TB0dLDTuawWEj+ax/RERNC+diLMM=
|
github.com/nats-io/nats.go v1.37.0 h1:07rauXbVnnJvv1gfIyghFEo6lUcYRY0WXc3x7x0vUxE=
|
||||||
github.com/nicksnyder/go-i18n/v2 v2.4.0/go.mod h1:nxYSZE9M0bf3Y70gPQjN9ha7XNHX7gMc814+6wVyEI4=
|
github.com/nats-io/nats.go v1.37.0/go.mod h1:Ubdu4Nh9exXdSz0RVWRFBbRfrbSxOYd26oF0wkWclB8=
|
||||||
github.com/pelletier/go-toml/v2 v2.1.1 h1:LWAJwfNvjQZCFIDKWYQaM62NcYeYViCmWIwmOStowAI=
|
github.com/nats-io/nkeys v0.4.7 h1:RwNJbbIdYCoClSDNY7QVKZlyb/wfT6ugvFCiKy6vDvI=
|
||||||
github.com/pelletier/go-toml/v2 v2.1.1/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
|
github.com/nats-io/nkeys v0.4.7/go.mod h1:kqXRgRDPlGy7nGaEDMuYzmiJCIAAWDK0IMBtDmGD0nc=
|
||||||
github.com/philhofer/fwd v1.1.2 h1:bnDivRJ1EWPjUIRXV5KfORO897HTbpFAQddBdE8t7Gw=
|
github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=
|
||||||
github.com/philhofer/fwd v1.1.2/go.mod h1:qkPdfjR2SIEbspLqpe1tO4n5yICnr2DY7mqEx2tUTP0=
|
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
|
||||||
|
github.com/nicksnyder/go-i18n/v2 v2.5.0 h1:3wH1gpaekcgGuwzWdSu7JwJhH9Tk87k1ezt0i1p2/Is=
|
||||||
|
github.com/nicksnyder/go-i18n/v2 v2.5.0/go.mod h1:DrhgsSDZxoAfvVrBVLXoxZn/pN5TXqaDbq7ju94viiQ=
|
||||||
|
github.com/oschwald/geoip2-golang v1.11.0 h1:hNENhCn1Uyzhf9PTmquXENiWS6AlxAEnBII6r8krA3w=
|
||||||
|
github.com/oschwald/geoip2-golang v1.11.0/go.mod h1:P9zG+54KPEFOliZ29i7SeYZ/GM6tfEL+rgSn03hYuUo=
|
||||||
|
github.com/oschwald/maxminddb-golang v1.13.0 h1:R8xBorY71s84yO06NgTmQvqvTvlS/bnYZrrWX1MElnU=
|
||||||
|
github.com/oschwald/maxminddb-golang v1.13.0/go.mod h1:BU0z8BfFVhi1LQaonTwwGQlsHUEu9pWNdMfmq4ztm0o=
|
||||||
|
github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
|
||||||
|
github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
|
||||||
|
github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c h1:dAMKvw0MlJT1GshSTtih8C2gDs04w8dReiOGXrGLNoY=
|
||||||
|
github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM=
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
github.com/pquerna/otp v1.4.0 h1:wZvl1TIVxKRThZIBiwOOHOGP/1+nZyWBil9Y2XNEDzg=
|
||||||
|
github.com/pquerna/otp v1.4.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg=
|
||||||
|
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.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
||||||
|
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
||||||
|
github.com/prometheus/common v0.52.3 h1:5f8uj6ZwHSscOGNdIQg6OiZv/ybiK2CO2q2drVZAQSA=
|
||||||
|
github.com/prometheus/common v0.52.3/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3l3e7W3RN5U=
|
||||||
|
github.com/prometheus/procfs v0.13.0 h1:GqzLlQyfsPbaEHaQkO7tbDlriv/4o5Hudv6OXHGKX7o=
|
||||||
|
github.com/prometheus/procfs v0.13.0/go.mod h1:cd4PFCR54QLnGKPaKGA6l+cfuNXtht43ZKY6tow0Y1g=
|
||||||
|
github.com/redis/go-redis/v9 v9.7.3 h1:YpPyAayJV+XErNsatSElgRZZVCwXX9QzkKYNvO7x0wM=
|
||||||
|
github.com/redis/go-redis/v9 v9.7.3/go.mod h1:bGUrSggJ9X9GUmZpZNEOQKaANxSGgOEBRltRTZHSvrA=
|
||||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||||
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
||||||
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||||
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
|
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
|
||||||
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
|
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
|
||||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
|
||||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
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.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||||
github.com/rs/zerolog v1.31.0 h1:FcTR3NnLWW+NnTwwhFWiJSZr4ECLpqCm6QsEnyvbV4A=
|
github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8=
|
||||||
github.com/rs/zerolog v1.31.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
|
github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
|
||||||
github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ=
|
github.com/sagikazarmark/locafero v0.6.0 h1:ON7AQg37yzcRPU69mt7gwhFEBwxI6P9T4Qu3N51bwOk=
|
||||||
github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4=
|
github.com/sagikazarmark/locafero v0.6.0/go.mod h1:77OmuIc6VTraTXKXIs/uvUxKGUXjE1GbemJYHqdNjX0=
|
||||||
github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE=
|
github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE=
|
||||||
github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ=
|
github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ=
|
||||||
github.com/samber/lo v1.39.0 h1:4gTz1wUhNYLhFSKl6O+8peW0v2F4BCY034GRpU9WnuA=
|
github.com/samber/lo v1.47.0 h1:z7RynLwP5nbyRscyvcD043DWYoOcYRv3mV8lBeqOCLc=
|
||||||
github.com/samber/lo v1.39.0/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA=
|
github.com/samber/lo v1.47.0/go.mod h1:RmDH9Ct32Qy3gduHQuKJ3gW1fMHAnE/fAzQuf6He5cU=
|
||||||
github.com/savsgio/gotils v0.0.0-20240303185622-093b76447511 h1:KanIMPX0QdEdB4R3CiimCAbxFrhB3j7h0/OvpYGVQa8=
|
|
||||||
github.com/savsgio/gotils v0.0.0-20240303185622-093b76447511/go.mod h1:sM7Mt7uEoCeFSCBM+qBrqvEo+/9vdmj19wzp3yzUhmg=
|
|
||||||
github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
|
github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
|
||||||
github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
|
github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
|
||||||
github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=
|
github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=
|
||||||
github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY=
|
github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY=
|
||||||
github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0=
|
github.com/spf13/cast v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w=
|
||||||
github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
|
github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
|
||||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
github.com/spf13/viper v1.18.1 h1:rmuU42rScKWlhhJDyXZRKJQHXFX02chSVW1IvkPGiVM=
|
github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI=
|
||||||
github.com/spf13/viper v1.18.1/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk=
|
github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
|
||||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
|
||||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
|
||||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
|
||||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
|
||||||
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
|
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
|
||||||
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
|
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
|
||||||
github.com/sujit-baniya/flash v0.1.8 h1:BwcrybCatPU30VMA9IBA5q3ZE0VSr5c7qTqwZrSvyRI=
|
github.com/sujit-baniya/flash v0.1.8 h1:BwcrybCatPU30VMA9IBA5q3ZE0VSr5c7qTqwZrSvyRI=
|
||||||
github.com/sujit-baniya/flash v0.1.8/go.mod h1:kmlAIkLDMlLshEeeE6fETEW8kSOopKN5WA3KXLmS/U0=
|
github.com/sujit-baniya/flash v0.1.8/go.mod h1:kmlAIkLDMlLshEeeE6fETEW8kSOopKN5WA3KXLmS/U0=
|
||||||
github.com/tinylib/msgp v1.1.8 h1:FCXC1xanKO4I8plpHGH2P7koL/RzZs12l/+r7vakfm0=
|
github.com/tinylib/msgp v1.2.5 h1:WeQg1whrXRFiZusidTQqzETkRpGjFjcIhW6uqWH09po=
|
||||||
github.com/tinylib/msgp v1.1.8/go.mod h1:qkpG+2ldGg4xRFmx+jfTvZPxfGFhi64BcnL9vkCm/Tw=
|
github.com/tinylib/msgp v1.2.5/go.mod h1:ykjzy2wzgrlvpDCRc4LA8UXy6D8bzMSuAF3WD57Gok0=
|
||||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||||
github.com/valyala/fasthttp v1.38.0/go.mod h1:t/G+3rLek+CyY9bnIE+YlMRddxVAAGjhxndDB4i4C0I=
|
github.com/valyala/fasthttp v1.38.0/go.mod h1:t/G+3rLek+CyY9bnIE+YlMRddxVAAGjhxndDB4i4C0I=
|
||||||
github.com/valyala/fasthttp v1.52.0 h1:wqBQpxH71XW0e2g+Og4dzQM8pk34aFYlA1Ga8db7gU0=
|
github.com/valyala/fasthttp v1.59.0 h1:Qu0qYHfXvPk1mSLNqcFtEk6DpxgA26hy6bmydotDpRI=
|
||||||
github.com/valyala/fasthttp v1.52.0/go.mod h1:hf5C4QnVMkNXMspnsUlfM3WitlgYflyhHYoKol/szxQ=
|
github.com/valyala/fasthttp v1.59.0/go.mod h1:GTxNb9Bc6r2a9D0TWNSPwDz78UxnTGBViY3xZNEqyYU=
|
||||||
github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8=
|
|
||||||
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
|
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
|
||||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
|
||||||
go.etcd.io/bbolt v1.3.9 h1:8x7aARPEXiXbHmtUwAIv7eV2fQFHrLLavdiJ3uzJXoI=
|
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
|
||||||
go.etcd.io/bbolt v1.3.9/go.mod h1:zaO32+Ti0PK1ivdPtgMESzuzL2VPoIG1PCQNvOdo/dE=
|
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||||
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
go.opentelemetry.io/otel v1.32.0 h1:WnBN+Xjcteh0zdk01SVqV55d/m62NJLJdIyb4y/WO5U=
|
||||||
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
go.opentelemetry.io/otel v1.32.0/go.mod h1:00DCVSB0RQcnzlwyTfqtxSm+DRr9hpYrHjNGiBHVQIg=
|
||||||
|
go.opentelemetry.io/otel/metric v1.32.0 h1:xV2umtmNcThh2/a/aCP+h64Xx5wsj8qqnkYZktzNa0M=
|
||||||
|
go.opentelemetry.io/otel/metric v1.32.0/go.mod h1:jH7CIbbK6SH2V2wE16W05BHCtIDzauciCRLoc/SyMv8=
|
||||||
|
go.opentelemetry.io/otel/sdk v1.32.0 h1:RNxepc9vK59A8XsgZQouW8ue8Gkb4jpWtJm9ge5lEG4=
|
||||||
|
go.opentelemetry.io/otel/sdk v1.32.0/go.mod h1:LqgegDBjKMmb2GC6/PrTnteJG39I8/vJCAP9LlJXEjU=
|
||||||
|
go.opentelemetry.io/otel/sdk/metric v1.32.0 h1:rZvFnvmvawYb0alrYkjraqJq0Z4ZUJAiyYCU9snn1CU=
|
||||||
|
go.opentelemetry.io/otel/sdk/metric v1.32.0/go.mod h1:PWeZlq0zt9YkYAp3gjKZ0eicRYvOh1Gd+X99x6GHpCQ=
|
||||||
|
go.opentelemetry.io/otel/trace v1.32.0 h1:WIC9mYrXf8TmY/EXuULKc8hR17vE+Hjv2cssQDe03fM=
|
||||||
|
go.opentelemetry.io/otel/trace v1.32.0/go.mod h1:+i4rkvCraA+tG6AzwloGaCtkx53Fa+L+V8e9a7YvhT8=
|
||||||
|
go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU=
|
||||||
|
go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
|
||||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
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/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
|
||||||
golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
|
golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus=
|
||||||
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
|
golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c h1:7dEasQXItcW1xKJ2+gg5VOiBnqWrJc+rq0DPKyvvdbY=
|
||||||
golang.org/x/exp v0.0.0-20231219180239-dc181d75b848 h1:+iq7lrkxmFNBM7xx+Rae2W6uyPfhPeDWD+n+JgppptE=
|
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8=
|
||||||
golang.org/x/exp v0.0.0-20231219180239-dc181d75b848/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI=
|
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
|
||||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
|
||||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
|
||||||
golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
|
||||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8=
|
||||||
golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
|
golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk=
|
||||||
golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc=
|
|
||||||
golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
|
||||||
golang.org/x/oauth2 v0.15.0 h1:s8pnnxNVzjWyrvYdFUQq5llS1PX2zhPXmccZv99h7uQ=
|
|
||||||
golang.org/x/oauth2 v0.15.0/go.mod h1:q48ptWNTY5XWf+JNten23lcvHpLJ0ZSxF5ttTHKVCAM=
|
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/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-20190423024810-112230192c58/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.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
|
||||||
golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
|
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||||
golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
|
||||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/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-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/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-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/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=
|
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
|
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
|
||||||
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.30.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/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
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.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
|
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
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.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.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
|
||||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
|
||||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
|
||||||
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
|
|
||||||
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
|
||||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
|
||||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
|
||||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
|
||||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||||
golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ=
|
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk=
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20250127172529-29210b9bc287 h1:J1H9f+LEdWAfHcez/4cvaVBox7cOYT+IU6rgqj5x++8=
|
||||||
google.golang.org/api v0.153.0 h1:N1AwGhielyKFaUqH07/ZSIQR3uNPcV7NVw0vj+j4iR4=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20250127172529-29210b9bc287/go.mod h1:8BS3B93F/U1juMFq9+EDk+qOT5CO1R9IzXxG3PTqiRk=
|
||||||
google.golang.org/api v0.153.0/go.mod h1:3qNJX5eOmhiWYc67jRA/3GsDw97UFb5ivv7Y2PrriAY=
|
google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ=
|
||||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw=
|
||||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
google.golang.org/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNIM=
|
||||||
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
|
||||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
|
||||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
|
||||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
|
||||||
google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 h1:wpZ8pe2x1Q3f2KyT5f8oP/fa9rHAKgFPr/HZdNuS+PQ=
|
|
||||||
google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:J7XzRzVy1+IPwWHZUzoD0IccYZIrXILAQpc+Qy9CMhY=
|
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17 h1:JpwMPBpFN3uKhdaekDpiNlImDdkUAyiJ6ez/uxGaUSo=
|
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:0xJLfVdJqpAPl8tDg1ujOCGzx6LFLttXT5NhllGOXY4=
|
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f h1:ultW7fxlIvee4HYrtnaRPon9HpEgFk5zYpmfMgtKB5I=
|
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f/go.mod h1:L9KNLi232K1/xB6f7AlSX692koaRnKaWSR0stBki0Yc=
|
|
||||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
|
||||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
|
||||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
|
||||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
|
||||||
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
|
||||||
google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk=
|
|
||||||
google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98=
|
|
||||||
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=
|
|
||||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
|
||||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
|
||||||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
|
||||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
|
||||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
|
||||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
|
||||||
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.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
|
|
||||||
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/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 h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||||
@ -356,18 +288,16 @@ gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
|||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
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 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gorm.io/datatypes v1.2.0 h1:5YT+eokWdIxhJgWHdrb2zYUimyk0+TaFth+7a0ybzco=
|
gorm.io/datatypes v1.2.4 h1:uZmGAcK/QZ0uyfCuVg0VQY1ZmV9h1fuG0tMwKByO1z4=
|
||||||
gorm.io/datatypes v1.2.0/go.mod h1:o1dh0ZvjIjhH/bngTpypG6lVRJ5chTBxE09FH/71k04=
|
gorm.io/datatypes v1.2.4/go.mod h1:f4BsLcFAX67szSv8svwLRjklArSHAvHLeE3pXAS5DZI=
|
||||||
gorm.io/driver/mysql v1.5.2 h1:QC2HRskSE75wBuOxe0+iCkyJZ+RqpudsQtqkp+IMuXs=
|
gorm.io/driver/mysql v1.5.7 h1:MndhOPYOfEp2rHKgkZIhJ16eVUIRf2HmzgoPmh7FCWo=
|
||||||
gorm.io/driver/mysql v1.5.2/go.mod h1:pQLhh1Ut/WUAySdTHwBpBv6+JKcj+ua4ZFx1QQTBzb8=
|
gorm.io/driver/mysql v1.5.7/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkDM=
|
||||||
gorm.io/driver/postgres v1.5.4 h1:Iyrp9Meh3GmbSuyIAGyjkN+n9K+GHX9b9MqsTL4EJCo=
|
gorm.io/driver/postgres v1.5.9 h1:DkegyItji119OlcaLjqN11kHoUgZ/j13E0jkJZgD6A8=
|
||||||
gorm.io/driver/postgres v1.5.4/go.mod h1:Bgo89+h0CRcdA33Y6frlaHHVuTdOf87pmyzwW9C/BH0=
|
gorm.io/driver/postgres v1.5.9/go.mod h1:DX3GReXH+3FPWGrrgffdvCk3DQ1dwDPdmbenSkweRGI=
|
||||||
gorm.io/driver/sqlite v1.4.3 h1:HBBcZSDnWi5BW3B3rwvVTc510KGkBkexlOg0QrmLUuU=
|
gorm.io/driver/sqlite v1.4.3 h1:HBBcZSDnWi5BW3B3rwvVTc510KGkBkexlOg0QrmLUuU=
|
||||||
gorm.io/driver/sqlite v1.4.3/go.mod h1:0Aq3iPO+v9ZKbcdiz8gLWRw5VOPcBOPUQJFLq5e2ecI=
|
gorm.io/driver/sqlite v1.4.3/go.mod h1:0Aq3iPO+v9ZKbcdiz8gLWRw5VOPcBOPUQJFLq5e2ecI=
|
||||||
gorm.io/driver/sqlserver v1.4.1 h1:t4r4r6Jam5E6ejqP7N82qAJIJAht27EGT41HyPfXRw0=
|
gorm.io/driver/sqlserver v1.4.1 h1:t4r4r6Jam5E6ejqP7N82qAJIJAht27EGT41HyPfXRw0=
|
||||||
gorm.io/driver/sqlserver v1.4.1/go.mod h1:DJ4P+MeZbc5rvY58PnmN1Lnyvb5gw5NPzGshHDnJLig=
|
gorm.io/driver/sqlserver v1.4.1/go.mod h1:DJ4P+MeZbc5rvY58PnmN1Lnyvb5gw5NPzGshHDnJLig=
|
||||||
gorm.io/gorm v1.25.2-0.20230530020048-26663ab9bf55/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
|
gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
|
||||||
gorm.io/gorm v1.25.5 h1:zR9lOiiYf09VNh5Q1gphfyia1JpiClIWG9hQaxB/mls=
|
gorm.io/gorm v1.25.12 h1:I0u8i2hWQItBq1WfE0o2+WuL9+8L21K9e2HHSTE/0f8=
|
||||||
gorm.io/gorm v1.25.5/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
|
gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=
|
||||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
|
||||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
|
||||||
|
18
locales/en-US.json
Normal file
18
locales/en-US.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"subjectLoginOneTimePassword": "Login verification code",
|
||||||
|
"shortBodyLoginOneTimePassword": "%s is your login verification code. It will expires in 30 minutes.",
|
||||||
|
"subjectConfirmRegistration": "Confirm your registration",
|
||||||
|
"subjectResetPassword": "Reset your password",
|
||||||
|
"subjectDeleteAccount": "Confirm your account deletion",
|
||||||
|
"subjectLoginAlert": "Login alert",
|
||||||
|
"shortBodyLoginAlert": "Your account got logged in from %s. If it's not your device, please deal with it immediately.",
|
||||||
|
"subjectAbuseReportUpdated": "Abuse report status has been changed",
|
||||||
|
"shortBodyAbuseReportUpdated": "Report #%d has been changed to %s. Moderator message: %s",
|
||||||
|
"subtitlePunishment": "Case #%d Moderated by %s",
|
||||||
|
"subjectPunishmentCreated": "You have been punished",
|
||||||
|
"shortBodyPunishmentCreated": "You have been punished for %s. Learn more inside the app.",
|
||||||
|
"subjectPunishmentUpdated": "Your punishment has been updated",
|
||||||
|
"shortBodyPunishmentUpdated": "Your punishment #%s has been updated. Learn more inside the app.",
|
||||||
|
"subjectPunishmentDeleted": "Your punishment has been revoked",
|
||||||
|
"shortBodyPunishmentDeleted": "Your punishment #%s has been revoked."
|
||||||
|
}
|
18
locales/zh-CN.json
Normal file
18
locales/zh-CN.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"subjectLoginOneTimePassword": "您的验证码",
|
||||||
|
"shortBodyLoginOneTimePassword": "%s 是您的登录验证码,它将在 30 分钟后过期。",
|
||||||
|
"subjectConfirmRegistration": "确认您的注册",
|
||||||
|
"subjectResetPassword": "重置您的密码",
|
||||||
|
"subjectDeleteAccount": "确认您的帐户删除",
|
||||||
|
"subjectLoginAlert": "登陆提醒",
|
||||||
|
"shortBodyLoginAlert": "您的帐户在 %s 登录,若它不是你的设备,请立即处理。",
|
||||||
|
"subjectAbuseReportUpdated": "举报状态已更新",
|
||||||
|
"shortBodyAbuseReportUpdated": "举报 #%d 已更新为 %s。管理员回复:%s",
|
||||||
|
"subtitlePunishment": "案件 #%d 由 %s 处理",
|
||||||
|
"subjectPunishmentCreated": "你收到了一份处分",
|
||||||
|
"shortBodyPunishmentCreated": "你因为 %s 而被处分,详情请在应用内查看。",
|
||||||
|
"subjectPunishmentUpdated": "你的处分已更新",
|
||||||
|
"shortBodyPunishmentUpdated": "你的处分 #%s 已更新。详情请在应用内查看。",
|
||||||
|
"subjectPunishmentDeleted": "你的处分已撤销",
|
||||||
|
"shortBodyPunishmentDeleted": "你的处分 #%s 已撤销。"
|
||||||
|
}
|
46
pkg/authkit/audit.go
Normal file
46
pkg/authkit/audit.go
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
package authkit
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"git.solsynth.dev/hypernet/nexus/pkg/nex"
|
||||||
|
"git.solsynth.dev/hypernet/nexus/pkg/nex/sec"
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/proto"
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
func AddEvent(nx *nex.Conn, userId uint, action string, meta map[string]any, ip, ua string) error {
|
||||||
|
conn, err := nx.GetClientGrpcConn(nex.ServiceTypeAuth)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to get auth service client: %v", err)
|
||||||
|
}
|
||||||
|
_, err = proto.NewAuditServiceClient(conn).RecordEvent(context.Background(), &proto.RecordEventRequest{
|
||||||
|
UserId: uint64(userId),
|
||||||
|
Action: action,
|
||||||
|
Metadata: nex.EncodeMap(meta),
|
||||||
|
Ip: ip,
|
||||||
|
UserAgent: ua,
|
||||||
|
})
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func AddEventExt(nx *nex.Conn, action string, meta map[string]any, c *fiber.Ctx) error {
|
||||||
|
user, ok := c.Locals("nex_user").(*sec.UserInfo)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("failed to get user info, make sure you call this method behind the ContextMiddleware")
|
||||||
|
}
|
||||||
|
|
||||||
|
conn, err := nx.GetClientGrpcConn(nex.ServiceTypeAuth)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to get auth service client: %v", err)
|
||||||
|
}
|
||||||
|
_, err = proto.NewAuditServiceClient(conn).RecordEvent(context.Background(), &proto.RecordEventRequest{
|
||||||
|
UserId: uint64(user.ID),
|
||||||
|
Action: action,
|
||||||
|
Metadata: nex.EncodeMap(meta),
|
||||||
|
Ip: c.IP(),
|
||||||
|
UserAgent: c.Get(fiber.HeaderUserAgent),
|
||||||
|
})
|
||||||
|
return err
|
||||||
|
}
|
26
pkg/authkit/auth.go
Normal file
26
pkg/authkit/auth.go
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
package authkit
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"git.solsynth.dev/hypernet/nexus/pkg/nex"
|
||||||
|
"git.solsynth.dev/hypernet/nexus/pkg/proto"
|
||||||
|
"github.com/samber/lo"
|
||||||
|
)
|
||||||
|
|
||||||
|
func EnsureUserPermGranted(nx *nex.Conn, userId, otherId uint, key string, val any) error {
|
||||||
|
conn, err := nx.GetClientGrpcConn(nex.ServiceTypeAuth)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to get auth service client: %v", err)
|
||||||
|
}
|
||||||
|
resp, err := proto.NewAuthServiceClient(conn).EnsureUserPermGranted(context.Background(), &proto.CheckUserPermRequest{
|
||||||
|
UserId: uint64(userId),
|
||||||
|
OtherId: uint64(otherId),
|
||||||
|
Key: key,
|
||||||
|
Value: nex.EncodeMap(val),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return lo.Ternary(resp.GetIsValid(), nil, fmt.Errorf("missing permission: %v", key))
|
||||||
|
}
|
19
pkg/authkit/models/account_groups.go
Normal file
19
pkg/authkit/models/account_groups.go
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import "gorm.io/datatypes"
|
||||||
|
|
||||||
|
type AccountGroup struct {
|
||||||
|
BaseModel
|
||||||
|
|
||||||
|
Name string `json:"name"`
|
||||||
|
PermNodes datatypes.JSONMap `json:"perm_nodes"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AccountGroupMember struct {
|
||||||
|
BaseModel
|
||||||
|
|
||||||
|
Account Account `json:"account"`
|
||||||
|
Group AccountGroup `json:"group"`
|
||||||
|
AccountID uint `json:"account_id"`
|
||||||
|
GroupID uint `json:"group_id"`
|
||||||
|
}
|
94
pkg/authkit/models/accounts.go
Normal file
94
pkg/authkit/models/accounts.go
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"git.solsynth.dev/hypernet/nexus/pkg/nex"
|
||||||
|
"git.solsynth.dev/hypernet/nexus/pkg/proto"
|
||||||
|
"gorm.io/datatypes"
|
||||||
|
|
||||||
|
"github.com/samber/lo"
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Account struct {
|
||||||
|
BaseModel
|
||||||
|
|
||||||
|
Name string `json:"name" gorm:"uniqueIndex"`
|
||||||
|
Nick string `json:"nick"`
|
||||||
|
Avatar *string `json:"avatar"`
|
||||||
|
Banner *string `json:"banner"`
|
||||||
|
ConfirmedAt *time.Time `json:"confirmed_at"`
|
||||||
|
SuspendedAt *time.Time `json:"suspended_at"`
|
||||||
|
PermNodes datatypes.JSONMap `json:"perm_nodes"`
|
||||||
|
Language string `json:"language"`
|
||||||
|
|
||||||
|
AutomatedBy *Account `json:"automated_by" gorm:"foreignKey:AutomatedID"`
|
||||||
|
AutomatedID *uint `json:"automated_id"`
|
||||||
|
|
||||||
|
AffiliatedTo *Realm `json:"affiliated_to" gorm:"foreignKey:AffiliatedID"`
|
||||||
|
AffiliatedID *uint `json:"affiliated_id"`
|
||||||
|
|
||||||
|
Profile AccountProfile `json:"profile,omitempty"`
|
||||||
|
Contacts []AccountContact `json:"contacts,omitempty"`
|
||||||
|
Badges []Badge `json:"badges,omitempty"`
|
||||||
|
|
||||||
|
Tickets []AuthTicket `json:"tickets,omitempty"`
|
||||||
|
Factors []AuthFactor `json:"factors,omitempty"`
|
||||||
|
|
||||||
|
Relations []AccountRelationship `json:"relations,omitempty" gorm:"foreignKey:AccountID"`
|
||||||
|
|
||||||
|
Punishments []Punishment `json:"punishments,omitempty"`
|
||||||
|
|
||||||
|
// Keep this for backward compability
|
||||||
|
Description string `json:"description" gorm:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v Account) GetAvatar() *string {
|
||||||
|
if v.Avatar != nil {
|
||||||
|
return lo.ToPtr(fmt.Sprintf("%s/%s", viper.GetString("content_endpoint"), *v.Avatar))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v Account) GetBanner() *string {
|
||||||
|
if v.Banner != nil {
|
||||||
|
return lo.ToPtr(fmt.Sprintf("%s/%s", viper.GetString("content_endpoint"), *v.Banner))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v Account) GetPrimaryEmail() AccountContact {
|
||||||
|
val, _ := lo.Find(v.Contacts, func(item AccountContact) bool {
|
||||||
|
return item.Type == EmailAccountContact && item.IsPrimary
|
||||||
|
})
|
||||||
|
return val
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v Account) EncodeToUserInfo() *proto.UserInfo {
|
||||||
|
return &proto.UserInfo{
|
||||||
|
Id: uint64(v.ID),
|
||||||
|
Name: v.Name,
|
||||||
|
Language: v.Language,
|
||||||
|
PermNodes: nex.EncodeMap(v.PermNodes),
|
||||||
|
Metadata: nex.EncodeMap(v),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type AccountContactType = int8
|
||||||
|
|
||||||
|
const (
|
||||||
|
EmailAccountContact = AccountContactType(iota)
|
||||||
|
)
|
||||||
|
|
||||||
|
type AccountContact struct {
|
||||||
|
BaseModel
|
||||||
|
|
||||||
|
Type int8 `json:"type"`
|
||||||
|
Content string `json:"content" gorm:"uniqueIndex"`
|
||||||
|
IsPublic bool `json:"is_public"`
|
||||||
|
IsPrimary bool `json:"is_primary"`
|
||||||
|
VerifiedAt *time.Time `json:"verified_at"`
|
||||||
|
AccountID uint `json:"account_id"`
|
||||||
|
}
|
16
pkg/authkit/models/audit.go
Normal file
16
pkg/authkit/models/audit.go
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import "gorm.io/datatypes"
|
||||||
|
|
||||||
|
type AuditRecord struct {
|
||||||
|
BaseModel
|
||||||
|
|
||||||
|
Action string `json:"action"`
|
||||||
|
Metadata datatypes.JSONMap `json:"metadata"`
|
||||||
|
Location *string `json:"location"`
|
||||||
|
CoordinateX *float64 `json:"coordinate_x"`
|
||||||
|
CoordinateY *float64 `json:"coordinate_y"`
|
||||||
|
UserAgent string `json:"user_agent"`
|
||||||
|
IpAddress string `json:"ip_address"`
|
||||||
|
AccountID uint `json:"account_id"`
|
||||||
|
}
|
85
pkg/authkit/models/auth.go
Normal file
85
pkg/authkit/models/auth.go
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"gorm.io/datatypes"
|
||||||
|
)
|
||||||
|
|
||||||
|
type AuthConfig struct {
|
||||||
|
AlwaysRisky bool `json:"always_risky"`
|
||||||
|
MaximumAuthSteps int `json:"maximum_auth_steps" validate:"required,min=1,max=99"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AuthFactorType = int8
|
||||||
|
|
||||||
|
const (
|
||||||
|
PasswordAuthFactor = AuthFactorType(iota)
|
||||||
|
EmailPasswordFactor
|
||||||
|
TimeOtpFactor
|
||||||
|
InAppNotifyFactor
|
||||||
|
)
|
||||||
|
|
||||||
|
type AuthFactor struct {
|
||||||
|
BaseModel
|
||||||
|
|
||||||
|
Type int8 `json:"type"`
|
||||||
|
Secret string `json:"-"`
|
||||||
|
Config datatypes.JSONMap `json:"config"`
|
||||||
|
|
||||||
|
Account Account `json:"account"`
|
||||||
|
AccountID uint `json:"account_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AuthTicket struct {
|
||||||
|
BaseModel
|
||||||
|
|
||||||
|
Location *string `json:"location"`
|
||||||
|
CoordinateX *float64 `json:"coordinate_x"`
|
||||||
|
CoordinateY *float64 `json:"coordinate_y"`
|
||||||
|
IpAddress string `json:"ip_address"`
|
||||||
|
UserAgent string `json:"user_agent"`
|
||||||
|
StepRemain int `json:"step_remain"`
|
||||||
|
Claims datatypes.JSONSlice[string] `json:"claims"`
|
||||||
|
Audiences datatypes.JSONSlice[string] `json:"audiences"`
|
||||||
|
FactorTrail datatypes.JSONSlice[int] `json:"factor_trail"`
|
||||||
|
GrantToken *string `json:"grant_token"`
|
||||||
|
AccessToken *string `json:"access_token"`
|
||||||
|
RefreshToken *string `json:"refresh_token"`
|
||||||
|
ExpiredAt *time.Time `json:"expired_at"`
|
||||||
|
AvailableAt *time.Time `json:"available_at"`
|
||||||
|
LastGrantAt *time.Time `json:"last_grant_at"`
|
||||||
|
Nonce *string `json:"nonce"`
|
||||||
|
ClientID *uint `json:"client_id"`
|
||||||
|
|
||||||
|
Account Account `json:"account"`
|
||||||
|
AccountID uint `json:"account_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v AuthTicket) IsAvailable() error {
|
||||||
|
if v.StepRemain > 0 {
|
||||||
|
return fmt.Errorf("ticket isn't authenticated yet")
|
||||||
|
}
|
||||||
|
if v.AvailableAt != nil && time.Now().Unix() < v.AvailableAt.Unix() {
|
||||||
|
return fmt.Errorf("ticket isn't available yet")
|
||||||
|
}
|
||||||
|
if v.ExpiredAt != nil && time.Now().Unix() > v.ExpiredAt.Unix() {
|
||||||
|
return fmt.Errorf("ticket expired")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v AuthTicket) IsCanBeAvailble() error {
|
||||||
|
if v.StepRemain > 0 {
|
||||||
|
return fmt.Errorf("ticket isn't authenticated yet")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type AuthContext struct {
|
||||||
|
Ticket AuthTicket `json:"ticket"`
|
||||||
|
Account Account `json:"account"`
|
||||||
|
}
|
12
pkg/authkit/models/badges.go
Normal file
12
pkg/authkit/models/badges.go
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import "gorm.io/datatypes"
|
||||||
|
|
||||||
|
type Badge struct {
|
||||||
|
BaseModel
|
||||||
|
|
||||||
|
Type string `json:"type"`
|
||||||
|
Metadata datatypes.JSONMap `json:"metadata"`
|
||||||
|
IsActive bool `json:"is_active"`
|
||||||
|
AccountID uint `json:"account_id"`
|
||||||
|
}
|
13
pkg/authkit/models/bot.go
Normal file
13
pkg/authkit/models/bot.go
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
type ApiKey struct {
|
||||||
|
BaseModel
|
||||||
|
|
||||||
|
Name string `json:"name"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
Lifecycle *int64 `json:"lifecycle"`
|
||||||
|
Ticket AuthTicket `json:"ticket" gorm:"TicketID"`
|
||||||
|
TicketID uint `json:"ticket_id"`
|
||||||
|
Account Account `json:"account"`
|
||||||
|
AccountID uint `json:"account_id"`
|
||||||
|
}
|
21
pkg/authkit/models/check_in.go
Normal file
21
pkg/authkit/models/check_in.go
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import "gorm.io/datatypes"
|
||||||
|
|
||||||
|
type CheckInRecord struct {
|
||||||
|
BaseModel
|
||||||
|
|
||||||
|
ResultTier int `json:"result_tier"`
|
||||||
|
ResultExperience int `json:"result_experience"`
|
||||||
|
ResultCoin float64 `json:"result_coin"`
|
||||||
|
CurrentStreak int `json:"current_streak"`
|
||||||
|
|
||||||
|
// The result modifiers are some random tips that will show up in the client;
|
||||||
|
// This field is to use to make sure the tips will be the same when the client is reloaded.
|
||||||
|
// For now, this modifier slice will contain four random numbers from 0 to 1024.
|
||||||
|
// Client should mod this modifier by the length of total available tips.
|
||||||
|
ResultModifiers datatypes.JSONSlice[int] `json:"result_modifiers"`
|
||||||
|
|
||||||
|
Account Account `json:"account"`
|
||||||
|
AccountID uint `json:"account_id"`
|
||||||
|
}
|
16
pkg/authkit/models/clients.go
Normal file
16
pkg/authkit/models/clients.go
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import "gorm.io/datatypes"
|
||||||
|
|
||||||
|
type ThirdClient struct {
|
||||||
|
BaseModel
|
||||||
|
|
||||||
|
Alias string `json:"alias" gorm:"uniqueIndex"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
Secret string `json:"secret"`
|
||||||
|
Urls datatypes.JSONSlice[string] `json:"urls"`
|
||||||
|
Callbacks datatypes.JSONSlice[string] `json:"callbacks"`
|
||||||
|
IsDraft bool `json:"is_draft"`
|
||||||
|
AccountID *uint `json:"account_id"`
|
||||||
|
}
|
18
pkg/authkit/models/events.go
Normal file
18
pkg/authkit/models/events.go
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import "gorm.io/datatypes"
|
||||||
|
|
||||||
|
type ActionEvent struct {
|
||||||
|
BaseModel
|
||||||
|
|
||||||
|
Type string `json:"type"`
|
||||||
|
Metadata datatypes.JSONMap `json:"metadata"`
|
||||||
|
Location *string `json:"location"`
|
||||||
|
CoordinateX *float64 `json:"coordinate_x"`
|
||||||
|
CoordinateY *float64 `json:"coordinate_y"`
|
||||||
|
IpAddress string `json:"ip_address"`
|
||||||
|
UserAgent string `json:"user_agent"`
|
||||||
|
|
||||||
|
Account Account `json:"account"`
|
||||||
|
AccountID uint `json:"account_id"`
|
||||||
|
}
|
65
pkg/authkit/models/notifications.go
Normal file
65
pkg/authkit/models/notifications.go
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"git.solsynth.dev/hypernet/pusher/pkg/pushkit"
|
||||||
|
"gorm.io/datatypes"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Notification struct {
|
||||||
|
BaseModel
|
||||||
|
|
||||||
|
Topic string `json:"topic"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
Subtitle string `json:"subtitle"`
|
||||||
|
Body string `json:"body"`
|
||||||
|
Metadata datatypes.JSONMap `json:"metadata"`
|
||||||
|
Priority int `json:"priority"`
|
||||||
|
SenderID *uint `json:"sender_id"`
|
||||||
|
|
||||||
|
Account Account `json:"account"`
|
||||||
|
AccountID uint `json:"account_id"`
|
||||||
|
|
||||||
|
ReadAt *time.Time `json:"read_at"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v Notification) EncodeToPushkit() pushkit.Notification {
|
||||||
|
return pushkit.Notification{
|
||||||
|
Topic: v.Topic,
|
||||||
|
Title: v.Title,
|
||||||
|
Subtitle: v.Subtitle,
|
||||||
|
Body: v.Body,
|
||||||
|
Metadata: v.Metadata,
|
||||||
|
Priority: v.Priority,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewNotificationFromPushkit(pk pushkit.Notification) Notification {
|
||||||
|
return Notification{
|
||||||
|
Topic: pk.Topic,
|
||||||
|
Title: pk.Title,
|
||||||
|
Subtitle: pk.Subtitle,
|
||||||
|
Body: pk.Body,
|
||||||
|
Metadata: pk.Metadata,
|
||||||
|
Priority: pk.Priority,
|
||||||
|
SenderID: nil,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
NotifySubscriberFirebase = "firebase"
|
||||||
|
NotifySubscriberAPNs = "apple"
|
||||||
|
)
|
||||||
|
|
||||||
|
type NotificationSubscriber struct {
|
||||||
|
BaseModel
|
||||||
|
|
||||||
|
UserAgent string `json:"user_agent"`
|
||||||
|
Provider string `json:"provider"`
|
||||||
|
DeviceID string `json:"device_id" gorm:"uniqueIndex"`
|
||||||
|
DeviceToken string `json:"device_token"`
|
||||||
|
|
||||||
|
Account Account `json:"account"`
|
||||||
|
AccountID uint `json:"account_id"`
|
||||||
|
}
|
19
pkg/authkit/models/preferences.go
Normal file
19
pkg/authkit/models/preferences.go
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import "gorm.io/datatypes"
|
||||||
|
|
||||||
|
type PreferenceAuth struct {
|
||||||
|
BaseModel
|
||||||
|
|
||||||
|
Config datatypes.JSONType[AuthConfig] `json:"config"`
|
||||||
|
AccountID uint `json:"account_id"`
|
||||||
|
Account Account `json:"account"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type PreferenceNotification struct {
|
||||||
|
BaseModel
|
||||||
|
|
||||||
|
Config datatypes.JSONMap `json:"config"`
|
||||||
|
AccountID uint `json:"account_id"`
|
||||||
|
Account Account `json:"account"`
|
||||||
|
}
|
31
pkg/authkit/models/profiles.go
Normal file
31
pkg/authkit/models/profiles.go
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"gorm.io/datatypes"
|
||||||
|
)
|
||||||
|
|
||||||
|
type AccountProfile struct {
|
||||||
|
BaseModel
|
||||||
|
|
||||||
|
FirstName string `json:"first_name"`
|
||||||
|
LastName string `json:"last_name"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
TimeZone string `json:"time_zone"`
|
||||||
|
Location string `json:"location"`
|
||||||
|
Pronouns string `json:"pronouns"`
|
||||||
|
Gender string `json:"gender"`
|
||||||
|
Links datatypes.JSONMap `json:"links"`
|
||||||
|
Experience uint64 `json:"experience"`
|
||||||
|
LastSeenAt *time.Time `json:"last_seen_at"`
|
||||||
|
Birthday *time.Time `json:"birthday"`
|
||||||
|
AccountID uint `json:"account_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AccountPage struct {
|
||||||
|
BaseModel
|
||||||
|
|
||||||
|
Content string `json:"content"`
|
||||||
|
AccountID uint `json:"account_id"`
|
||||||
|
}
|
44
pkg/authkit/models/programs.go
Normal file
44
pkg/authkit/models/programs.go
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"gorm.io/datatypes"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ProgramPrice struct {
|
||||||
|
Currency string `json:"currency"`
|
||||||
|
Amount float64 `json:"amount"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ProgramBadge struct {
|
||||||
|
Type string `json:"type"`
|
||||||
|
Metadata map[string]any `json:"metadata"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ProgramGroup struct {
|
||||||
|
ID uint `json:"id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Program struct {
|
||||||
|
BaseModel
|
||||||
|
|
||||||
|
Name string `json:"name"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
Alias string `json:"alias" gorm:"uniqueIndex"`
|
||||||
|
ExpRequirement int64 `json:"exp_requirement"`
|
||||||
|
Price datatypes.JSONType[ProgramPrice] `json:"price"`
|
||||||
|
Badge datatypes.JSONType[ProgramBadge] `json:"badge"`
|
||||||
|
Group datatypes.JSONType[ProgramGroup] `json:"group"`
|
||||||
|
Appearance datatypes.JSONMap `json:"appearance"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ProgramMember struct {
|
||||||
|
BaseModel
|
||||||
|
|
||||||
|
LastPaid *time.Time `json:"last_paid"`
|
||||||
|
Account Account `json:"account"`
|
||||||
|
AccountID uint `json:"account_id"`
|
||||||
|
Program Program `json:"program"`
|
||||||
|
ProgramID uint `json:"program_id"`
|
||||||
|
}
|
26
pkg/authkit/models/punishments.go
Normal file
26
pkg/authkit/models/punishments.go
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"gorm.io/datatypes"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
PunishmentTypeStrike = iota
|
||||||
|
PunishmentTypeLimited
|
||||||
|
PunishmentTypeDisabled
|
||||||
|
)
|
||||||
|
|
||||||
|
type Punishment struct {
|
||||||
|
BaseModel
|
||||||
|
|
||||||
|
Reason string `json:"reason"`
|
||||||
|
Type int `json:"type"`
|
||||||
|
PermNodes datatypes.JSONMap `json:"perm_nodes"`
|
||||||
|
ExpiredAt *time.Time `json:"expired_at"`
|
||||||
|
Account Account `json:"account"`
|
||||||
|
AccountID uint `json:"account_id"`
|
||||||
|
Moderator *Account `json:"moderator"`
|
||||||
|
ModeratorID *uint `json:"moderator_id"`
|
||||||
|
}
|
66
pkg/authkit/models/realms.go
Normal file
66
pkg/authkit/models/realms.go
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.solsynth.dev/hypernet/nexus/pkg/nex"
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/proto"
|
||||||
|
"gorm.io/datatypes"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
RealmPopularityMemberFactor = 5
|
||||||
|
RealmPopularityPostFactor = 10
|
||||||
|
RealmPopularityChatFactor = 2
|
||||||
|
)
|
||||||
|
|
||||||
|
type Realm struct {
|
||||||
|
BaseModel
|
||||||
|
|
||||||
|
Alias string `json:"alias" gorm:"uniqueIndex"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
Members []RealmMember `json:"members"`
|
||||||
|
Avatar *string `json:"avatar"`
|
||||||
|
Banner *string `json:"banner"`
|
||||||
|
Popularity int `json:"popularity"`
|
||||||
|
AccessPolicy datatypes.JSONMap `json:"access_policy"`
|
||||||
|
IsPublic bool `json:"is_public"`
|
||||||
|
IsCommunity bool `json:"is_community"`
|
||||||
|
AccountID uint `json:"account_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewRealmFromProto(proto *proto.RealmInfo) Realm {
|
||||||
|
return Realm{
|
||||||
|
BaseModel: BaseModel{
|
||||||
|
ID: uint(proto.GetId()),
|
||||||
|
},
|
||||||
|
Alias: proto.GetAlias(),
|
||||||
|
Name: proto.GetName(),
|
||||||
|
Description: proto.GetDescription(),
|
||||||
|
Avatar: &proto.Avatar,
|
||||||
|
Banner: &proto.Banner,
|
||||||
|
IsPublic: proto.GetIsPublic(),
|
||||||
|
IsCommunity: proto.GetIsCommunity(),
|
||||||
|
AccessPolicy: nex.DecodeMap(proto.GetAccessPolicy()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type RealmMember struct {
|
||||||
|
BaseModel
|
||||||
|
|
||||||
|
RealmID uint `json:"realm_id"`
|
||||||
|
AccountID uint `json:"account_id"`
|
||||||
|
Realm Realm `json:"realm"`
|
||||||
|
Account Account `json:"account"`
|
||||||
|
PowerLevel int `json:"power_level"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewRealmMemberFromProto(proto *proto.RealmMemberInfo) RealmMember {
|
||||||
|
return RealmMember{
|
||||||
|
BaseModel: BaseModel{
|
||||||
|
ID: uint(proto.GetId()),
|
||||||
|
},
|
||||||
|
RealmID: uint(proto.GetRealmId()),
|
||||||
|
AccountID: uint(proto.GetUserId()),
|
||||||
|
PowerLevel: int(proto.GetPowerLevel()),
|
||||||
|
}
|
||||||
|
}
|
23
pkg/authkit/models/relationships.go
Normal file
23
pkg/authkit/models/relationships.go
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import "gorm.io/datatypes"
|
||||||
|
|
||||||
|
type RelationshipStatus = int8
|
||||||
|
|
||||||
|
const (
|
||||||
|
RelationshipPending = RelationshipStatus(iota)
|
||||||
|
RelationshipFriend
|
||||||
|
RelationshipBlocked
|
||||||
|
RelationshipWaiting
|
||||||
|
)
|
||||||
|
|
||||||
|
type AccountRelationship struct {
|
||||||
|
BaseModel
|
||||||
|
|
||||||
|
AccountID uint `json:"account_id"`
|
||||||
|
RelatedID uint `json:"related_id"`
|
||||||
|
Account Account `json:"account"`
|
||||||
|
Related Account `json:"related"`
|
||||||
|
Status RelationshipStatus `json:"status"`
|
||||||
|
PermNodes datatypes.JSONMap `json:"perm_nodes"`
|
||||||
|
}
|
19
pkg/authkit/models/reports.go
Normal file
19
pkg/authkit/models/reports.go
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
const (
|
||||||
|
ReportStatusPending = "pending"
|
||||||
|
ReportStatusReviewing = "reviewing"
|
||||||
|
ReportStatusConfirmed = "confirmed"
|
||||||
|
ReportStatusRejected = "rejected"
|
||||||
|
ReportStatusProcessed = "processed"
|
||||||
|
)
|
||||||
|
|
||||||
|
type AbuseReport struct {
|
||||||
|
BaseModel
|
||||||
|
|
||||||
|
Resource string `json:"resource"`
|
||||||
|
Reason string `json:"reason"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
AccountID uint `json:"account_id"`
|
||||||
|
Account Account `json:"account"`
|
||||||
|
}
|
23
pkg/authkit/models/statuses.go
Normal file
23
pkg/authkit/models/statuses.go
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type StatusAttitude = uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
AttitudeNeutral = StatusAttitude(iota)
|
||||||
|
AttitudePositive
|
||||||
|
AttitudeNegative
|
||||||
|
)
|
||||||
|
|
||||||
|
type Status struct {
|
||||||
|
BaseModel
|
||||||
|
|
||||||
|
Type string `json:"type"`
|
||||||
|
Label string `json:"label"`
|
||||||
|
Attitude StatusAttitude `json:"attitude"`
|
||||||
|
IsNoDisturb bool `json:"is_no_disturb"`
|
||||||
|
IsInvisible bool `json:"is_invisible"`
|
||||||
|
ClearAt *time.Time `json:"clear_at"`
|
||||||
|
AccountID uint `json:"account_id"`
|
||||||
|
}
|
22
pkg/authkit/models/tokens.go
Normal file
22
pkg/authkit/models/tokens.go
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type MagicTokenType = int8
|
||||||
|
|
||||||
|
const (
|
||||||
|
ConfirmMagicToken = MagicTokenType(iota)
|
||||||
|
RegistrationMagicToken
|
||||||
|
ResetPasswordMagicToken
|
||||||
|
DeleteAccountMagicToken
|
||||||
|
)
|
||||||
|
|
||||||
|
type MagicToken struct {
|
||||||
|
BaseModel
|
||||||
|
|
||||||
|
Code string `json:"code"`
|
||||||
|
Type int8 `json:"type"`
|
||||||
|
AccountID *uint `json:"account_id"`
|
||||||
|
ExpiredAt *time.Time `json:"expired_at"`
|
||||||
|
LastNotifiedAt *time.Time `json:"last_notified_at"`
|
||||||
|
}
|
48
pkg/authkit/notify.go
Normal file
48
pkg/authkit/notify.go
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
package authkit
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"git.solsynth.dev/hypernet/nexus/pkg/nex"
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/proto"
|
||||||
|
"git.solsynth.dev/hypernet/pusher/pkg/pushkit"
|
||||||
|
"github.com/goccy/go-json"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NotifyUser(nx *nex.Conn, userId uint64, notify pushkit.Notification, unsaved ...bool) error {
|
||||||
|
conn, err := nx.GetClientGrpcConn(nex.ServiceTypeAuth)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to get auth service client: %v", err)
|
||||||
|
}
|
||||||
|
raw, _ := json.Marshal(notify)
|
||||||
|
if len(unsaved) == 0 {
|
||||||
|
unsaved = append(unsaved, false)
|
||||||
|
}
|
||||||
|
_, err = proto.NewNotifyServiceClient(conn).NotifyUser(context.Background(), &proto.NotifyUserRequest{
|
||||||
|
UserId: userId,
|
||||||
|
Notify: &proto.NotifyInfoPayload{
|
||||||
|
Unsaved: unsaved[0],
|
||||||
|
Data: raw,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func NotifyUserBatch(nx *nex.Conn, userId []uint64, notify pushkit.Notification, unsaved ...bool) error {
|
||||||
|
conn, err := nx.GetClientGrpcConn(nex.ServiceTypeAuth)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to get auth service client: %v", err)
|
||||||
|
}
|
||||||
|
raw, _ := json.Marshal(notify)
|
||||||
|
if len(unsaved) == 0 {
|
||||||
|
unsaved = append(unsaved, false)
|
||||||
|
}
|
||||||
|
_, err = proto.NewNotifyServiceClient(conn).NotifyUserBatch(context.Background(), &proto.NotifyUserBatchRequest{
|
||||||
|
UserId: userId,
|
||||||
|
Notify: &proto.NotifyInfoPayload{
|
||||||
|
Unsaved: unsaved[0],
|
||||||
|
Data: raw,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
return err
|
||||||
|
}
|
27
pkg/authkit/parser.go
Normal file
27
pkg/authkit/parser.go
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package authkit
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.solsynth.dev/hypernet/nexus/pkg/nex/sec"
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/authkit/models"
|
||||||
|
"github.com/goccy/go-json"
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetAccountFromUserInfo returns the account from the user info
|
||||||
|
// This method will not to query the database, it will parse the token and get the subject of the userinfo token
|
||||||
|
func GetAccountFromUserInfo(info *sec.UserInfo) models.Account {
|
||||||
|
raw, _ := json.Marshal(info.Metadata)
|
||||||
|
|
||||||
|
// We assume the token is signed by the same version of service
|
||||||
|
// So directly read the data out of the metadata
|
||||||
|
var out models.Account
|
||||||
|
_ = json.Unmarshal(raw, &out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
func ParseAccountMiddleware(c *fiber.Ctx) error {
|
||||||
|
if info, ok := c.Locals("nex_user").(*sec.UserInfo); ok {
|
||||||
|
c.Locals("user", GetAccountFromUserInfo(info))
|
||||||
|
}
|
||||||
|
return c.Next()
|
||||||
|
}
|
109
pkg/authkit/realm.go
Normal file
109
pkg/authkit/realm.go
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
package authkit
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"git.solsynth.dev/hypernet/nexus/pkg/nex"
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/authkit/models"
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/proto"
|
||||||
|
"github.com/samber/lo"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetRealm(nx *nex.Conn, id uint) (models.Realm, error) {
|
||||||
|
var realm models.Realm
|
||||||
|
conn, err := nx.GetClientGrpcConn(nex.ServiceTypeAuth)
|
||||||
|
if err != nil {
|
||||||
|
return realm, err
|
||||||
|
}
|
||||||
|
resp, err := proto.NewRealmServiceClient(conn).GetRealm(context.Background(), &proto.LookupRealmRequest{
|
||||||
|
Id: lo.ToPtr(uint64(id)),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return realm, err
|
||||||
|
}
|
||||||
|
return models.NewRealmFromProto(resp), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetRealmByAlias(nx *nex.Conn, alias string) (models.Realm, error) {
|
||||||
|
var realm models.Realm
|
||||||
|
conn, err := nx.GetClientGrpcConn(nex.ServiceTypeAuth)
|
||||||
|
if err != nil {
|
||||||
|
return realm, err
|
||||||
|
}
|
||||||
|
resp, err := proto.NewRealmServiceClient(conn).GetRealm(context.Background(), &proto.LookupRealmRequest{
|
||||||
|
Alias: &alias,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return realm, err
|
||||||
|
}
|
||||||
|
return models.NewRealmFromProto(resp), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ListRealm(nx *nex.Conn, id []uint) ([]models.Realm, error) {
|
||||||
|
var realms []models.Realm
|
||||||
|
conn, err := nx.GetClientGrpcConn(nex.ServiceTypeAuth)
|
||||||
|
if err != nil {
|
||||||
|
return realms, err
|
||||||
|
}
|
||||||
|
resp, err := proto.NewRealmServiceClient(conn).ListRealm(context.Background(), &proto.ListRealmRequest{
|
||||||
|
Id: lo.Map(id, func(item uint, _ int) uint64 {
|
||||||
|
return uint64(item)
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return realms, err
|
||||||
|
}
|
||||||
|
for _, realm := range resp.GetData() {
|
||||||
|
realms = append(realms, models.NewRealmFromProto(realm))
|
||||||
|
}
|
||||||
|
return realms, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetRealmMember(nx *nex.Conn, realmID, userID uint) (models.RealmMember, error) {
|
||||||
|
var member models.RealmMember
|
||||||
|
conn, err := nx.GetClientGrpcConn(nex.ServiceTypeAuth)
|
||||||
|
if err != nil {
|
||||||
|
return member, err
|
||||||
|
}
|
||||||
|
resp, err := proto.NewRealmServiceClient(conn).GetRealmMember(context.Background(), &proto.RealmMemberLookupRequest{
|
||||||
|
RealmId: lo.ToPtr(uint64(realmID)),
|
||||||
|
UserId: lo.ToPtr(uint64(userID)),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return member, err
|
||||||
|
}
|
||||||
|
return models.NewRealmMemberFromProto(resp), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ListRealmMember(nx *nex.Conn, realmID uint) ([]models.RealmMember, error) {
|
||||||
|
var members []models.RealmMember
|
||||||
|
conn, err := nx.GetClientGrpcConn(nex.ServiceTypeAuth)
|
||||||
|
if err != nil {
|
||||||
|
return members, err
|
||||||
|
}
|
||||||
|
resp, err := proto.NewRealmServiceClient(conn).ListRealmMember(context.Background(), &proto.RealmMemberLookupRequest{
|
||||||
|
RealmId: lo.ToPtr(uint64(realmID)),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return members, err
|
||||||
|
}
|
||||||
|
for _, member := range resp.GetData() {
|
||||||
|
members = append(members, models.NewRealmMemberFromProto(member))
|
||||||
|
}
|
||||||
|
return members, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func CheckRealmMemberPerm(nx *nex.Conn, realmID uint, userID, power int) bool {
|
||||||
|
conn, err := nx.GetClientGrpcConn(nex.ServiceTypeAuth)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
resp, err := proto.NewRealmServiceClient(conn).CheckRealmMemberPerm(context.Background(), &proto.CheckRealmPermRequest{
|
||||||
|
RealmId: uint64(realmID),
|
||||||
|
UserId: uint64(userID),
|
||||||
|
PowerLevel: int32(power),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return resp.GetIsSuccess()
|
||||||
|
}
|
23
pkg/authkit/relative.go
Normal file
23
pkg/authkit/relative.go
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
package authkit
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"git.solsynth.dev/hypernet/nexus/pkg/nex"
|
||||||
|
"git.solsynth.dev/hypernet/nexus/pkg/proto"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ListRelative(nx *nex.Conn, userId uint, status int32, isRelated bool) ([]*proto.UserInfo, error) {
|
||||||
|
conn, err := nx.GetClientGrpcConn(nex.ServiceTypeAuth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
resp, err := proto.NewUserServiceClient(conn).ListUserRelative(context.Background(), &proto.ListUserRelativeRequest{
|
||||||
|
UserId: uint64(userId),
|
||||||
|
Status: status,
|
||||||
|
IsRelated: isRelated,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return resp.GetData(), err
|
||||||
|
}
|
65
pkg/authkit/third_client.go
Normal file
65
pkg/authkit/third_client.go
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
package authkit
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"git.solsynth.dev/hypernet/nexus/pkg/nex"
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/authkit/models"
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/proto"
|
||||||
|
"github.com/samber/lo"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetThirdClient(nx *nex.Conn, id uint, secret *string) (*models.ThirdClient, error) {
|
||||||
|
conn, err := nx.GetClientGrpcConn(nex.ServiceTypeAuth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to get auth service client: %v", err)
|
||||||
|
}
|
||||||
|
resp, err := proto.NewThirdClientServiceClient(conn).
|
||||||
|
GetThirdClient(context.Background(), &proto.GetThirdClientRequest{
|
||||||
|
Id: lo.ToPtr(uint64(id)),
|
||||||
|
Secret: secret,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &models.ThirdClient{
|
||||||
|
Alias: resp.GetInfo().GetAlias(),
|
||||||
|
Name: resp.GetInfo().GetName(),
|
||||||
|
Description: resp.GetInfo().GetDescription(),
|
||||||
|
IsDraft: resp.GetInfo().GetIsDraft(),
|
||||||
|
AccountID: lo.TernaryF(resp.GetInfo().AccountId != nil, func() *uint {
|
||||||
|
return lo.ToPtr(uint(resp.GetInfo().GetAccountId()))
|
||||||
|
}, func() *uint {
|
||||||
|
return nil
|
||||||
|
}),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetThirdClientByAlias(nx *nex.Conn, alias string, secret *string) (*models.ThirdClient, error) {
|
||||||
|
conn, err := nx.GetClientGrpcConn(nex.ServiceTypeAuth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to get auth service client: %v", err)
|
||||||
|
}
|
||||||
|
resp, err := proto.NewThirdClientServiceClient(conn).
|
||||||
|
GetThirdClient(context.Background(), &proto.GetThirdClientRequest{
|
||||||
|
Alias: &alias,
|
||||||
|
Secret: secret,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &models.ThirdClient{
|
||||||
|
Alias: resp.GetInfo().GetAlias(),
|
||||||
|
Name: resp.GetInfo().GetName(),
|
||||||
|
Description: resp.GetInfo().GetDescription(),
|
||||||
|
IsDraft: resp.GetInfo().GetIsDraft(),
|
||||||
|
AccountID: lo.TernaryF(resp.GetInfo().AccountId != nil, func() *uint {
|
||||||
|
return lo.ToPtr(uint(resp.GetInfo().GetAccountId()))
|
||||||
|
}, func() *uint {
|
||||||
|
return nil
|
||||||
|
}),
|
||||||
|
}, nil
|
||||||
|
}
|
118
pkg/authkit/user.go
Normal file
118
pkg/authkit/user.go
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
package authkit
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"git.solsynth.dev/hypernet/nexus/pkg/nex"
|
||||||
|
"git.solsynth.dev/hypernet/nexus/pkg/nex/cachekit"
|
||||||
|
"git.solsynth.dev/hypernet/nexus/pkg/nex/sec"
|
||||||
|
"git.solsynth.dev/hypernet/nexus/pkg/proto"
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/authkit/models"
|
||||||
|
"github.com/samber/lo"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetUser(nx *nex.Conn, userId uint) (models.Account, error) {
|
||||||
|
cacheConn, err := cachekit.NewConn(nx, 3*time.Second)
|
||||||
|
if err == nil {
|
||||||
|
key := cachekit.FKey(cachekit.DAAttachment, userId)
|
||||||
|
if user, err := cachekit.Get[models.Account](cacheConn, key); err == nil {
|
||||||
|
return user, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
conn, err := nx.GetClientGrpcConn(nex.ServiceTypeAuth)
|
||||||
|
if err != nil {
|
||||||
|
return models.Account{}, err
|
||||||
|
}
|
||||||
|
raw, _ := proto.NewUserServiceClient(conn).GetUser(context.Background(), &proto.GetUserRequest{
|
||||||
|
UserId: lo.ToPtr(uint64(userId)),
|
||||||
|
})
|
||||||
|
return GetAccountFromUserInfo(&sec.UserInfo{
|
||||||
|
ID: uint(raw.GetId()),
|
||||||
|
Name: raw.GetName(),
|
||||||
|
PermNodes: nex.DecodeMap(raw.GetPermNodes()),
|
||||||
|
Metadata: nex.DecodeMap(raw.GetMetadata()),
|
||||||
|
}), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetUserByName(nx *nex.Conn, name string) (models.Account, error) {
|
||||||
|
cacheConn, err := cachekit.NewConn(nx, 3*time.Second)
|
||||||
|
if err == nil {
|
||||||
|
key := cachekit.FKey(cachekit.DAAttachment, name)
|
||||||
|
if user, err := cachekit.Get[models.Account](cacheConn, key); err == nil {
|
||||||
|
return user, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
conn, err := nx.GetClientGrpcConn(nex.ServiceTypeAuth)
|
||||||
|
if err != nil {
|
||||||
|
return models.Account{}, err
|
||||||
|
}
|
||||||
|
raw, _ := proto.NewUserServiceClient(conn).GetUser(context.Background(), &proto.GetUserRequest{
|
||||||
|
Name: &name,
|
||||||
|
})
|
||||||
|
return GetAccountFromUserInfo(&sec.UserInfo{
|
||||||
|
ID: uint(raw.GetId()),
|
||||||
|
Name: raw.GetName(),
|
||||||
|
PermNodes: nex.DecodeMap(raw.GetPermNodes()),
|
||||||
|
Metadata: nex.DecodeMap(raw.GetMetadata()),
|
||||||
|
}), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ListUser(nx *nex.Conn, userIds []uint) ([]models.Account, error) {
|
||||||
|
var accounts []models.Account
|
||||||
|
var missingId []uint
|
||||||
|
cachedUsers := make(map[uint]models.Account)
|
||||||
|
|
||||||
|
// Try to get users from cache
|
||||||
|
cacheConn, err := cachekit.NewConn(nx, 3*time.Second)
|
||||||
|
if err == nil {
|
||||||
|
for _, userId := range userIds {
|
||||||
|
key := cachekit.FKey(cachekit.DAAttachment, userId)
|
||||||
|
if user, err := cachekit.Get[models.Account](cacheConn, key); err == nil {
|
||||||
|
cachedUsers[userId] = user
|
||||||
|
} else {
|
||||||
|
missingId = append(missingId, userId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If all users are found in cache, return them
|
||||||
|
if len(missingId) == 0 {
|
||||||
|
for _, account := range cachedUsers {
|
||||||
|
accounts = append(accounts, account)
|
||||||
|
}
|
||||||
|
return accounts, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch missing users from the gRPC service
|
||||||
|
conn, err := nx.GetClientGrpcConn(nex.ServiceTypeAuth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
raw, _ := proto.NewUserServiceClient(conn).ListUser(context.Background(), &proto.ListUserRequest{
|
||||||
|
UserId: lo.Map(missingId, func(item uint, index int) uint64 {
|
||||||
|
return uint64(item)
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
|
||||||
|
// Convert fetched users and add to the result
|
||||||
|
for _, item := range raw.GetData() {
|
||||||
|
account := GetAccountFromUserInfo(&sec.UserInfo{
|
||||||
|
ID: uint(item.GetId()),
|
||||||
|
Name: item.GetName(),
|
||||||
|
PermNodes: nex.DecodeMap(item.GetPermNodes()),
|
||||||
|
Metadata: nex.DecodeMap(item.GetMetadata()),
|
||||||
|
})
|
||||||
|
accounts = append(accounts, account)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Merge cached and fetched results
|
||||||
|
for _, account := range cachedUsers {
|
||||||
|
accounts = append(accounts, account)
|
||||||
|
}
|
||||||
|
|
||||||
|
return accounts, nil
|
||||||
|
}
|
@ -1,89 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"git.solsynth.dev/hydrogen/passport/pkg"
|
|
||||||
"git.solsynth.dev/hydrogen/passport/pkg/i18n"
|
|
||||||
"os"
|
|
||||||
"os/signal"
|
|
||||||
"syscall"
|
|
||||||
|
|
||||||
"git.solsynth.dev/hydrogen/passport/pkg/external"
|
|
||||||
"git.solsynth.dev/hydrogen/passport/pkg/grpc"
|
|
||||||
"git.solsynth.dev/hydrogen/passport/pkg/server"
|
|
||||||
"git.solsynth.dev/hydrogen/passport/pkg/services"
|
|
||||||
"github.com/robfig/cron/v3"
|
|
||||||
|
|
||||||
"git.solsynth.dev/hydrogen/passport/pkg/database"
|
|
||||||
"github.com/rs/zerolog"
|
|
||||||
"github.com/rs/zerolog/log"
|
|
||||||
"github.com/spf13/viper"
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
zerolog.TimeFieldFormat = zerolog.TimeFormatUnix
|
|
||||||
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stdout})
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
// Configure settings
|
|
||||||
viper.AddConfigPath(".")
|
|
||||||
viper.AddConfigPath("..")
|
|
||||||
viper.SetConfigName("settings")
|
|
||||||
viper.SetConfigType("toml")
|
|
||||||
|
|
||||||
// Load settings
|
|
||||||
if err := viper.ReadInConfig(); err != nil {
|
|
||||||
log.Panic().Err(err).Msg("An error occurred when loading settings.")
|
|
||||||
}
|
|
||||||
|
|
||||||
i18n.InitInternationalization()
|
|
||||||
|
|
||||||
// Connect to database
|
|
||||||
if err := database.NewGorm(); err != nil {
|
|
||||||
log.Fatal().Err(err).Msg("An error occurred when connect to database.")
|
|
||||||
} else if err := database.RunMigration(database.C); err != nil {
|
|
||||||
log.Fatal().Err(err).Msg("An error occurred when running database auto migration.")
|
|
||||||
}
|
|
||||||
if err := database.NewBolt(); err != nil {
|
|
||||||
log.Fatal().Err(err).Msg("An error occurred when init bolt db.")
|
|
||||||
}
|
|
||||||
|
|
||||||
// External
|
|
||||||
// All the things are optional so when error occurred the server won't crash
|
|
||||||
if err := external.SetupFirebase(viper.GetString("external.firebase.credentials")); err != nil {
|
|
||||||
log.Error().Err(err).Msg("An error occurred when starting firebase communicating...")
|
|
||||||
} else {
|
|
||||||
log.Info().Msg("Successfully setup firebase communication.")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Server
|
|
||||||
server.NewServer()
|
|
||||||
go server.Listen()
|
|
||||||
|
|
||||||
// Grpc Server
|
|
||||||
go func() {
|
|
||||||
if err := grpc.StartGrpc(); err != nil {
|
|
||||||
log.Fatal().Err(err).Msg("An message occurred when starting grpc server.")
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
// Configure timed tasks
|
|
||||||
quartz := cron.New(cron.WithLogger(cron.VerbosePrintfLogger(&log.Logger)))
|
|
||||||
quartz.AddFunc("@every 60m", services.DoAutoSignoff)
|
|
||||||
quartz.AddFunc("@every 60m", services.DoAutoAuthCleanup)
|
|
||||||
quartz.AddFunc("@every 60m", services.DoAutoDatabaseCleanup)
|
|
||||||
quartz.Start()
|
|
||||||
|
|
||||||
// Messages
|
|
||||||
log.Info().Msgf("Passport v%s is started...", pkg.AppVersion)
|
|
||||||
|
|
||||||
quit := make(chan os.Signal, 1)
|
|
||||||
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
|
|
||||||
<-quit
|
|
||||||
|
|
||||||
log.Info().Msgf("Passport v%s is quitting...", pkg.AppVersion)
|
|
||||||
|
|
||||||
quartz.Stop()
|
|
||||||
|
|
||||||
database.B.Close()
|
|
||||||
}
|
|
@ -1,31 +0,0 @@
|
|||||||
package database
|
|
||||||
|
|
||||||
import (
|
|
||||||
"git.solsynth.dev/hydrogen/passport/pkg/models"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
var DatabaseAutoActionRange = []any{
|
|
||||||
&models.Account{},
|
|
||||||
&models.AuthFactor{},
|
|
||||||
&models.AccountProfile{},
|
|
||||||
&models.AccountPage{},
|
|
||||||
&models.AccountContact{},
|
|
||||||
&models.AccountFriendship{},
|
|
||||||
&models.Realm{},
|
|
||||||
&models.RealmMember{},
|
|
||||||
&models.AuthTicket{},
|
|
||||||
&models.MagicToken{},
|
|
||||||
&models.ThirdClient{},
|
|
||||||
&models.ActionEvent{},
|
|
||||||
&models.Notification{},
|
|
||||||
&models.NotificationSubscriber{},
|
|
||||||
}
|
|
||||||
|
|
||||||
func RunMigration(source *gorm.DB) error {
|
|
||||||
if err := source.AutoMigrate(DatabaseAutoActionRange...); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
package database
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/rs/zerolog/log"
|
|
||||||
"github.com/samber/lo"
|
|
||||||
"github.com/spf13/viper"
|
|
||||||
"go.etcd.io/bbolt"
|
|
||||||
"gorm.io/driver/postgres"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
"gorm.io/gorm/logger"
|
|
||||||
"gorm.io/gorm/schema"
|
|
||||||
)
|
|
||||||
|
|
||||||
var C *gorm.DB
|
|
||||||
|
|
||||||
func NewGorm() error {
|
|
||||||
var err error
|
|
||||||
|
|
||||||
dialector := postgres.Open(viper.GetString("database.dsn"))
|
|
||||||
C, err = gorm.Open(dialector, &gorm.Config{NamingStrategy: schema.NamingStrategy{
|
|
||||||
TablePrefix: viper.GetString("database.prefix"),
|
|
||||||
}, Logger: logger.New(&log.Logger, logger.Config{
|
|
||||||
Colorful: true,
|
|
||||||
IgnoreRecordNotFoundError: true,
|
|
||||||
LogLevel: lo.Ternary(viper.GetBool("debug.database"), logger.Info, logger.Silent),
|
|
||||||
})})
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
var B *bbolt.DB
|
|
||||||
|
|
||||||
func NewBolt() error {
|
|
||||||
var err error
|
|
||||||
|
|
||||||
dsn := viper.GetString("database.bolt")
|
|
||||||
B, err = bbolt.Open(dsn, 0600, nil)
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
package pkg
|
|
||||||
|
|
||||||
import "embed"
|
|
||||||
|
|
||||||
//go:embed views/*
|
|
||||||
var FS embed.FS
|
|
21
pkg/external/firebase.go
vendored
21
pkg/external/firebase.go
vendored
@ -1,21 +0,0 @@
|
|||||||
package external
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
firebase "firebase.google.com/go"
|
|
||||||
"google.golang.org/api/option"
|
|
||||||
)
|
|
||||||
|
|
||||||
var Fire *firebase.App
|
|
||||||
|
|
||||||
func SetupFirebase(credentials string) error {
|
|
||||||
opt := option.WithCredentialsFile(credentials)
|
|
||||||
app, err := firebase.NewApp(context.Background(), nil, opt)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
} else {
|
|
||||||
Fire = app
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
package grpc
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"git.solsynth.dev/hydrogen/passport/pkg/grpc/proto"
|
|
||||||
"git.solsynth.dev/hydrogen/passport/pkg/services"
|
|
||||||
"github.com/spf13/viper"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (v *Server) Authenticate(_ context.Context, in *proto.AuthRequest) (*proto.AuthReply, error) {
|
|
||||||
user, atk, rtk, err := services.Authenticate(in.GetAccessToken(), in.GetRefreshToken(), 0)
|
|
||||||
if err != nil {
|
|
||||||
return &proto.AuthReply{
|
|
||||||
IsValid: false,
|
|
||||||
}, nil
|
|
||||||
} else {
|
|
||||||
return &proto.AuthReply{
|
|
||||||
IsValid: true,
|
|
||||||
AccessToken: &atk,
|
|
||||||
RefreshToken: &rtk,
|
|
||||||
Userinfo: &proto.Userinfo{
|
|
||||||
Id: uint64(user.ID),
|
|
||||||
Name: user.Name,
|
|
||||||
Nick: user.Nick,
|
|
||||||
Email: user.GetPrimaryEmail().Content,
|
|
||||||
Avatar: fmt.Sprintf("https://%s/api/avatar/%s", viper.GetString("domain"), user.Avatar),
|
|
||||||
Banner: fmt.Sprintf("https://%s/api/avatar/%s", viper.GetString("domain"), user.Banner),
|
|
||||||
Description: &user.Description,
|
|
||||||
},
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,46 +0,0 @@
|
|||||||
package grpc
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"git.solsynth.dev/hydrogen/passport/pkg/grpc/proto"
|
|
||||||
"git.solsynth.dev/hydrogen/passport/pkg/models"
|
|
||||||
"git.solsynth.dev/hydrogen/passport/pkg/services"
|
|
||||||
"github.com/samber/lo"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (v *Server) ListFriendship(_ context.Context, request *proto.FriendshipLookupRequest) (*proto.ListFriendshipResponse, error) {
|
|
||||||
account, err := services.GetAccount(uint(request.GetAccountId()))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
friends, err := services.ListFriend(account, models.FriendshipStatus(request.GetStatus()))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &proto.ListFriendshipResponse{
|
|
||||||
Data: lo.Map(friends, func(item models.AccountFriendship, index int) *proto.FriendshipResponse {
|
|
||||||
return &proto.FriendshipResponse{
|
|
||||||
AccountId: uint64(item.AccountID),
|
|
||||||
RelatedId: uint64(item.RelatedID),
|
|
||||||
Status: uint32(item.Status),
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Server) GetFriendship(ctx context.Context, request *proto.FriendshipTwoSideLookupRequest) (*proto.FriendshipResponse, error) {
|
|
||||||
friend, err := services.GetFriendWithTwoSides(uint(request.GetAccountId()), uint(request.GetRelatedId()))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else if friend.Status != models.FriendshipStatus(request.GetStatus()) {
|
|
||||||
return nil, fmt.Errorf("status mismatch")
|
|
||||||
}
|
|
||||||
|
|
||||||
return &proto.FriendshipResponse{
|
|
||||||
AccountId: uint64(friend.AccountID),
|
|
||||||
RelatedId: uint64(friend.RelatedID),
|
|
||||||
Status: uint32(friend.Status),
|
|
||||||
}, nil
|
|
||||||
}
|
|
@ -1,52 +0,0 @@
|
|||||||
package grpc
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"git.solsynth.dev/hydrogen/passport/pkg/grpc/proto"
|
|
||||||
"git.solsynth.dev/hydrogen/passport/pkg/models"
|
|
||||||
"git.solsynth.dev/hydrogen/passport/pkg/services"
|
|
||||||
"github.com/samber/lo"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (v *Server) NotifyUser(_ context.Context, in *proto.NotifyRequest) (*proto.NotifyReply, error) {
|
|
||||||
client, err := services.GetThirdClientWithSecret(in.GetClientId(), in.GetClientSecret())
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var user models.Account
|
|
||||||
if user, err = services.GetAccount(uint(in.GetRecipientId())); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
links := lo.Map(in.GetLinks(), func(item *proto.NotifyLink, index int) models.NotificationLink {
|
|
||||||
return models.NotificationLink{
|
|
||||||
Label: item.Label,
|
|
||||||
Url: item.Url,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
notification := models.Notification{
|
|
||||||
Subject: in.GetSubject(),
|
|
||||||
Content: in.GetContent(),
|
|
||||||
Links: links,
|
|
||||||
IsImportant: in.GetIsImportant(),
|
|
||||||
IsRealtime: in.GetIsRealtime(),
|
|
||||||
ReadAt: nil,
|
|
||||||
RecipientID: user.ID,
|
|
||||||
SenderID: &client.ID,
|
|
||||||
}
|
|
||||||
|
|
||||||
if in.GetIsRealtime() {
|
|
||||||
if err := services.PushNotification(notification); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if err := services.NewNotification(notification); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return &proto.NotifyReply{IsSent: true}, nil
|
|
||||||
}
|
|
@ -1,382 +0,0 @@
|
|||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
|
||||||
// versions:
|
|
||||||
// protoc-gen-go v1.33.0
|
|
||||||
// protoc v4.25.3
|
|
||||||
// source: auth.proto
|
|
||||||
|
|
||||||
package proto
|
|
||||||
|
|
||||||
import (
|
|
||||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
|
||||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
|
||||||
reflect "reflect"
|
|
||||||
sync "sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// Verify that this generated code is sufficiently up-to-date.
|
|
||||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
|
||||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
|
||||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
|
||||||
)
|
|
||||||
|
|
||||||
type Userinfo struct {
|
|
||||||
state protoimpl.MessageState
|
|
||||||
sizeCache protoimpl.SizeCache
|
|
||||||
unknownFields protoimpl.UnknownFields
|
|
||||||
|
|
||||||
Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
|
|
||||||
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
|
|
||||||
Nick string `protobuf:"bytes,3,opt,name=nick,proto3" json:"nick,omitempty"`
|
|
||||||
Email string `protobuf:"bytes,4,opt,name=email,proto3" json:"email,omitempty"`
|
|
||||||
Avatar string `protobuf:"bytes,5,opt,name=avatar,proto3" json:"avatar,omitempty"`
|
|
||||||
Banner string `protobuf:"bytes,6,opt,name=banner,proto3" json:"banner,omitempty"`
|
|
||||||
Description *string `protobuf:"bytes,7,opt,name=description,proto3,oneof" json:"description,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *Userinfo) Reset() {
|
|
||||||
*x = Userinfo{}
|
|
||||||
if protoimpl.UnsafeEnabled {
|
|
||||||
mi := &file_auth_proto_msgTypes[0]
|
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
||||||
ms.StoreMessageInfo(mi)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *Userinfo) String() string {
|
|
||||||
return protoimpl.X.MessageStringOf(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*Userinfo) ProtoMessage() {}
|
|
||||||
|
|
||||||
func (x *Userinfo) ProtoReflect() protoreflect.Message {
|
|
||||||
mi := &file_auth_proto_msgTypes[0]
|
|
||||||
if protoimpl.UnsafeEnabled && x != nil {
|
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
||||||
if ms.LoadMessageInfo() == nil {
|
|
||||||
ms.StoreMessageInfo(mi)
|
|
||||||
}
|
|
||||||
return ms
|
|
||||||
}
|
|
||||||
return mi.MessageOf(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Use Userinfo.ProtoReflect.Descriptor instead.
|
|
||||||
func (*Userinfo) Descriptor() ([]byte, []int) {
|
|
||||||
return file_auth_proto_rawDescGZIP(), []int{0}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *Userinfo) GetId() uint64 {
|
|
||||||
if x != nil {
|
|
||||||
return x.Id
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *Userinfo) GetName() string {
|
|
||||||
if x != nil {
|
|
||||||
return x.Name
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *Userinfo) GetNick() string {
|
|
||||||
if x != nil {
|
|
||||||
return x.Nick
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *Userinfo) GetEmail() string {
|
|
||||||
if x != nil {
|
|
||||||
return x.Email
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *Userinfo) GetAvatar() string {
|
|
||||||
if x != nil {
|
|
||||||
return x.Avatar
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *Userinfo) GetBanner() string {
|
|
||||||
if x != nil {
|
|
||||||
return x.Banner
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *Userinfo) GetDescription() string {
|
|
||||||
if x != nil && x.Description != nil {
|
|
||||||
return *x.Description
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
type AuthRequest struct {
|
|
||||||
state protoimpl.MessageState
|
|
||||||
sizeCache protoimpl.SizeCache
|
|
||||||
unknownFields protoimpl.UnknownFields
|
|
||||||
|
|
||||||
AccessToken string `protobuf:"bytes,1,opt,name=access_token,json=accessToken,proto3" json:"access_token,omitempty"`
|
|
||||||
RefreshToken *string `protobuf:"bytes,2,opt,name=refresh_token,json=refreshToken,proto3,oneof" json:"refresh_token,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *AuthRequest) Reset() {
|
|
||||||
*x = AuthRequest{}
|
|
||||||
if protoimpl.UnsafeEnabled {
|
|
||||||
mi := &file_auth_proto_msgTypes[1]
|
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
||||||
ms.StoreMessageInfo(mi)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *AuthRequest) String() string {
|
|
||||||
return protoimpl.X.MessageStringOf(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*AuthRequest) ProtoMessage() {}
|
|
||||||
|
|
||||||
func (x *AuthRequest) ProtoReflect() protoreflect.Message {
|
|
||||||
mi := &file_auth_proto_msgTypes[1]
|
|
||||||
if protoimpl.UnsafeEnabled && x != nil {
|
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
||||||
if ms.LoadMessageInfo() == nil {
|
|
||||||
ms.StoreMessageInfo(mi)
|
|
||||||
}
|
|
||||||
return ms
|
|
||||||
}
|
|
||||||
return mi.MessageOf(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Use AuthRequest.ProtoReflect.Descriptor instead.
|
|
||||||
func (*AuthRequest) Descriptor() ([]byte, []int) {
|
|
||||||
return file_auth_proto_rawDescGZIP(), []int{1}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *AuthRequest) GetAccessToken() string {
|
|
||||||
if x != nil {
|
|
||||||
return x.AccessToken
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *AuthRequest) GetRefreshToken() string {
|
|
||||||
if x != nil && x.RefreshToken != nil {
|
|
||||||
return *x.RefreshToken
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
type AuthReply struct {
|
|
||||||
state protoimpl.MessageState
|
|
||||||
sizeCache protoimpl.SizeCache
|
|
||||||
unknownFields protoimpl.UnknownFields
|
|
||||||
|
|
||||||
IsValid bool `protobuf:"varint,1,opt,name=is_valid,json=isValid,proto3" json:"is_valid,omitempty"`
|
|
||||||
AccessToken *string `protobuf:"bytes,2,opt,name=access_token,json=accessToken,proto3,oneof" json:"access_token,omitempty"`
|
|
||||||
RefreshToken *string `protobuf:"bytes,3,opt,name=refresh_token,json=refreshToken,proto3,oneof" json:"refresh_token,omitempty"`
|
|
||||||
Userinfo *Userinfo `protobuf:"bytes,4,opt,name=userinfo,proto3,oneof" json:"userinfo,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *AuthReply) Reset() {
|
|
||||||
*x = AuthReply{}
|
|
||||||
if protoimpl.UnsafeEnabled {
|
|
||||||
mi := &file_auth_proto_msgTypes[2]
|
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
||||||
ms.StoreMessageInfo(mi)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *AuthReply) String() string {
|
|
||||||
return protoimpl.X.MessageStringOf(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*AuthReply) ProtoMessage() {}
|
|
||||||
|
|
||||||
func (x *AuthReply) ProtoReflect() protoreflect.Message {
|
|
||||||
mi := &file_auth_proto_msgTypes[2]
|
|
||||||
if protoimpl.UnsafeEnabled && x != nil {
|
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
||||||
if ms.LoadMessageInfo() == nil {
|
|
||||||
ms.StoreMessageInfo(mi)
|
|
||||||
}
|
|
||||||
return ms
|
|
||||||
}
|
|
||||||
return mi.MessageOf(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Use AuthReply.ProtoReflect.Descriptor instead.
|
|
||||||
func (*AuthReply) Descriptor() ([]byte, []int) {
|
|
||||||
return file_auth_proto_rawDescGZIP(), []int{2}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *AuthReply) GetIsValid() bool {
|
|
||||||
if x != nil {
|
|
||||||
return x.IsValid
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *AuthReply) GetAccessToken() string {
|
|
||||||
if x != nil && x.AccessToken != nil {
|
|
||||||
return *x.AccessToken
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *AuthReply) GetRefreshToken() string {
|
|
||||||
if x != nil && x.RefreshToken != nil {
|
|
||||||
return *x.RefreshToken
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *AuthReply) GetUserinfo() *Userinfo {
|
|
||||||
if x != nil {
|
|
||||||
return x.Userinfo
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var File_auth_proto protoreflect.FileDescriptor
|
|
||||||
|
|
||||||
var file_auth_proto_rawDesc = []byte{
|
|
||||||
0x0a, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x70, 0x72,
|
|
||||||
0x6f, 0x74, 0x6f, 0x22, 0xbf, 0x01, 0x0a, 0x08, 0x55, 0x73, 0x65, 0x72, 0x69, 0x6e, 0x66, 0x6f,
|
|
||||||
0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x69, 0x64,
|
|
||||||
0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
|
|
||||||
0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x69, 0x63, 0x6b, 0x18, 0x03, 0x20, 0x01,
|
|
||||||
0x28, 0x09, 0x52, 0x04, 0x6e, 0x69, 0x63, 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69,
|
|
||||||
0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x16,
|
|
||||||
0x0a, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06,
|
|
||||||
0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x61, 0x6e, 0x6e, 0x65, 0x72,
|
|
||||||
0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x62, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x12, 0x25,
|
|
||||||
0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20,
|
|
||||||
0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69,
|
|
||||||
0x6f, 0x6e, 0x88, 0x01, 0x01, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69,
|
|
||||||
0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x6c, 0x0a, 0x0b, 0x41, 0x75, 0x74, 0x68, 0x52, 0x65, 0x71,
|
|
||||||
0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74,
|
|
||||||
0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x65,
|
|
||||||
0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x28, 0x0a, 0x0d, 0x72, 0x65, 0x66, 0x72, 0x65,
|
|
||||||
0x73, 0x68, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00,
|
|
||||||
0x52, 0x0c, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x88, 0x01,
|
|
||||||
0x01, 0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x5f, 0x74, 0x6f,
|
|
||||||
0x6b, 0x65, 0x6e, 0x22, 0xda, 0x01, 0x0a, 0x09, 0x41, 0x75, 0x74, 0x68, 0x52, 0x65, 0x70, 0x6c,
|
|
||||||
0x79, 0x12, 0x19, 0x0a, 0x08, 0x69, 0x73, 0x5f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x18, 0x01, 0x20,
|
|
||||||
0x01, 0x28, 0x08, 0x52, 0x07, 0x69, 0x73, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x12, 0x26, 0x0a, 0x0c,
|
|
||||||
0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01,
|
|
||||||
0x28, 0x09, 0x48, 0x00, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65,
|
|
||||||
0x6e, 0x88, 0x01, 0x01, 0x12, 0x28, 0x0a, 0x0d, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x5f,
|
|
||||||
0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x0c, 0x72,
|
|
||||||
0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x88, 0x01, 0x01, 0x12, 0x30,
|
|
||||||
0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b,
|
|
||||||
0x32, 0x0f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x69, 0x6e, 0x66,
|
|
||||||
0x6f, 0x48, 0x02, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x69, 0x6e, 0x66, 0x6f, 0x88, 0x01, 0x01,
|
|
||||||
0x42, 0x0f, 0x0a, 0x0d, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65,
|
|
||||||
0x6e, 0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x5f, 0x74, 0x6f,
|
|
||||||
0x6b, 0x65, 0x6e, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x69, 0x6e, 0x66, 0x6f,
|
|
||||||
0x32, 0x3e, 0x0a, 0x04, 0x41, 0x75, 0x74, 0x68, 0x12, 0x36, 0x0a, 0x0c, 0x41, 0x75, 0x74, 0x68,
|
|
||||||
0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
|
||||||
0x2e, 0x41, 0x75, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x70,
|
|
||||||
0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00,
|
|
||||||
0x42, 0x09, 0x5a, 0x07, 0x2e, 0x3b, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f,
|
|
||||||
0x74, 0x6f, 0x33,
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
file_auth_proto_rawDescOnce sync.Once
|
|
||||||
file_auth_proto_rawDescData = file_auth_proto_rawDesc
|
|
||||||
)
|
|
||||||
|
|
||||||
func file_auth_proto_rawDescGZIP() []byte {
|
|
||||||
file_auth_proto_rawDescOnce.Do(func() {
|
|
||||||
file_auth_proto_rawDescData = protoimpl.X.CompressGZIP(file_auth_proto_rawDescData)
|
|
||||||
})
|
|
||||||
return file_auth_proto_rawDescData
|
|
||||||
}
|
|
||||||
|
|
||||||
var file_auth_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
|
|
||||||
var file_auth_proto_goTypes = []interface{}{
|
|
||||||
(*Userinfo)(nil), // 0: proto.Userinfo
|
|
||||||
(*AuthRequest)(nil), // 1: proto.AuthRequest
|
|
||||||
(*AuthReply)(nil), // 2: proto.AuthReply
|
|
||||||
}
|
|
||||||
var file_auth_proto_depIdxs = []int32{
|
|
||||||
0, // 0: proto.AuthReply.userinfo:type_name -> proto.Userinfo
|
|
||||||
1, // 1: proto.Auth.Authenticate:input_type -> proto.AuthRequest
|
|
||||||
2, // 2: proto.Auth.Authenticate:output_type -> proto.AuthReply
|
|
||||||
2, // [2:3] is the sub-list for method output_type
|
|
||||||
1, // [1:2] is the sub-list for method input_type
|
|
||||||
1, // [1:1] is the sub-list for extension type_name
|
|
||||||
1, // [1:1] is the sub-list for extension extendee
|
|
||||||
0, // [0:1] is the sub-list for field type_name
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() { file_auth_proto_init() }
|
|
||||||
func file_auth_proto_init() {
|
|
||||||
if File_auth_proto != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if !protoimpl.UnsafeEnabled {
|
|
||||||
file_auth_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
|
||||||
switch v := v.(*Userinfo); i {
|
|
||||||
case 0:
|
|
||||||
return &v.state
|
|
||||||
case 1:
|
|
||||||
return &v.sizeCache
|
|
||||||
case 2:
|
|
||||||
return &v.unknownFields
|
|
||||||
default:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
file_auth_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
|
||||||
switch v := v.(*AuthRequest); i {
|
|
||||||
case 0:
|
|
||||||
return &v.state
|
|
||||||
case 1:
|
|
||||||
return &v.sizeCache
|
|
||||||
case 2:
|
|
||||||
return &v.unknownFields
|
|
||||||
default:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
file_auth_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
|
||||||
switch v := v.(*AuthReply); i {
|
|
||||||
case 0:
|
|
||||||
return &v.state
|
|
||||||
case 1:
|
|
||||||
return &v.sizeCache
|
|
||||||
case 2:
|
|
||||||
return &v.unknownFields
|
|
||||||
default:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
file_auth_proto_msgTypes[0].OneofWrappers = []interface{}{}
|
|
||||||
file_auth_proto_msgTypes[1].OneofWrappers = []interface{}{}
|
|
||||||
file_auth_proto_msgTypes[2].OneofWrappers = []interface{}{}
|
|
||||||
type x struct{}
|
|
||||||
out := protoimpl.TypeBuilder{
|
|
||||||
File: protoimpl.DescBuilder{
|
|
||||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
|
||||||
RawDescriptor: file_auth_proto_rawDesc,
|
|
||||||
NumEnums: 0,
|
|
||||||
NumMessages: 3,
|
|
||||||
NumExtensions: 0,
|
|
||||||
NumServices: 1,
|
|
||||||
},
|
|
||||||
GoTypes: file_auth_proto_goTypes,
|
|
||||||
DependencyIndexes: file_auth_proto_depIdxs,
|
|
||||||
MessageInfos: file_auth_proto_msgTypes,
|
|
||||||
}.Build()
|
|
||||||
File_auth_proto = out.File
|
|
||||||
file_auth_proto_rawDesc = nil
|
|
||||||
file_auth_proto_goTypes = nil
|
|
||||||
file_auth_proto_depIdxs = nil
|
|
||||||
}
|
|
@ -1,31 +0,0 @@
|
|||||||
syntax = "proto3";
|
|
||||||
|
|
||||||
option go_package = ".;proto";
|
|
||||||
|
|
||||||
package proto;
|
|
||||||
|
|
||||||
service Auth {
|
|
||||||
rpc Authenticate(AuthRequest) returns (AuthReply) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
message Userinfo {
|
|
||||||
uint64 id = 1;
|
|
||||||
string name = 2;
|
|
||||||
string nick = 3;
|
|
||||||
string email = 4;
|
|
||||||
string avatar = 5;
|
|
||||||
string banner = 6;
|
|
||||||
optional string description = 7;
|
|
||||||
}
|
|
||||||
|
|
||||||
message AuthRequest {
|
|
||||||
string access_token = 1;
|
|
||||||
optional string refresh_token = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message AuthReply {
|
|
||||||
bool is_valid = 1;
|
|
||||||
optional string access_token = 2;
|
|
||||||
optional string refresh_token = 3;
|
|
||||||
optional Userinfo userinfo = 4;
|
|
||||||
}
|
|
@ -1,109 +0,0 @@
|
|||||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
|
||||||
// versions:
|
|
||||||
// - protoc-gen-go-grpc v1.3.0
|
|
||||||
// - protoc v4.25.3
|
|
||||||
// source: auth.proto
|
|
||||||
|
|
||||||
package proto
|
|
||||||
|
|
||||||
import (
|
|
||||||
context "context"
|
|
||||||
grpc "google.golang.org/grpc"
|
|
||||||
codes "google.golang.org/grpc/codes"
|
|
||||||
status "google.golang.org/grpc/status"
|
|
||||||
)
|
|
||||||
|
|
||||||
// This is a compile-time assertion to ensure that this generated file
|
|
||||||
// is compatible with the grpc package it is being compiled against.
|
|
||||||
// Requires gRPC-Go v1.32.0 or later.
|
|
||||||
const _ = grpc.SupportPackageIsVersion7
|
|
||||||
|
|
||||||
const (
|
|
||||||
Auth_Authenticate_FullMethodName = "/proto.Auth/Authenticate"
|
|
||||||
)
|
|
||||||
|
|
||||||
// AuthClient is the client API for Auth service.
|
|
||||||
//
|
|
||||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
|
||||||
type AuthClient interface {
|
|
||||||
Authenticate(ctx context.Context, in *AuthRequest, opts ...grpc.CallOption) (*AuthReply, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type authClient struct {
|
|
||||||
cc grpc.ClientConnInterface
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewAuthClient(cc grpc.ClientConnInterface) AuthClient {
|
|
||||||
return &authClient{cc}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *authClient) Authenticate(ctx context.Context, in *AuthRequest, opts ...grpc.CallOption) (*AuthReply, error) {
|
|
||||||
out := new(AuthReply)
|
|
||||||
err := c.cc.Invoke(ctx, Auth_Authenticate_FullMethodName, in, out, opts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// AuthServer is the server API for Auth service.
|
|
||||||
// All implementations must embed UnimplementedAuthServer
|
|
||||||
// for forward compatibility
|
|
||||||
type AuthServer interface {
|
|
||||||
Authenticate(context.Context, *AuthRequest) (*AuthReply, error)
|
|
||||||
mustEmbedUnimplementedAuthServer()
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnimplementedAuthServer must be embedded to have forward compatible implementations.
|
|
||||||
type UnimplementedAuthServer struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (UnimplementedAuthServer) Authenticate(context.Context, *AuthRequest) (*AuthReply, error) {
|
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method Authenticate not implemented")
|
|
||||||
}
|
|
||||||
func (UnimplementedAuthServer) mustEmbedUnimplementedAuthServer() {}
|
|
||||||
|
|
||||||
// UnsafeAuthServer may be embedded to opt out of forward compatibility for this service.
|
|
||||||
// Use of this interface is not recommended, as added methods to AuthServer will
|
|
||||||
// result in compilation errors.
|
|
||||||
type UnsafeAuthServer interface {
|
|
||||||
mustEmbedUnimplementedAuthServer()
|
|
||||||
}
|
|
||||||
|
|
||||||
func RegisterAuthServer(s grpc.ServiceRegistrar, srv AuthServer) {
|
|
||||||
s.RegisterService(&Auth_ServiceDesc, srv)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _Auth_Authenticate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(AuthRequest)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(AuthServer).Authenticate(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{
|
|
||||||
Server: srv,
|
|
||||||
FullMethod: Auth_Authenticate_FullMethodName,
|
|
||||||
}
|
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(AuthServer).Authenticate(ctx, req.(*AuthRequest))
|
|
||||||
}
|
|
||||||
return interceptor(ctx, in, info, handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Auth_ServiceDesc is the grpc.ServiceDesc for Auth service.
|
|
||||||
// It's only intended for direct use with grpc.RegisterService,
|
|
||||||
// and not to be introspected or modified (even as a copy)
|
|
||||||
var Auth_ServiceDesc = grpc.ServiceDesc{
|
|
||||||
ServiceName: "proto.Auth",
|
|
||||||
HandlerType: (*AuthServer)(nil),
|
|
||||||
Methods: []grpc.MethodDesc{
|
|
||||||
{
|
|
||||||
MethodName: "Authenticate",
|
|
||||||
Handler: _Auth_Authenticate_Handler,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Streams: []grpc.StreamDesc{},
|
|
||||||
Metadata: "auth.proto",
|
|
||||||
}
|
|
@ -1,400 +0,0 @@
|
|||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
|
||||||
// versions:
|
|
||||||
// protoc-gen-go v1.33.0
|
|
||||||
// protoc v5.26.1
|
|
||||||
// source: friendships.proto
|
|
||||||
|
|
||||||
package proto
|
|
||||||
|
|
||||||
import (
|
|
||||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
|
||||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
|
||||||
reflect "reflect"
|
|
||||||
sync "sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// Verify that this generated code is sufficiently up-to-date.
|
|
||||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
|
||||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
|
||||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
|
||||||
)
|
|
||||||
|
|
||||||
type FriendshipLookupRequest struct {
|
|
||||||
state protoimpl.MessageState
|
|
||||||
sizeCache protoimpl.SizeCache
|
|
||||||
unknownFields protoimpl.UnknownFields
|
|
||||||
|
|
||||||
AccountId uint64 `protobuf:"varint,1,opt,name=account_id,json=accountId,proto3" json:"account_id,omitempty"`
|
|
||||||
Status uint32 `protobuf:"varint,2,opt,name=status,proto3" json:"status,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *FriendshipLookupRequest) Reset() {
|
|
||||||
*x = FriendshipLookupRequest{}
|
|
||||||
if protoimpl.UnsafeEnabled {
|
|
||||||
mi := &file_friendships_proto_msgTypes[0]
|
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
||||||
ms.StoreMessageInfo(mi)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *FriendshipLookupRequest) String() string {
|
|
||||||
return protoimpl.X.MessageStringOf(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*FriendshipLookupRequest) ProtoMessage() {}
|
|
||||||
|
|
||||||
func (x *FriendshipLookupRequest) ProtoReflect() protoreflect.Message {
|
|
||||||
mi := &file_friendships_proto_msgTypes[0]
|
|
||||||
if protoimpl.UnsafeEnabled && x != nil {
|
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
||||||
if ms.LoadMessageInfo() == nil {
|
|
||||||
ms.StoreMessageInfo(mi)
|
|
||||||
}
|
|
||||||
return ms
|
|
||||||
}
|
|
||||||
return mi.MessageOf(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Use FriendshipLookupRequest.ProtoReflect.Descriptor instead.
|
|
||||||
func (*FriendshipLookupRequest) Descriptor() ([]byte, []int) {
|
|
||||||
return file_friendships_proto_rawDescGZIP(), []int{0}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *FriendshipLookupRequest) GetAccountId() uint64 {
|
|
||||||
if x != nil {
|
|
||||||
return x.AccountId
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *FriendshipLookupRequest) GetStatus() uint32 {
|
|
||||||
if x != nil {
|
|
||||||
return x.Status
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
type FriendshipTwoSideLookupRequest struct {
|
|
||||||
state protoimpl.MessageState
|
|
||||||
sizeCache protoimpl.SizeCache
|
|
||||||
unknownFields protoimpl.UnknownFields
|
|
||||||
|
|
||||||
AccountId uint64 `protobuf:"varint,1,opt,name=account_id,json=accountId,proto3" json:"account_id,omitempty"`
|
|
||||||
RelatedId uint64 `protobuf:"varint,2,opt,name=related_id,json=relatedId,proto3" json:"related_id,omitempty"`
|
|
||||||
Status uint32 `protobuf:"varint,3,opt,name=status,proto3" json:"status,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *FriendshipTwoSideLookupRequest) Reset() {
|
|
||||||
*x = FriendshipTwoSideLookupRequest{}
|
|
||||||
if protoimpl.UnsafeEnabled {
|
|
||||||
mi := &file_friendships_proto_msgTypes[1]
|
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
||||||
ms.StoreMessageInfo(mi)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *FriendshipTwoSideLookupRequest) String() string {
|
|
||||||
return protoimpl.X.MessageStringOf(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*FriendshipTwoSideLookupRequest) ProtoMessage() {}
|
|
||||||
|
|
||||||
func (x *FriendshipTwoSideLookupRequest) ProtoReflect() protoreflect.Message {
|
|
||||||
mi := &file_friendships_proto_msgTypes[1]
|
|
||||||
if protoimpl.UnsafeEnabled && x != nil {
|
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
||||||
if ms.LoadMessageInfo() == nil {
|
|
||||||
ms.StoreMessageInfo(mi)
|
|
||||||
}
|
|
||||||
return ms
|
|
||||||
}
|
|
||||||
return mi.MessageOf(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Use FriendshipTwoSideLookupRequest.ProtoReflect.Descriptor instead.
|
|
||||||
func (*FriendshipTwoSideLookupRequest) Descriptor() ([]byte, []int) {
|
|
||||||
return file_friendships_proto_rawDescGZIP(), []int{1}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *FriendshipTwoSideLookupRequest) GetAccountId() uint64 {
|
|
||||||
if x != nil {
|
|
||||||
return x.AccountId
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *FriendshipTwoSideLookupRequest) GetRelatedId() uint64 {
|
|
||||||
if x != nil {
|
|
||||||
return x.RelatedId
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *FriendshipTwoSideLookupRequest) GetStatus() uint32 {
|
|
||||||
if x != nil {
|
|
||||||
return x.Status
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
type ListFriendshipResponse struct {
|
|
||||||
state protoimpl.MessageState
|
|
||||||
sizeCache protoimpl.SizeCache
|
|
||||||
unknownFields protoimpl.UnknownFields
|
|
||||||
|
|
||||||
Data []*FriendshipResponse `protobuf:"bytes,1,rep,name=data,proto3" json:"data,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *ListFriendshipResponse) Reset() {
|
|
||||||
*x = ListFriendshipResponse{}
|
|
||||||
if protoimpl.UnsafeEnabled {
|
|
||||||
mi := &file_friendships_proto_msgTypes[2]
|
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
||||||
ms.StoreMessageInfo(mi)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *ListFriendshipResponse) String() string {
|
|
||||||
return protoimpl.X.MessageStringOf(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*ListFriendshipResponse) ProtoMessage() {}
|
|
||||||
|
|
||||||
func (x *ListFriendshipResponse) ProtoReflect() protoreflect.Message {
|
|
||||||
mi := &file_friendships_proto_msgTypes[2]
|
|
||||||
if protoimpl.UnsafeEnabled && x != nil {
|
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
||||||
if ms.LoadMessageInfo() == nil {
|
|
||||||
ms.StoreMessageInfo(mi)
|
|
||||||
}
|
|
||||||
return ms
|
|
||||||
}
|
|
||||||
return mi.MessageOf(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Use ListFriendshipResponse.ProtoReflect.Descriptor instead.
|
|
||||||
func (*ListFriendshipResponse) Descriptor() ([]byte, []int) {
|
|
||||||
return file_friendships_proto_rawDescGZIP(), []int{2}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *ListFriendshipResponse) GetData() []*FriendshipResponse {
|
|
||||||
if x != nil {
|
|
||||||
return x.Data
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type FriendshipResponse struct {
|
|
||||||
state protoimpl.MessageState
|
|
||||||
sizeCache protoimpl.SizeCache
|
|
||||||
unknownFields protoimpl.UnknownFields
|
|
||||||
|
|
||||||
AccountId uint64 `protobuf:"varint,1,opt,name=account_id,json=accountId,proto3" json:"account_id,omitempty"`
|
|
||||||
RelatedId uint64 `protobuf:"varint,2,opt,name=related_id,json=relatedId,proto3" json:"related_id,omitempty"`
|
|
||||||
Status uint32 `protobuf:"varint,3,opt,name=status,proto3" json:"status,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *FriendshipResponse) Reset() {
|
|
||||||
*x = FriendshipResponse{}
|
|
||||||
if protoimpl.UnsafeEnabled {
|
|
||||||
mi := &file_friendships_proto_msgTypes[3]
|
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
||||||
ms.StoreMessageInfo(mi)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *FriendshipResponse) String() string {
|
|
||||||
return protoimpl.X.MessageStringOf(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*FriendshipResponse) ProtoMessage() {}
|
|
||||||
|
|
||||||
func (x *FriendshipResponse) ProtoReflect() protoreflect.Message {
|
|
||||||
mi := &file_friendships_proto_msgTypes[3]
|
|
||||||
if protoimpl.UnsafeEnabled && x != nil {
|
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
||||||
if ms.LoadMessageInfo() == nil {
|
|
||||||
ms.StoreMessageInfo(mi)
|
|
||||||
}
|
|
||||||
return ms
|
|
||||||
}
|
|
||||||
return mi.MessageOf(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Use FriendshipResponse.ProtoReflect.Descriptor instead.
|
|
||||||
func (*FriendshipResponse) Descriptor() ([]byte, []int) {
|
|
||||||
return file_friendships_proto_rawDescGZIP(), []int{3}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *FriendshipResponse) GetAccountId() uint64 {
|
|
||||||
if x != nil {
|
|
||||||
return x.AccountId
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *FriendshipResponse) GetRelatedId() uint64 {
|
|
||||||
if x != nil {
|
|
||||||
return x.RelatedId
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *FriendshipResponse) GetStatus() uint32 {
|
|
||||||
if x != nil {
|
|
||||||
return x.Status
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
var File_friendships_proto protoreflect.FileDescriptor
|
|
||||||
|
|
||||||
var file_friendships_proto_rawDesc = []byte{
|
|
||||||
0x0a, 0x11, 0x66, 0x72, 0x69, 0x65, 0x6e, 0x64, 0x73, 0x68, 0x69, 0x70, 0x73, 0x2e, 0x70, 0x72,
|
|
||||||
0x6f, 0x74, 0x6f, 0x12, 0x05, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x50, 0x0a, 0x17, 0x46, 0x72,
|
|
||||||
0x69, 0x65, 0x6e, 0x64, 0x73, 0x68, 0x69, 0x70, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x52, 0x65,
|
|
||||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74,
|
|
||||||
0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x61, 0x63, 0x63, 0x6f, 0x75,
|
|
||||||
0x6e, 0x74, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02,
|
|
||||||
0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x76, 0x0a, 0x1e,
|
|
||||||
0x46, 0x72, 0x69, 0x65, 0x6e, 0x64, 0x73, 0x68, 0x69, 0x70, 0x54, 0x77, 0x6f, 0x53, 0x69, 0x64,
|
|
||||||
0x65, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d,
|
|
||||||
0x0a, 0x0a, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
|
|
||||||
0x28, 0x04, 0x52, 0x09, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a,
|
|
||||||
0x0a, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28,
|
|
||||||
0x04, 0x52, 0x09, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06,
|
|
||||||
0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x73, 0x74,
|
|
||||||
0x61, 0x74, 0x75, 0x73, 0x22, 0x47, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x72, 0x69, 0x65,
|
|
||||||
0x6e, 0x64, 0x73, 0x68, 0x69, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2d,
|
|
||||||
0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x70,
|
|
||||||
0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x46, 0x72, 0x69, 0x65, 0x6e, 0x64, 0x73, 0x68, 0x69, 0x70, 0x52,
|
|
||||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x6a, 0x0a,
|
|
||||||
0x12, 0x46, 0x72, 0x69, 0x65, 0x6e, 0x64, 0x73, 0x68, 0x69, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
|
||||||
0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69,
|
|
||||||
0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74,
|
|
||||||
0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x69, 0x64,
|
|
||||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x49,
|
|
||||||
0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28,
|
|
||||||
0x0d, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x32, 0xb5, 0x01, 0x0a, 0x0b, 0x46, 0x72,
|
|
||||||
0x69, 0x65, 0x6e, 0x64, 0x73, 0x68, 0x69, 0x70, 0x73, 0x12, 0x51, 0x0a, 0x0e, 0x4c, 0x69, 0x73,
|
|
||||||
0x74, 0x46, 0x72, 0x69, 0x65, 0x6e, 0x64, 0x73, 0x68, 0x69, 0x70, 0x12, 0x1e, 0x2e, 0x70, 0x72,
|
|
||||||
0x6f, 0x74, 0x6f, 0x2e, 0x46, 0x72, 0x69, 0x65, 0x6e, 0x64, 0x73, 0x68, 0x69, 0x70, 0x4c, 0x6f,
|
|
||||||
0x6f, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x70, 0x72,
|
|
||||||
0x6f, 0x74, 0x6f, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x72, 0x69, 0x65, 0x6e, 0x64, 0x73, 0x68,
|
|
||||||
0x69, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x53, 0x0a, 0x0d,
|
|
||||||
0x47, 0x65, 0x74, 0x46, 0x72, 0x69, 0x65, 0x6e, 0x64, 0x73, 0x68, 0x69, 0x70, 0x12, 0x25, 0x2e,
|
|
||||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x46, 0x72, 0x69, 0x65, 0x6e, 0x64, 0x73, 0x68, 0x69, 0x70,
|
|
||||||
0x54, 0x77, 0x6f, 0x53, 0x69, 0x64, 0x65, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x71,
|
|
||||||
0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x46, 0x72, 0x69,
|
|
||||||
0x65, 0x6e, 0x64, 0x73, 0x68, 0x69, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
|
|
||||||
0x00, 0x42, 0x09, 0x5a, 0x07, 0x2e, 0x3b, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72,
|
|
||||||
0x6f, 0x74, 0x6f, 0x33,
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
file_friendships_proto_rawDescOnce sync.Once
|
|
||||||
file_friendships_proto_rawDescData = file_friendships_proto_rawDesc
|
|
||||||
)
|
|
||||||
|
|
||||||
func file_friendships_proto_rawDescGZIP() []byte {
|
|
||||||
file_friendships_proto_rawDescOnce.Do(func() {
|
|
||||||
file_friendships_proto_rawDescData = protoimpl.X.CompressGZIP(file_friendships_proto_rawDescData)
|
|
||||||
})
|
|
||||||
return file_friendships_proto_rawDescData
|
|
||||||
}
|
|
||||||
|
|
||||||
var file_friendships_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
|
|
||||||
var file_friendships_proto_goTypes = []interface{}{
|
|
||||||
(*FriendshipLookupRequest)(nil), // 0: proto.FriendshipLookupRequest
|
|
||||||
(*FriendshipTwoSideLookupRequest)(nil), // 1: proto.FriendshipTwoSideLookupRequest
|
|
||||||
(*ListFriendshipResponse)(nil), // 2: proto.ListFriendshipResponse
|
|
||||||
(*FriendshipResponse)(nil), // 3: proto.FriendshipResponse
|
|
||||||
}
|
|
||||||
var file_friendships_proto_depIdxs = []int32{
|
|
||||||
3, // 0: proto.ListFriendshipResponse.data:type_name -> proto.FriendshipResponse
|
|
||||||
0, // 1: proto.Friendships.ListFriendship:input_type -> proto.FriendshipLookupRequest
|
|
||||||
1, // 2: proto.Friendships.GetFriendship:input_type -> proto.FriendshipTwoSideLookupRequest
|
|
||||||
2, // 3: proto.Friendships.ListFriendship:output_type -> proto.ListFriendshipResponse
|
|
||||||
3, // 4: proto.Friendships.GetFriendship:output_type -> proto.FriendshipResponse
|
|
||||||
3, // [3:5] is the sub-list for method output_type
|
|
||||||
1, // [1:3] is the sub-list for method input_type
|
|
||||||
1, // [1:1] is the sub-list for extension type_name
|
|
||||||
1, // [1:1] is the sub-list for extension extendee
|
|
||||||
0, // [0:1] is the sub-list for field type_name
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() { file_friendships_proto_init() }
|
|
||||||
func file_friendships_proto_init() {
|
|
||||||
if File_friendships_proto != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if !protoimpl.UnsafeEnabled {
|
|
||||||
file_friendships_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
|
||||||
switch v := v.(*FriendshipLookupRequest); i {
|
|
||||||
case 0:
|
|
||||||
return &v.state
|
|
||||||
case 1:
|
|
||||||
return &v.sizeCache
|
|
||||||
case 2:
|
|
||||||
return &v.unknownFields
|
|
||||||
default:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
file_friendships_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
|
||||||
switch v := v.(*FriendshipTwoSideLookupRequest); i {
|
|
||||||
case 0:
|
|
||||||
return &v.state
|
|
||||||
case 1:
|
|
||||||
return &v.sizeCache
|
|
||||||
case 2:
|
|
||||||
return &v.unknownFields
|
|
||||||
default:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
file_friendships_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
|
||||||
switch v := v.(*ListFriendshipResponse); i {
|
|
||||||
case 0:
|
|
||||||
return &v.state
|
|
||||||
case 1:
|
|
||||||
return &v.sizeCache
|
|
||||||
case 2:
|
|
||||||
return &v.unknownFields
|
|
||||||
default:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
file_friendships_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
|
|
||||||
switch v := v.(*FriendshipResponse); i {
|
|
||||||
case 0:
|
|
||||||
return &v.state
|
|
||||||
case 1:
|
|
||||||
return &v.sizeCache
|
|
||||||
case 2:
|
|
||||||
return &v.unknownFields
|
|
||||||
default:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
type x struct{}
|
|
||||||
out := protoimpl.TypeBuilder{
|
|
||||||
File: protoimpl.DescBuilder{
|
|
||||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
|
||||||
RawDescriptor: file_friendships_proto_rawDesc,
|
|
||||||
NumEnums: 0,
|
|
||||||
NumMessages: 4,
|
|
||||||
NumExtensions: 0,
|
|
||||||
NumServices: 1,
|
|
||||||
},
|
|
||||||
GoTypes: file_friendships_proto_goTypes,
|
|
||||||
DependencyIndexes: file_friendships_proto_depIdxs,
|
|
||||||
MessageInfos: file_friendships_proto_msgTypes,
|
|
||||||
}.Build()
|
|
||||||
File_friendships_proto = out.File
|
|
||||||
file_friendships_proto_rawDesc = nil
|
|
||||||
file_friendships_proto_goTypes = nil
|
|
||||||
file_friendships_proto_depIdxs = nil
|
|
||||||
}
|
|
@ -1,31 +0,0 @@
|
|||||||
syntax = "proto3";
|
|
||||||
|
|
||||||
option go_package = ".;proto";
|
|
||||||
|
|
||||||
package proto;
|
|
||||||
|
|
||||||
service Friendships {
|
|
||||||
rpc ListFriendship(FriendshipLookupRequest) returns (ListFriendshipResponse) {}
|
|
||||||
rpc GetFriendship(FriendshipTwoSideLookupRequest) returns (FriendshipResponse) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
message FriendshipLookupRequest {
|
|
||||||
uint64 account_id = 1;
|
|
||||||
uint32 status = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message FriendshipTwoSideLookupRequest {
|
|
||||||
uint64 account_id = 1;
|
|
||||||
uint64 related_id = 2;
|
|
||||||
uint32 status = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
message FriendshipResponse {
|
|
||||||
uint64 account_id = 1;
|
|
||||||
uint64 related_id = 2;
|
|
||||||
uint32 status = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
message ListFriendshipResponse {
|
|
||||||
repeated FriendshipResponse data = 1;
|
|
||||||
}
|
|
@ -1,146 +0,0 @@
|
|||||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
|
||||||
// versions:
|
|
||||||
// - protoc-gen-go-grpc v1.3.0
|
|
||||||
// - protoc v5.26.1
|
|
||||||
// source: friendships.proto
|
|
||||||
|
|
||||||
package proto
|
|
||||||
|
|
||||||
import (
|
|
||||||
context "context"
|
|
||||||
grpc "google.golang.org/grpc"
|
|
||||||
codes "google.golang.org/grpc/codes"
|
|
||||||
status "google.golang.org/grpc/status"
|
|
||||||
)
|
|
||||||
|
|
||||||
// This is a compile-time assertion to ensure that this generated file
|
|
||||||
// is compatible with the grpc package it is being compiled against.
|
|
||||||
// Requires gRPC-Go v1.32.0 or later.
|
|
||||||
const _ = grpc.SupportPackageIsVersion7
|
|
||||||
|
|
||||||
const (
|
|
||||||
Friendships_ListFriendship_FullMethodName = "/proto.Friendships/ListFriendship"
|
|
||||||
Friendships_GetFriendship_FullMethodName = "/proto.Friendships/GetFriendship"
|
|
||||||
)
|
|
||||||
|
|
||||||
// FriendshipsClient is the client API for Friendships service.
|
|
||||||
//
|
|
||||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
|
||||||
type FriendshipsClient interface {
|
|
||||||
ListFriendship(ctx context.Context, in *FriendshipLookupRequest, opts ...grpc.CallOption) (*ListFriendshipResponse, error)
|
|
||||||
GetFriendship(ctx context.Context, in *FriendshipTwoSideLookupRequest, opts ...grpc.CallOption) (*FriendshipResponse, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type friendshipsClient struct {
|
|
||||||
cc grpc.ClientConnInterface
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewFriendshipsClient(cc grpc.ClientConnInterface) FriendshipsClient {
|
|
||||||
return &friendshipsClient{cc}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *friendshipsClient) ListFriendship(ctx context.Context, in *FriendshipLookupRequest, opts ...grpc.CallOption) (*ListFriendshipResponse, error) {
|
|
||||||
out := new(ListFriendshipResponse)
|
|
||||||
err := c.cc.Invoke(ctx, Friendships_ListFriendship_FullMethodName, in, out, opts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *friendshipsClient) GetFriendship(ctx context.Context, in *FriendshipTwoSideLookupRequest, opts ...grpc.CallOption) (*FriendshipResponse, error) {
|
|
||||||
out := new(FriendshipResponse)
|
|
||||||
err := c.cc.Invoke(ctx, Friendships_GetFriendship_FullMethodName, in, out, opts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// FriendshipsServer is the server API for Friendships service.
|
|
||||||
// All implementations must embed UnimplementedFriendshipsServer
|
|
||||||
// for forward compatibility
|
|
||||||
type FriendshipsServer interface {
|
|
||||||
ListFriendship(context.Context, *FriendshipLookupRequest) (*ListFriendshipResponse, error)
|
|
||||||
GetFriendship(context.Context, *FriendshipTwoSideLookupRequest) (*FriendshipResponse, error)
|
|
||||||
mustEmbedUnimplementedFriendshipsServer()
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnimplementedFriendshipsServer must be embedded to have forward compatible implementations.
|
|
||||||
type UnimplementedFriendshipsServer struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (UnimplementedFriendshipsServer) ListFriendship(context.Context, *FriendshipLookupRequest) (*ListFriendshipResponse, error) {
|
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method ListFriendship not implemented")
|
|
||||||
}
|
|
||||||
func (UnimplementedFriendshipsServer) GetFriendship(context.Context, *FriendshipTwoSideLookupRequest) (*FriendshipResponse, error) {
|
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method GetFriendship not implemented")
|
|
||||||
}
|
|
||||||
func (UnimplementedFriendshipsServer) mustEmbedUnimplementedFriendshipsServer() {}
|
|
||||||
|
|
||||||
// UnsafeFriendshipsServer may be embedded to opt out of forward compatibility for this service.
|
|
||||||
// Use of this interface is not recommended, as added methods to FriendshipsServer will
|
|
||||||
// result in compilation errors.
|
|
||||||
type UnsafeFriendshipsServer interface {
|
|
||||||
mustEmbedUnimplementedFriendshipsServer()
|
|
||||||
}
|
|
||||||
|
|
||||||
func RegisterFriendshipsServer(s grpc.ServiceRegistrar, srv FriendshipsServer) {
|
|
||||||
s.RegisterService(&Friendships_ServiceDesc, srv)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _Friendships_ListFriendship_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(FriendshipLookupRequest)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(FriendshipsServer).ListFriendship(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{
|
|
||||||
Server: srv,
|
|
||||||
FullMethod: Friendships_ListFriendship_FullMethodName,
|
|
||||||
}
|
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(FriendshipsServer).ListFriendship(ctx, req.(*FriendshipLookupRequest))
|
|
||||||
}
|
|
||||||
return interceptor(ctx, in, info, handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _Friendships_GetFriendship_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(FriendshipTwoSideLookupRequest)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(FriendshipsServer).GetFriendship(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{
|
|
||||||
Server: srv,
|
|
||||||
FullMethod: Friendships_GetFriendship_FullMethodName,
|
|
||||||
}
|
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(FriendshipsServer).GetFriendship(ctx, req.(*FriendshipTwoSideLookupRequest))
|
|
||||||
}
|
|
||||||
return interceptor(ctx, in, info, handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Friendships_ServiceDesc is the grpc.ServiceDesc for Friendships service.
|
|
||||||
// It's only intended for direct use with grpc.RegisterService,
|
|
||||||
// and not to be introspected or modified (even as a copy)
|
|
||||||
var Friendships_ServiceDesc = grpc.ServiceDesc{
|
|
||||||
ServiceName: "proto.Friendships",
|
|
||||||
HandlerType: (*FriendshipsServer)(nil),
|
|
||||||
Methods: []grpc.MethodDesc{
|
|
||||||
{
|
|
||||||
MethodName: "ListFriendship",
|
|
||||||
Handler: _Friendships_ListFriendship_Handler,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
MethodName: "GetFriendship",
|
|
||||||
Handler: _Friendships_GetFriendship_Handler,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Streams: []grpc.StreamDesc{},
|
|
||||||
Metadata: "friendships.proto",
|
|
||||||
}
|
|
@ -1,354 +0,0 @@
|
|||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
|
||||||
// versions:
|
|
||||||
// protoc-gen-go v1.33.0
|
|
||||||
// protoc v4.25.3
|
|
||||||
// source: notify.proto
|
|
||||||
|
|
||||||
package proto
|
|
||||||
|
|
||||||
import (
|
|
||||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
|
||||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
|
||||||
reflect "reflect"
|
|
||||||
sync "sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// Verify that this generated code is sufficiently up-to-date.
|
|
||||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
|
||||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
|
||||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
|
||||||
)
|
|
||||||
|
|
||||||
type NotifyLink struct {
|
|
||||||
state protoimpl.MessageState
|
|
||||||
sizeCache protoimpl.SizeCache
|
|
||||||
unknownFields protoimpl.UnknownFields
|
|
||||||
|
|
||||||
Label string `protobuf:"bytes,1,opt,name=label,proto3" json:"label,omitempty"`
|
|
||||||
Url string `protobuf:"bytes,2,opt,name=url,proto3" json:"url,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *NotifyLink) Reset() {
|
|
||||||
*x = NotifyLink{}
|
|
||||||
if protoimpl.UnsafeEnabled {
|
|
||||||
mi := &file_notify_proto_msgTypes[0]
|
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
||||||
ms.StoreMessageInfo(mi)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *NotifyLink) String() string {
|
|
||||||
return protoimpl.X.MessageStringOf(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*NotifyLink) ProtoMessage() {}
|
|
||||||
|
|
||||||
func (x *NotifyLink) ProtoReflect() protoreflect.Message {
|
|
||||||
mi := &file_notify_proto_msgTypes[0]
|
|
||||||
if protoimpl.UnsafeEnabled && x != nil {
|
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
||||||
if ms.LoadMessageInfo() == nil {
|
|
||||||
ms.StoreMessageInfo(mi)
|
|
||||||
}
|
|
||||||
return ms
|
|
||||||
}
|
|
||||||
return mi.MessageOf(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Use NotifyLink.ProtoReflect.Descriptor instead.
|
|
||||||
func (*NotifyLink) Descriptor() ([]byte, []int) {
|
|
||||||
return file_notify_proto_rawDescGZIP(), []int{0}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *NotifyLink) GetLabel() string {
|
|
||||||
if x != nil {
|
|
||||||
return x.Label
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *NotifyLink) GetUrl() string {
|
|
||||||
if x != nil {
|
|
||||||
return x.Url
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
type NotifyRequest struct {
|
|
||||||
state protoimpl.MessageState
|
|
||||||
sizeCache protoimpl.SizeCache
|
|
||||||
unknownFields protoimpl.UnknownFields
|
|
||||||
|
|
||||||
Subject string `protobuf:"bytes,1,opt,name=subject,proto3" json:"subject,omitempty"`
|
|
||||||
Content string `protobuf:"bytes,2,opt,name=content,proto3" json:"content,omitempty"`
|
|
||||||
Links []*NotifyLink `protobuf:"bytes,3,rep,name=links,proto3" json:"links,omitempty"`
|
|
||||||
IsImportant bool `protobuf:"varint,4,opt,name=is_important,json=isImportant,proto3" json:"is_important,omitempty"`
|
|
||||||
RecipientId uint64 `protobuf:"varint,5,opt,name=recipient_id,json=recipientId,proto3" json:"recipient_id,omitempty"`
|
|
||||||
ClientId string `protobuf:"bytes,6,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty"`
|
|
||||||
ClientSecret string `protobuf:"bytes,7,opt,name=client_secret,json=clientSecret,proto3" json:"client_secret,omitempty"`
|
|
||||||
IsRealtime bool `protobuf:"varint,8,opt,name=is_realtime,json=isRealtime,proto3" json:"is_realtime,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *NotifyRequest) Reset() {
|
|
||||||
*x = NotifyRequest{}
|
|
||||||
if protoimpl.UnsafeEnabled {
|
|
||||||
mi := &file_notify_proto_msgTypes[1]
|
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
||||||
ms.StoreMessageInfo(mi)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *NotifyRequest) String() string {
|
|
||||||
return protoimpl.X.MessageStringOf(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*NotifyRequest) ProtoMessage() {}
|
|
||||||
|
|
||||||
func (x *NotifyRequest) ProtoReflect() protoreflect.Message {
|
|
||||||
mi := &file_notify_proto_msgTypes[1]
|
|
||||||
if protoimpl.UnsafeEnabled && x != nil {
|
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
||||||
if ms.LoadMessageInfo() == nil {
|
|
||||||
ms.StoreMessageInfo(mi)
|
|
||||||
}
|
|
||||||
return ms
|
|
||||||
}
|
|
||||||
return mi.MessageOf(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Use NotifyRequest.ProtoReflect.Descriptor instead.
|
|
||||||
func (*NotifyRequest) Descriptor() ([]byte, []int) {
|
|
||||||
return file_notify_proto_rawDescGZIP(), []int{1}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *NotifyRequest) GetSubject() string {
|
|
||||||
if x != nil {
|
|
||||||
return x.Subject
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *NotifyRequest) GetContent() string {
|
|
||||||
if x != nil {
|
|
||||||
return x.Content
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *NotifyRequest) GetLinks() []*NotifyLink {
|
|
||||||
if x != nil {
|
|
||||||
return x.Links
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *NotifyRequest) GetIsImportant() bool {
|
|
||||||
if x != nil {
|
|
||||||
return x.IsImportant
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *NotifyRequest) GetRecipientId() uint64 {
|
|
||||||
if x != nil {
|
|
||||||
return x.RecipientId
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *NotifyRequest) GetClientId() string {
|
|
||||||
if x != nil {
|
|
||||||
return x.ClientId
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *NotifyRequest) GetClientSecret() string {
|
|
||||||
if x != nil {
|
|
||||||
return x.ClientSecret
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *NotifyRequest) GetIsRealtime() bool {
|
|
||||||
if x != nil {
|
|
||||||
return x.IsRealtime
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
type NotifyReply struct {
|
|
||||||
state protoimpl.MessageState
|
|
||||||
sizeCache protoimpl.SizeCache
|
|
||||||
unknownFields protoimpl.UnknownFields
|
|
||||||
|
|
||||||
IsSent bool `protobuf:"varint,1,opt,name=is_sent,json=isSent,proto3" json:"is_sent,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *NotifyReply) Reset() {
|
|
||||||
*x = NotifyReply{}
|
|
||||||
if protoimpl.UnsafeEnabled {
|
|
||||||
mi := &file_notify_proto_msgTypes[2]
|
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
||||||
ms.StoreMessageInfo(mi)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *NotifyReply) String() string {
|
|
||||||
return protoimpl.X.MessageStringOf(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*NotifyReply) ProtoMessage() {}
|
|
||||||
|
|
||||||
func (x *NotifyReply) ProtoReflect() protoreflect.Message {
|
|
||||||
mi := &file_notify_proto_msgTypes[2]
|
|
||||||
if protoimpl.UnsafeEnabled && x != nil {
|
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
||||||
if ms.LoadMessageInfo() == nil {
|
|
||||||
ms.StoreMessageInfo(mi)
|
|
||||||
}
|
|
||||||
return ms
|
|
||||||
}
|
|
||||||
return mi.MessageOf(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Use NotifyReply.ProtoReflect.Descriptor instead.
|
|
||||||
func (*NotifyReply) Descriptor() ([]byte, []int) {
|
|
||||||
return file_notify_proto_rawDescGZIP(), []int{2}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *NotifyReply) GetIsSent() bool {
|
|
||||||
if x != nil {
|
|
||||||
return x.IsSent
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
var File_notify_proto protoreflect.FileDescriptor
|
|
||||||
|
|
||||||
var file_notify_proto_rawDesc = []byte{
|
|
||||||
0x0a, 0x0c, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x05,
|
|
||||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x34, 0x0a, 0x0a, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x4c,
|
|
||||||
0x69, 0x6e, 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01,
|
|
||||||
0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c,
|
|
||||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x22, 0x95, 0x02, 0x0a, 0x0d,
|
|
||||||
0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a,
|
|
||||||
0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07,
|
|
||||||
0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65,
|
|
||||||
0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e,
|
|
||||||
0x74, 0x12, 0x27, 0x0a, 0x05, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b,
|
|
||||||
0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x4c,
|
|
||||||
0x69, 0x6e, 0x6b, 0x52, 0x05, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x73,
|
|
||||||
0x5f, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08,
|
|
||||||
0x52, 0x0b, 0x69, 0x73, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, 0x12, 0x21, 0x0a,
|
|
||||||
0x0c, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20,
|
|
||||||
0x01, 0x28, 0x04, 0x52, 0x0b, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64,
|
|
||||||
0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20,
|
|
||||||
0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x23, 0x0a,
|
|
||||||
0x0d, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x07,
|
|
||||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x63, 0x72,
|
|
||||||
0x65, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x73, 0x5f, 0x72, 0x65, 0x61, 0x6c, 0x74, 0x69, 0x6d,
|
|
||||||
0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x69, 0x73, 0x52, 0x65, 0x61, 0x6c, 0x74,
|
|
||||||
0x69, 0x6d, 0x65, 0x22, 0x26, 0x0a, 0x0b, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x52, 0x65, 0x70,
|
|
||||||
0x6c, 0x79, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x73, 0x5f, 0x73, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20,
|
|
||||||
0x01, 0x28, 0x08, 0x52, 0x06, 0x69, 0x73, 0x53, 0x65, 0x6e, 0x74, 0x32, 0x42, 0x0a, 0x06, 0x4e,
|
|
||||||
0x6f, 0x74, 0x69, 0x66, 0x79, 0x12, 0x38, 0x0a, 0x0a, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x55,
|
|
||||||
0x73, 0x65, 0x72, 0x12, 0x14, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4e, 0x6f, 0x74, 0x69,
|
|
||||||
0x66, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
|
||||||
0x6f, 0x2e, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x42,
|
|
||||||
0x09, 0x5a, 0x07, 0x2e, 0x3b, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
|
|
||||||
0x6f, 0x33,
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
file_notify_proto_rawDescOnce sync.Once
|
|
||||||
file_notify_proto_rawDescData = file_notify_proto_rawDesc
|
|
||||||
)
|
|
||||||
|
|
||||||
func file_notify_proto_rawDescGZIP() []byte {
|
|
||||||
file_notify_proto_rawDescOnce.Do(func() {
|
|
||||||
file_notify_proto_rawDescData = protoimpl.X.CompressGZIP(file_notify_proto_rawDescData)
|
|
||||||
})
|
|
||||||
return file_notify_proto_rawDescData
|
|
||||||
}
|
|
||||||
|
|
||||||
var file_notify_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
|
|
||||||
var file_notify_proto_goTypes = []interface{}{
|
|
||||||
(*NotifyLink)(nil), // 0: proto.NotifyLink
|
|
||||||
(*NotifyRequest)(nil), // 1: proto.NotifyRequest
|
|
||||||
(*NotifyReply)(nil), // 2: proto.NotifyReply
|
|
||||||
}
|
|
||||||
var file_notify_proto_depIdxs = []int32{
|
|
||||||
0, // 0: proto.NotifyRequest.links:type_name -> proto.NotifyLink
|
|
||||||
1, // 1: proto.Notify.NotifyUser:input_type -> proto.NotifyRequest
|
|
||||||
2, // 2: proto.Notify.NotifyUser:output_type -> proto.NotifyReply
|
|
||||||
2, // [2:3] is the sub-list for method output_type
|
|
||||||
1, // [1:2] is the sub-list for method input_type
|
|
||||||
1, // [1:1] is the sub-list for extension type_name
|
|
||||||
1, // [1:1] is the sub-list for extension extendee
|
|
||||||
0, // [0:1] is the sub-list for field type_name
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() { file_notify_proto_init() }
|
|
||||||
func file_notify_proto_init() {
|
|
||||||
if File_notify_proto != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if !protoimpl.UnsafeEnabled {
|
|
||||||
file_notify_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
|
||||||
switch v := v.(*NotifyLink); i {
|
|
||||||
case 0:
|
|
||||||
return &v.state
|
|
||||||
case 1:
|
|
||||||
return &v.sizeCache
|
|
||||||
case 2:
|
|
||||||
return &v.unknownFields
|
|
||||||
default:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
file_notify_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
|
||||||
switch v := v.(*NotifyRequest); i {
|
|
||||||
case 0:
|
|
||||||
return &v.state
|
|
||||||
case 1:
|
|
||||||
return &v.sizeCache
|
|
||||||
case 2:
|
|
||||||
return &v.unknownFields
|
|
||||||
default:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
file_notify_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
|
||||||
switch v := v.(*NotifyReply); i {
|
|
||||||
case 0:
|
|
||||||
return &v.state
|
|
||||||
case 1:
|
|
||||||
return &v.sizeCache
|
|
||||||
case 2:
|
|
||||||
return &v.unknownFields
|
|
||||||
default:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
type x struct{}
|
|
||||||
out := protoimpl.TypeBuilder{
|
|
||||||
File: protoimpl.DescBuilder{
|
|
||||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
|
||||||
RawDescriptor: file_notify_proto_rawDesc,
|
|
||||||
NumEnums: 0,
|
|
||||||
NumMessages: 3,
|
|
||||||
NumExtensions: 0,
|
|
||||||
NumServices: 1,
|
|
||||||
},
|
|
||||||
GoTypes: file_notify_proto_goTypes,
|
|
||||||
DependencyIndexes: file_notify_proto_depIdxs,
|
|
||||||
MessageInfos: file_notify_proto_msgTypes,
|
|
||||||
}.Build()
|
|
||||||
File_notify_proto = out.File
|
|
||||||
file_notify_proto_rawDesc = nil
|
|
||||||
file_notify_proto_goTypes = nil
|
|
||||||
file_notify_proto_depIdxs = nil
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
syntax = "proto3";
|
|
||||||
|
|
||||||
option go_package = ".;proto";
|
|
||||||
|
|
||||||
package proto;
|
|
||||||
|
|
||||||
service Notify {
|
|
||||||
rpc NotifyUser(NotifyRequest) returns (NotifyReply) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
message NotifyLink {
|
|
||||||
string label = 1;
|
|
||||||
string url = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message NotifyRequest {
|
|
||||||
string subject = 1;
|
|
||||||
string content = 2;
|
|
||||||
repeated NotifyLink links = 3;
|
|
||||||
bool is_important = 4;
|
|
||||||
uint64 recipient_id = 5;
|
|
||||||
string client_id = 6;
|
|
||||||
string client_secret = 7;
|
|
||||||
bool is_realtime = 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
message NotifyReply {
|
|
||||||
bool is_sent = 1;
|
|
||||||
}
|
|
@ -1,109 +0,0 @@
|
|||||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
|
||||||
// versions:
|
|
||||||
// - protoc-gen-go-grpc v1.3.0
|
|
||||||
// - protoc v4.25.3
|
|
||||||
// source: notify.proto
|
|
||||||
|
|
||||||
package proto
|
|
||||||
|
|
||||||
import (
|
|
||||||
context "context"
|
|
||||||
grpc "google.golang.org/grpc"
|
|
||||||
codes "google.golang.org/grpc/codes"
|
|
||||||
status "google.golang.org/grpc/status"
|
|
||||||
)
|
|
||||||
|
|
||||||
// This is a compile-time assertion to ensure that this generated file
|
|
||||||
// is compatible with the grpc package it is being compiled against.
|
|
||||||
// Requires gRPC-Go v1.32.0 or later.
|
|
||||||
const _ = grpc.SupportPackageIsVersion7
|
|
||||||
|
|
||||||
const (
|
|
||||||
Notify_NotifyUser_FullMethodName = "/proto.Notify/NotifyUser"
|
|
||||||
)
|
|
||||||
|
|
||||||
// NotifyClient is the client API for Notify service.
|
|
||||||
//
|
|
||||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
|
||||||
type NotifyClient interface {
|
|
||||||
NotifyUser(ctx context.Context, in *NotifyRequest, opts ...grpc.CallOption) (*NotifyReply, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type notifyClient struct {
|
|
||||||
cc grpc.ClientConnInterface
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewNotifyClient(cc grpc.ClientConnInterface) NotifyClient {
|
|
||||||
return ¬ifyClient{cc}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *notifyClient) NotifyUser(ctx context.Context, in *NotifyRequest, opts ...grpc.CallOption) (*NotifyReply, error) {
|
|
||||||
out := new(NotifyReply)
|
|
||||||
err := c.cc.Invoke(ctx, Notify_NotifyUser_FullMethodName, in, out, opts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// NotifyServer is the server API for Notify service.
|
|
||||||
// All implementations must embed UnimplementedNotifyServer
|
|
||||||
// for forward compatibility
|
|
||||||
type NotifyServer interface {
|
|
||||||
NotifyUser(context.Context, *NotifyRequest) (*NotifyReply, error)
|
|
||||||
mustEmbedUnimplementedNotifyServer()
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnimplementedNotifyServer must be embedded to have forward compatible implementations.
|
|
||||||
type UnimplementedNotifyServer struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (UnimplementedNotifyServer) NotifyUser(context.Context, *NotifyRequest) (*NotifyReply, error) {
|
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method NotifyUser not implemented")
|
|
||||||
}
|
|
||||||
func (UnimplementedNotifyServer) mustEmbedUnimplementedNotifyServer() {}
|
|
||||||
|
|
||||||
// UnsafeNotifyServer may be embedded to opt out of forward compatibility for this service.
|
|
||||||
// Use of this interface is not recommended, as added methods to NotifyServer will
|
|
||||||
// result in compilation errors.
|
|
||||||
type UnsafeNotifyServer interface {
|
|
||||||
mustEmbedUnimplementedNotifyServer()
|
|
||||||
}
|
|
||||||
|
|
||||||
func RegisterNotifyServer(s grpc.ServiceRegistrar, srv NotifyServer) {
|
|
||||||
s.RegisterService(&Notify_ServiceDesc, srv)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _Notify_NotifyUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(NotifyRequest)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(NotifyServer).NotifyUser(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{
|
|
||||||
Server: srv,
|
|
||||||
FullMethod: Notify_NotifyUser_FullMethodName,
|
|
||||||
}
|
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(NotifyServer).NotifyUser(ctx, req.(*NotifyRequest))
|
|
||||||
}
|
|
||||||
return interceptor(ctx, in, info, handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Notify_ServiceDesc is the grpc.ServiceDesc for Notify service.
|
|
||||||
// It's only intended for direct use with grpc.RegisterService,
|
|
||||||
// and not to be introspected or modified (even as a copy)
|
|
||||||
var Notify_ServiceDesc = grpc.ServiceDesc{
|
|
||||||
ServiceName: "proto.Notify",
|
|
||||||
HandlerType: (*NotifyServer)(nil),
|
|
||||||
Methods: []grpc.MethodDesc{
|
|
||||||
{
|
|
||||||
MethodName: "NotifyUser",
|
|
||||||
Handler: _Notify_NotifyUser_Handler,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Streams: []grpc.StreamDesc{},
|
|
||||||
Metadata: "notify.proto",
|
|
||||||
}
|
|
@ -1,685 +0,0 @@
|
|||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
|
||||||
// versions:
|
|
||||||
// protoc-gen-go v1.33.0
|
|
||||||
// protoc v5.26.1
|
|
||||||
// source: realms.proto
|
|
||||||
|
|
||||||
package proto
|
|
||||||
|
|
||||||
import (
|
|
||||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
|
||||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
|
||||||
emptypb "google.golang.org/protobuf/types/known/emptypb"
|
|
||||||
reflect "reflect"
|
|
||||||
sync "sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// Verify that this generated code is sufficiently up-to-date.
|
|
||||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
|
||||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
|
||||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
|
||||||
)
|
|
||||||
|
|
||||||
type RealmLookupWithUserRequest struct {
|
|
||||||
state protoimpl.MessageState
|
|
||||||
sizeCache protoimpl.SizeCache
|
|
||||||
unknownFields protoimpl.UnknownFields
|
|
||||||
|
|
||||||
UserId uint64 `protobuf:"varint,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *RealmLookupWithUserRequest) Reset() {
|
|
||||||
*x = RealmLookupWithUserRequest{}
|
|
||||||
if protoimpl.UnsafeEnabled {
|
|
||||||
mi := &file_realms_proto_msgTypes[0]
|
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
||||||
ms.StoreMessageInfo(mi)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *RealmLookupWithUserRequest) String() string {
|
|
||||||
return protoimpl.X.MessageStringOf(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*RealmLookupWithUserRequest) ProtoMessage() {}
|
|
||||||
|
|
||||||
func (x *RealmLookupWithUserRequest) ProtoReflect() protoreflect.Message {
|
|
||||||
mi := &file_realms_proto_msgTypes[0]
|
|
||||||
if protoimpl.UnsafeEnabled && x != nil {
|
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
||||||
if ms.LoadMessageInfo() == nil {
|
|
||||||
ms.StoreMessageInfo(mi)
|
|
||||||
}
|
|
||||||
return ms
|
|
||||||
}
|
|
||||||
return mi.MessageOf(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Use RealmLookupWithUserRequest.ProtoReflect.Descriptor instead.
|
|
||||||
func (*RealmLookupWithUserRequest) Descriptor() ([]byte, []int) {
|
|
||||||
return file_realms_proto_rawDescGZIP(), []int{0}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *RealmLookupWithUserRequest) GetUserId() uint64 {
|
|
||||||
if x != nil {
|
|
||||||
return x.UserId
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
type RealmLookupRequest struct {
|
|
||||||
state protoimpl.MessageState
|
|
||||||
sizeCache protoimpl.SizeCache
|
|
||||||
unknownFields protoimpl.UnknownFields
|
|
||||||
|
|
||||||
Id *uint64 `protobuf:"varint,1,opt,name=id,proto3,oneof" json:"id,omitempty"`
|
|
||||||
Alias *string `protobuf:"bytes,2,opt,name=alias,proto3,oneof" json:"alias,omitempty"`
|
|
||||||
IsPublic *bool `protobuf:"varint,3,opt,name=is_public,json=isPublic,proto3,oneof" json:"is_public,omitempty"`
|
|
||||||
IsCommunity *bool `protobuf:"varint,4,opt,name=is_community,json=isCommunity,proto3,oneof" json:"is_community,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *RealmLookupRequest) Reset() {
|
|
||||||
*x = RealmLookupRequest{}
|
|
||||||
if protoimpl.UnsafeEnabled {
|
|
||||||
mi := &file_realms_proto_msgTypes[1]
|
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
||||||
ms.StoreMessageInfo(mi)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *RealmLookupRequest) String() string {
|
|
||||||
return protoimpl.X.MessageStringOf(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*RealmLookupRequest) ProtoMessage() {}
|
|
||||||
|
|
||||||
func (x *RealmLookupRequest) ProtoReflect() protoreflect.Message {
|
|
||||||
mi := &file_realms_proto_msgTypes[1]
|
|
||||||
if protoimpl.UnsafeEnabled && x != nil {
|
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
||||||
if ms.LoadMessageInfo() == nil {
|
|
||||||
ms.StoreMessageInfo(mi)
|
|
||||||
}
|
|
||||||
return ms
|
|
||||||
}
|
|
||||||
return mi.MessageOf(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Use RealmLookupRequest.ProtoReflect.Descriptor instead.
|
|
||||||
func (*RealmLookupRequest) Descriptor() ([]byte, []int) {
|
|
||||||
return file_realms_proto_rawDescGZIP(), []int{1}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *RealmLookupRequest) GetId() uint64 {
|
|
||||||
if x != nil && x.Id != nil {
|
|
||||||
return *x.Id
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *RealmLookupRequest) GetAlias() string {
|
|
||||||
if x != nil && x.Alias != nil {
|
|
||||||
return *x.Alias
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *RealmLookupRequest) GetIsPublic() bool {
|
|
||||||
if x != nil && x.IsPublic != nil {
|
|
||||||
return *x.IsPublic
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *RealmLookupRequest) GetIsCommunity() bool {
|
|
||||||
if x != nil && x.IsCommunity != nil {
|
|
||||||
return *x.IsCommunity
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
type RealmResponse struct {
|
|
||||||
state protoimpl.MessageState
|
|
||||||
sizeCache protoimpl.SizeCache
|
|
||||||
unknownFields protoimpl.UnknownFields
|
|
||||||
|
|
||||||
Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
|
|
||||||
Alias string `protobuf:"bytes,2,opt,name=alias,proto3" json:"alias,omitempty"`
|
|
||||||
Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"`
|
|
||||||
Description string `protobuf:"bytes,4,opt,name=description,proto3" json:"description,omitempty"`
|
|
||||||
IsPublic bool `protobuf:"varint,5,opt,name=is_public,json=isPublic,proto3" json:"is_public,omitempty"`
|
|
||||||
IsCommunity bool `protobuf:"varint,6,opt,name=is_community,json=isCommunity,proto3" json:"is_community,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *RealmResponse) Reset() {
|
|
||||||
*x = RealmResponse{}
|
|
||||||
if protoimpl.UnsafeEnabled {
|
|
||||||
mi := &file_realms_proto_msgTypes[2]
|
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
||||||
ms.StoreMessageInfo(mi)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *RealmResponse) String() string {
|
|
||||||
return protoimpl.X.MessageStringOf(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*RealmResponse) ProtoMessage() {}
|
|
||||||
|
|
||||||
func (x *RealmResponse) ProtoReflect() protoreflect.Message {
|
|
||||||
mi := &file_realms_proto_msgTypes[2]
|
|
||||||
if protoimpl.UnsafeEnabled && x != nil {
|
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
||||||
if ms.LoadMessageInfo() == nil {
|
|
||||||
ms.StoreMessageInfo(mi)
|
|
||||||
}
|
|
||||||
return ms
|
|
||||||
}
|
|
||||||
return mi.MessageOf(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Use RealmResponse.ProtoReflect.Descriptor instead.
|
|
||||||
func (*RealmResponse) Descriptor() ([]byte, []int) {
|
|
||||||
return file_realms_proto_rawDescGZIP(), []int{2}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *RealmResponse) GetId() uint64 {
|
|
||||||
if x != nil {
|
|
||||||
return x.Id
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *RealmResponse) GetAlias() string {
|
|
||||||
if x != nil {
|
|
||||||
return x.Alias
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *RealmResponse) GetName() string {
|
|
||||||
if x != nil {
|
|
||||||
return x.Name
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *RealmResponse) GetDescription() string {
|
|
||||||
if x != nil {
|
|
||||||
return x.Description
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *RealmResponse) GetIsPublic() bool {
|
|
||||||
if x != nil {
|
|
||||||
return x.IsPublic
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *RealmResponse) GetIsCommunity() bool {
|
|
||||||
if x != nil {
|
|
||||||
return x.IsCommunity
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
type ListRealmResponse struct {
|
|
||||||
state protoimpl.MessageState
|
|
||||||
sizeCache protoimpl.SizeCache
|
|
||||||
unknownFields protoimpl.UnknownFields
|
|
||||||
|
|
||||||
Data []*RealmResponse `protobuf:"bytes,1,rep,name=data,proto3" json:"data,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *ListRealmResponse) Reset() {
|
|
||||||
*x = ListRealmResponse{}
|
|
||||||
if protoimpl.UnsafeEnabled {
|
|
||||||
mi := &file_realms_proto_msgTypes[3]
|
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
||||||
ms.StoreMessageInfo(mi)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *ListRealmResponse) String() string {
|
|
||||||
return protoimpl.X.MessageStringOf(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*ListRealmResponse) ProtoMessage() {}
|
|
||||||
|
|
||||||
func (x *ListRealmResponse) ProtoReflect() protoreflect.Message {
|
|
||||||
mi := &file_realms_proto_msgTypes[3]
|
|
||||||
if protoimpl.UnsafeEnabled && x != nil {
|
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
||||||
if ms.LoadMessageInfo() == nil {
|
|
||||||
ms.StoreMessageInfo(mi)
|
|
||||||
}
|
|
||||||
return ms
|
|
||||||
}
|
|
||||||
return mi.MessageOf(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Use ListRealmResponse.ProtoReflect.Descriptor instead.
|
|
||||||
func (*ListRealmResponse) Descriptor() ([]byte, []int) {
|
|
||||||
return file_realms_proto_rawDescGZIP(), []int{3}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *ListRealmResponse) GetData() []*RealmResponse {
|
|
||||||
if x != nil {
|
|
||||||
return x.Data
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type RealmMemberLookupRequest struct {
|
|
||||||
state protoimpl.MessageState
|
|
||||||
sizeCache protoimpl.SizeCache
|
|
||||||
unknownFields protoimpl.UnknownFields
|
|
||||||
|
|
||||||
RealmId uint64 `protobuf:"varint,1,opt,name=realm_id,json=realmId,proto3" json:"realm_id,omitempty"`
|
|
||||||
UserId *uint64 `protobuf:"varint,2,opt,name=user_id,json=userId,proto3,oneof" json:"user_id,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *RealmMemberLookupRequest) Reset() {
|
|
||||||
*x = RealmMemberLookupRequest{}
|
|
||||||
if protoimpl.UnsafeEnabled {
|
|
||||||
mi := &file_realms_proto_msgTypes[4]
|
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
||||||
ms.StoreMessageInfo(mi)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *RealmMemberLookupRequest) String() string {
|
|
||||||
return protoimpl.X.MessageStringOf(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*RealmMemberLookupRequest) ProtoMessage() {}
|
|
||||||
|
|
||||||
func (x *RealmMemberLookupRequest) ProtoReflect() protoreflect.Message {
|
|
||||||
mi := &file_realms_proto_msgTypes[4]
|
|
||||||
if protoimpl.UnsafeEnabled && x != nil {
|
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
||||||
if ms.LoadMessageInfo() == nil {
|
|
||||||
ms.StoreMessageInfo(mi)
|
|
||||||
}
|
|
||||||
return ms
|
|
||||||
}
|
|
||||||
return mi.MessageOf(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Use RealmMemberLookupRequest.ProtoReflect.Descriptor instead.
|
|
||||||
func (*RealmMemberLookupRequest) Descriptor() ([]byte, []int) {
|
|
||||||
return file_realms_proto_rawDescGZIP(), []int{4}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *RealmMemberLookupRequest) GetRealmId() uint64 {
|
|
||||||
if x != nil {
|
|
||||||
return x.RealmId
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *RealmMemberLookupRequest) GetUserId() uint64 {
|
|
||||||
if x != nil && x.UserId != nil {
|
|
||||||
return *x.UserId
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
type RealmMemberResponse struct {
|
|
||||||
state protoimpl.MessageState
|
|
||||||
sizeCache protoimpl.SizeCache
|
|
||||||
unknownFields protoimpl.UnknownFields
|
|
||||||
|
|
||||||
RealmId uint64 `protobuf:"varint,1,opt,name=realm_id,json=realmId,proto3" json:"realm_id,omitempty"`
|
|
||||||
UserId uint64 `protobuf:"varint,2,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"`
|
|
||||||
PowerLevel int32 `protobuf:"varint,3,opt,name=power_level,json=powerLevel,proto3" json:"power_level,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *RealmMemberResponse) Reset() {
|
|
||||||
*x = RealmMemberResponse{}
|
|
||||||
if protoimpl.UnsafeEnabled {
|
|
||||||
mi := &file_realms_proto_msgTypes[5]
|
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
||||||
ms.StoreMessageInfo(mi)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *RealmMemberResponse) String() string {
|
|
||||||
return protoimpl.X.MessageStringOf(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*RealmMemberResponse) ProtoMessage() {}
|
|
||||||
|
|
||||||
func (x *RealmMemberResponse) ProtoReflect() protoreflect.Message {
|
|
||||||
mi := &file_realms_proto_msgTypes[5]
|
|
||||||
if protoimpl.UnsafeEnabled && x != nil {
|
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
||||||
if ms.LoadMessageInfo() == nil {
|
|
||||||
ms.StoreMessageInfo(mi)
|
|
||||||
}
|
|
||||||
return ms
|
|
||||||
}
|
|
||||||
return mi.MessageOf(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Use RealmMemberResponse.ProtoReflect.Descriptor instead.
|
|
||||||
func (*RealmMemberResponse) Descriptor() ([]byte, []int) {
|
|
||||||
return file_realms_proto_rawDescGZIP(), []int{5}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *RealmMemberResponse) GetRealmId() uint64 {
|
|
||||||
if x != nil {
|
|
||||||
return x.RealmId
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *RealmMemberResponse) GetUserId() uint64 {
|
|
||||||
if x != nil {
|
|
||||||
return x.UserId
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *RealmMemberResponse) GetPowerLevel() int32 {
|
|
||||||
if x != nil {
|
|
||||||
return x.PowerLevel
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
type ListRealmMemberResponse struct {
|
|
||||||
state protoimpl.MessageState
|
|
||||||
sizeCache protoimpl.SizeCache
|
|
||||||
unknownFields protoimpl.UnknownFields
|
|
||||||
|
|
||||||
Data []*RealmMemberResponse `protobuf:"bytes,1,rep,name=data,proto3" json:"data,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *ListRealmMemberResponse) Reset() {
|
|
||||||
*x = ListRealmMemberResponse{}
|
|
||||||
if protoimpl.UnsafeEnabled {
|
|
||||||
mi := &file_realms_proto_msgTypes[6]
|
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
||||||
ms.StoreMessageInfo(mi)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *ListRealmMemberResponse) String() string {
|
|
||||||
return protoimpl.X.MessageStringOf(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*ListRealmMemberResponse) ProtoMessage() {}
|
|
||||||
|
|
||||||
func (x *ListRealmMemberResponse) ProtoReflect() protoreflect.Message {
|
|
||||||
mi := &file_realms_proto_msgTypes[6]
|
|
||||||
if protoimpl.UnsafeEnabled && x != nil {
|
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
|
||||||
if ms.LoadMessageInfo() == nil {
|
|
||||||
ms.StoreMessageInfo(mi)
|
|
||||||
}
|
|
||||||
return ms
|
|
||||||
}
|
|
||||||
return mi.MessageOf(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Use ListRealmMemberResponse.ProtoReflect.Descriptor instead.
|
|
||||||
func (*ListRealmMemberResponse) Descriptor() ([]byte, []int) {
|
|
||||||
return file_realms_proto_rawDescGZIP(), []int{6}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *ListRealmMemberResponse) GetData() []*RealmMemberResponse {
|
|
||||||
if x != nil {
|
|
||||||
return x.Data
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var File_realms_proto protoreflect.FileDescriptor
|
|
||||||
|
|
||||||
var file_realms_proto_rawDesc = []byte{
|
|
||||||
0x0a, 0x0c, 0x72, 0x65, 0x61, 0x6c, 0x6d, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x05,
|
|
||||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72,
|
|
||||||
0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f,
|
|
||||||
0x74, 0x6f, 0x22, 0x35, 0x0a, 0x1a, 0x52, 0x65, 0x61, 0x6c, 0x6d, 0x4c, 0x6f, 0x6f, 0x6b, 0x75,
|
|
||||||
0x70, 0x57, 0x69, 0x74, 0x68, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
|
||||||
0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
|
|
||||||
0x04, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x22, 0xbe, 0x01, 0x0a, 0x12, 0x52, 0x65,
|
|
||||||
0x61, 0x6c, 0x6d, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
|
||||||
0x12, 0x13, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x48, 0x00, 0x52, 0x02,
|
|
||||||
0x69, 0x64, 0x88, 0x01, 0x01, 0x12, 0x19, 0x0a, 0x05, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x02,
|
|
||||||
0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x05, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x88, 0x01, 0x01,
|
|
||||||
0x12, 0x20, 0x0a, 0x09, 0x69, 0x73, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x18, 0x03, 0x20,
|
|
||||||
0x01, 0x28, 0x08, 0x48, 0x02, 0x52, 0x08, 0x69, 0x73, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x88,
|
|
||||||
0x01, 0x01, 0x12, 0x26, 0x0a, 0x0c, 0x69, 0x73, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69,
|
|
||||||
0x74, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x48, 0x03, 0x52, 0x0b, 0x69, 0x73, 0x43, 0x6f,
|
|
||||||
0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x88, 0x01, 0x01, 0x42, 0x05, 0x0a, 0x03, 0x5f, 0x69,
|
|
||||||
0x64, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x42, 0x0c, 0x0a, 0x0a, 0x5f,
|
|
||||||
0x69, 0x73, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x42, 0x0f, 0x0a, 0x0d, 0x5f, 0x69, 0x73,
|
|
||||||
0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x22, 0xab, 0x01, 0x0a, 0x0d, 0x52,
|
|
||||||
0x65, 0x61, 0x6c, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02,
|
|
||||||
0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05,
|
|
||||||
0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x6c, 0x69,
|
|
||||||
0x61, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
|
|
||||||
0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69,
|
|
||||||
0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73,
|
|
||||||
0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x69, 0x73, 0x5f, 0x70,
|
|
||||||
0x75, 0x62, 0x6c, 0x69, 0x63, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x69, 0x73, 0x50,
|
|
||||||
0x75, 0x62, 0x6c, 0x69, 0x63, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x73, 0x5f, 0x63, 0x6f, 0x6d, 0x6d,
|
|
||||||
0x75, 0x6e, 0x69, 0x74, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x73, 0x43,
|
|
||||||
0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x22, 0x3d, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74,
|
|
||||||
0x52, 0x65, 0x61, 0x6c, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x28, 0x0a,
|
|
||||||
0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x70, 0x72,
|
|
||||||
0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x61, 0x6c, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
|
||||||
0x65, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x5f, 0x0a, 0x18, 0x52, 0x65, 0x61, 0x6c, 0x6d,
|
|
||||||
0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75,
|
|
||||||
0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x65, 0x61, 0x6c, 0x6d, 0x5f, 0x69, 0x64, 0x18,
|
|
||||||
0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x72, 0x65, 0x61, 0x6c, 0x6d, 0x49, 0x64, 0x12, 0x1c,
|
|
||||||
0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x48,
|
|
||||||
0x00, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x88, 0x01, 0x01, 0x42, 0x0a, 0x0a, 0x08,
|
|
||||||
0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x22, 0x6a, 0x0a, 0x13, 0x52, 0x65, 0x61, 0x6c,
|
|
||||||
0x6d, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
|
|
||||||
0x19, 0x0a, 0x08, 0x72, 0x65, 0x61, 0x6c, 0x6d, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
|
|
||||||
0x04, 0x52, 0x07, 0x72, 0x65, 0x61, 0x6c, 0x6d, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73,
|
|
||||||
0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x75, 0x73, 0x65,
|
|
||||||
0x72, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x6f, 0x77, 0x65, 0x72, 0x5f, 0x6c, 0x65, 0x76,
|
|
||||||
0x65, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x70, 0x6f, 0x77, 0x65, 0x72, 0x4c,
|
|
||||||
0x65, 0x76, 0x65, 0x6c, 0x22, 0x49, 0x0a, 0x17, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x61, 0x6c,
|
|
||||||
0x6d, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
|
|
||||||
0x2e, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e,
|
|
||||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x61, 0x6c, 0x6d, 0x4d, 0x65, 0x6d, 0x62, 0x65,
|
|
||||||
0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x32,
|
|
||||||
0xde, 0x03, 0x0a, 0x06, 0x52, 0x65, 0x61, 0x6c, 0x6d, 0x73, 0x12, 0x48, 0x0a, 0x12, 0x4c, 0x69,
|
|
||||||
0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x52, 0x65, 0x61, 0x6c, 0x6d,
|
|
||||||
0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
|
|
||||||
0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
|
||||||
0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x61, 0x6c, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
|
||||||
0x73, 0x65, 0x22, 0x00, 0x12, 0x53, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x76, 0x61, 0x69,
|
|
||||||
0x6c, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x61, 0x6c, 0x6d, 0x12, 0x21, 0x2e, 0x70, 0x72, 0x6f,
|
|
||||||
0x74, 0x6f, 0x2e, 0x52, 0x65, 0x61, 0x6c, 0x6d, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x57, 0x69,
|
|
||||||
0x74, 0x68, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e,
|
|
||||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x61, 0x6c, 0x6d, 0x52,
|
|
||||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4f, 0x0a, 0x0e, 0x4c, 0x69, 0x73,
|
|
||||||
0x74, 0x4f, 0x77, 0x6e, 0x65, 0x64, 0x52, 0x65, 0x61, 0x6c, 0x6d, 0x12, 0x21, 0x2e, 0x70, 0x72,
|
|
||||||
0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x61, 0x6c, 0x6d, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x57,
|
|
||||||
0x69, 0x74, 0x68, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18,
|
|
||||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x61, 0x6c, 0x6d,
|
|
||||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3d, 0x0a, 0x08, 0x47, 0x65,
|
|
||||||
0x74, 0x52, 0x65, 0x61, 0x6c, 0x6d, 0x12, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52,
|
|
||||||
0x65, 0x61, 0x6c, 0x6d, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
|
||||||
0x74, 0x1a, 0x14, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x61, 0x6c, 0x6d, 0x52,
|
|
||||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x54, 0x0a, 0x0f, 0x4c, 0x69, 0x73,
|
|
||||||
0x74, 0x52, 0x65, 0x61, 0x6c, 0x6d, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x1f, 0x2e, 0x70,
|
|
||||||
0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x61, 0x6c, 0x6d, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72,
|
|
||||||
0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e,
|
|
||||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x61, 0x6c, 0x6d, 0x4d,
|
|
||||||
0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12,
|
|
||||||
0x4f, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x61, 0x6c, 0x6d, 0x4d, 0x65, 0x6d, 0x62, 0x65,
|
|
||||||
0x72, 0x12, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x61, 0x6c, 0x6d, 0x4d,
|
|
||||||
0x65, 0x6d, 0x62, 0x65, 0x72, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65,
|
|
||||||
0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x61, 0x6c, 0x6d,
|
|
||||||
0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00,
|
|
||||||
0x42, 0x09, 0x5a, 0x07, 0x2e, 0x3b, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f,
|
|
||||||
0x74, 0x6f, 0x33,
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
file_realms_proto_rawDescOnce sync.Once
|
|
||||||
file_realms_proto_rawDescData = file_realms_proto_rawDesc
|
|
||||||
)
|
|
||||||
|
|
||||||
func file_realms_proto_rawDescGZIP() []byte {
|
|
||||||
file_realms_proto_rawDescOnce.Do(func() {
|
|
||||||
file_realms_proto_rawDescData = protoimpl.X.CompressGZIP(file_realms_proto_rawDescData)
|
|
||||||
})
|
|
||||||
return file_realms_proto_rawDescData
|
|
||||||
}
|
|
||||||
|
|
||||||
var file_realms_proto_msgTypes = make([]protoimpl.MessageInfo, 7)
|
|
||||||
var file_realms_proto_goTypes = []interface{}{
|
|
||||||
(*RealmLookupWithUserRequest)(nil), // 0: proto.RealmLookupWithUserRequest
|
|
||||||
(*RealmLookupRequest)(nil), // 1: proto.RealmLookupRequest
|
|
||||||
(*RealmResponse)(nil), // 2: proto.RealmResponse
|
|
||||||
(*ListRealmResponse)(nil), // 3: proto.ListRealmResponse
|
|
||||||
(*RealmMemberLookupRequest)(nil), // 4: proto.RealmMemberLookupRequest
|
|
||||||
(*RealmMemberResponse)(nil), // 5: proto.RealmMemberResponse
|
|
||||||
(*ListRealmMemberResponse)(nil), // 6: proto.ListRealmMemberResponse
|
|
||||||
(*emptypb.Empty)(nil), // 7: google.protobuf.Empty
|
|
||||||
}
|
|
||||||
var file_realms_proto_depIdxs = []int32{
|
|
||||||
2, // 0: proto.ListRealmResponse.data:type_name -> proto.RealmResponse
|
|
||||||
5, // 1: proto.ListRealmMemberResponse.data:type_name -> proto.RealmMemberResponse
|
|
||||||
7, // 2: proto.Realms.ListCommunityRealm:input_type -> google.protobuf.Empty
|
|
||||||
0, // 3: proto.Realms.ListAvailableRealm:input_type -> proto.RealmLookupWithUserRequest
|
|
||||||
0, // 4: proto.Realms.ListOwnedRealm:input_type -> proto.RealmLookupWithUserRequest
|
|
||||||
1, // 5: proto.Realms.GetRealm:input_type -> proto.RealmLookupRequest
|
|
||||||
4, // 6: proto.Realms.ListRealmMember:input_type -> proto.RealmMemberLookupRequest
|
|
||||||
4, // 7: proto.Realms.GetRealmMember:input_type -> proto.RealmMemberLookupRequest
|
|
||||||
3, // 8: proto.Realms.ListCommunityRealm:output_type -> proto.ListRealmResponse
|
|
||||||
3, // 9: proto.Realms.ListAvailableRealm:output_type -> proto.ListRealmResponse
|
|
||||||
3, // 10: proto.Realms.ListOwnedRealm:output_type -> proto.ListRealmResponse
|
|
||||||
2, // 11: proto.Realms.GetRealm:output_type -> proto.RealmResponse
|
|
||||||
6, // 12: proto.Realms.ListRealmMember:output_type -> proto.ListRealmMemberResponse
|
|
||||||
5, // 13: proto.Realms.GetRealmMember:output_type -> proto.RealmMemberResponse
|
|
||||||
8, // [8:14] is the sub-list for method output_type
|
|
||||||
2, // [2:8] is the sub-list for method input_type
|
|
||||||
2, // [2:2] is the sub-list for extension type_name
|
|
||||||
2, // [2:2] is the sub-list for extension extendee
|
|
||||||
0, // [0:2] is the sub-list for field type_name
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() { file_realms_proto_init() }
|
|
||||||
func file_realms_proto_init() {
|
|
||||||
if File_realms_proto != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if !protoimpl.UnsafeEnabled {
|
|
||||||
file_realms_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
|
||||||
switch v := v.(*RealmLookupWithUserRequest); i {
|
|
||||||
case 0:
|
|
||||||
return &v.state
|
|
||||||
case 1:
|
|
||||||
return &v.sizeCache
|
|
||||||
case 2:
|
|
||||||
return &v.unknownFields
|
|
||||||
default:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
file_realms_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
|
||||||
switch v := v.(*RealmLookupRequest); i {
|
|
||||||
case 0:
|
|
||||||
return &v.state
|
|
||||||
case 1:
|
|
||||||
return &v.sizeCache
|
|
||||||
case 2:
|
|
||||||
return &v.unknownFields
|
|
||||||
default:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
file_realms_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
|
||||||
switch v := v.(*RealmResponse); i {
|
|
||||||
case 0:
|
|
||||||
return &v.state
|
|
||||||
case 1:
|
|
||||||
return &v.sizeCache
|
|
||||||
case 2:
|
|
||||||
return &v.unknownFields
|
|
||||||
default:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
file_realms_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
|
|
||||||
switch v := v.(*ListRealmResponse); i {
|
|
||||||
case 0:
|
|
||||||
return &v.state
|
|
||||||
case 1:
|
|
||||||
return &v.sizeCache
|
|
||||||
case 2:
|
|
||||||
return &v.unknownFields
|
|
||||||
default:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
file_realms_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
|
|
||||||
switch v := v.(*RealmMemberLookupRequest); i {
|
|
||||||
case 0:
|
|
||||||
return &v.state
|
|
||||||
case 1:
|
|
||||||
return &v.sizeCache
|
|
||||||
case 2:
|
|
||||||
return &v.unknownFields
|
|
||||||
default:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
file_realms_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
|
|
||||||
switch v := v.(*RealmMemberResponse); i {
|
|
||||||
case 0:
|
|
||||||
return &v.state
|
|
||||||
case 1:
|
|
||||||
return &v.sizeCache
|
|
||||||
case 2:
|
|
||||||
return &v.unknownFields
|
|
||||||
default:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
file_realms_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
|
|
||||||
switch v := v.(*ListRealmMemberResponse); i {
|
|
||||||
case 0:
|
|
||||||
return &v.state
|
|
||||||
case 1:
|
|
||||||
return &v.sizeCache
|
|
||||||
case 2:
|
|
||||||
return &v.unknownFields
|
|
||||||
default:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
file_realms_proto_msgTypes[1].OneofWrappers = []interface{}{}
|
|
||||||
file_realms_proto_msgTypes[4].OneofWrappers = []interface{}{}
|
|
||||||
type x struct{}
|
|
||||||
out := protoimpl.TypeBuilder{
|
|
||||||
File: protoimpl.DescBuilder{
|
|
||||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
|
||||||
RawDescriptor: file_realms_proto_rawDesc,
|
|
||||||
NumEnums: 0,
|
|
||||||
NumMessages: 7,
|
|
||||||
NumExtensions: 0,
|
|
||||||
NumServices: 1,
|
|
||||||
},
|
|
||||||
GoTypes: file_realms_proto_goTypes,
|
|
||||||
DependencyIndexes: file_realms_proto_depIdxs,
|
|
||||||
MessageInfos: file_realms_proto_msgTypes,
|
|
||||||
}.Build()
|
|
||||||
File_realms_proto = out.File
|
|
||||||
file_realms_proto_rawDesc = nil
|
|
||||||
file_realms_proto_goTypes = nil
|
|
||||||
file_realms_proto_depIdxs = nil
|
|
||||||
}
|
|
@ -1,55 +0,0 @@
|
|||||||
syntax = "proto3";
|
|
||||||
|
|
||||||
import "google/protobuf/empty.proto";
|
|
||||||
|
|
||||||
option go_package = ".;proto";
|
|
||||||
|
|
||||||
package proto;
|
|
||||||
|
|
||||||
service Realms {
|
|
||||||
rpc ListCommunityRealm(google.protobuf.Empty) returns (ListRealmResponse) {}
|
|
||||||
rpc ListAvailableRealm(RealmLookupWithUserRequest) returns (ListRealmResponse) {}
|
|
||||||
rpc ListOwnedRealm(RealmLookupWithUserRequest) returns (ListRealmResponse) {}
|
|
||||||
rpc GetRealm(RealmLookupRequest) returns (RealmResponse) {}
|
|
||||||
rpc ListRealmMember(RealmMemberLookupRequest) returns (ListRealmMemberResponse) {}
|
|
||||||
rpc GetRealmMember(RealmMemberLookupRequest) returns (RealmMemberResponse) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
message RealmLookupWithUserRequest {
|
|
||||||
uint64 user_id = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message RealmLookupRequest {
|
|
||||||
optional uint64 id = 1;
|
|
||||||
optional string alias = 2;
|
|
||||||
optional bool is_public = 3;
|
|
||||||
optional bool is_community = 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
message RealmResponse {
|
|
||||||
uint64 id = 1;
|
|
||||||
string alias = 2;
|
|
||||||
string name = 3;
|
|
||||||
string description = 4;
|
|
||||||
bool is_public = 5;
|
|
||||||
bool is_community = 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
message ListRealmResponse {
|
|
||||||
repeated RealmResponse data = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message RealmMemberLookupRequest {
|
|
||||||
uint64 realm_id = 1;
|
|
||||||
optional uint64 user_id = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message RealmMemberResponse {
|
|
||||||
uint64 realm_id = 1;
|
|
||||||
uint64 user_id = 2;
|
|
||||||
int32 power_level = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
message ListRealmMemberResponse {
|
|
||||||
repeated RealmMemberResponse data = 1;
|
|
||||||
}
|
|
@ -1,295 +0,0 @@
|
|||||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
|
||||||
// versions:
|
|
||||||
// - protoc-gen-go-grpc v1.3.0
|
|
||||||
// - protoc v5.26.1
|
|
||||||
// source: realms.proto
|
|
||||||
|
|
||||||
package proto
|
|
||||||
|
|
||||||
import (
|
|
||||||
context "context"
|
|
||||||
grpc "google.golang.org/grpc"
|
|
||||||
codes "google.golang.org/grpc/codes"
|
|
||||||
status "google.golang.org/grpc/status"
|
|
||||||
emptypb "google.golang.org/protobuf/types/known/emptypb"
|
|
||||||
)
|
|
||||||
|
|
||||||
// This is a compile-time assertion to ensure that this generated file
|
|
||||||
// is compatible with the grpc package it is being compiled against.
|
|
||||||
// Requires gRPC-Go v1.32.0 or later.
|
|
||||||
const _ = grpc.SupportPackageIsVersion7
|
|
||||||
|
|
||||||
const (
|
|
||||||
Realms_ListCommunityRealm_FullMethodName = "/proto.Realms/ListCommunityRealm"
|
|
||||||
Realms_ListAvailableRealm_FullMethodName = "/proto.Realms/ListAvailableRealm"
|
|
||||||
Realms_ListOwnedRealm_FullMethodName = "/proto.Realms/ListOwnedRealm"
|
|
||||||
Realms_GetRealm_FullMethodName = "/proto.Realms/GetRealm"
|
|
||||||
Realms_ListRealmMember_FullMethodName = "/proto.Realms/ListRealmMember"
|
|
||||||
Realms_GetRealmMember_FullMethodName = "/proto.Realms/GetRealmMember"
|
|
||||||
)
|
|
||||||
|
|
||||||
// RealmsClient is the client API for Realms service.
|
|
||||||
//
|
|
||||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
|
||||||
type RealmsClient interface {
|
|
||||||
ListCommunityRealm(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*ListRealmResponse, error)
|
|
||||||
ListAvailableRealm(ctx context.Context, in *RealmLookupWithUserRequest, opts ...grpc.CallOption) (*ListRealmResponse, error)
|
|
||||||
ListOwnedRealm(ctx context.Context, in *RealmLookupWithUserRequest, opts ...grpc.CallOption) (*ListRealmResponse, error)
|
|
||||||
GetRealm(ctx context.Context, in *RealmLookupRequest, opts ...grpc.CallOption) (*RealmResponse, error)
|
|
||||||
ListRealmMember(ctx context.Context, in *RealmMemberLookupRequest, opts ...grpc.CallOption) (*ListRealmMemberResponse, error)
|
|
||||||
GetRealmMember(ctx context.Context, in *RealmMemberLookupRequest, opts ...grpc.CallOption) (*RealmMemberResponse, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type realmsClient struct {
|
|
||||||
cc grpc.ClientConnInterface
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewRealmsClient(cc grpc.ClientConnInterface) RealmsClient {
|
|
||||||
return &realmsClient{cc}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *realmsClient) ListCommunityRealm(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*ListRealmResponse, error) {
|
|
||||||
out := new(ListRealmResponse)
|
|
||||||
err := c.cc.Invoke(ctx, Realms_ListCommunityRealm_FullMethodName, in, out, opts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *realmsClient) ListAvailableRealm(ctx context.Context, in *RealmLookupWithUserRequest, opts ...grpc.CallOption) (*ListRealmResponse, error) {
|
|
||||||
out := new(ListRealmResponse)
|
|
||||||
err := c.cc.Invoke(ctx, Realms_ListAvailableRealm_FullMethodName, in, out, opts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *realmsClient) ListOwnedRealm(ctx context.Context, in *RealmLookupWithUserRequest, opts ...grpc.CallOption) (*ListRealmResponse, error) {
|
|
||||||
out := new(ListRealmResponse)
|
|
||||||
err := c.cc.Invoke(ctx, Realms_ListOwnedRealm_FullMethodName, in, out, opts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *realmsClient) GetRealm(ctx context.Context, in *RealmLookupRequest, opts ...grpc.CallOption) (*RealmResponse, error) {
|
|
||||||
out := new(RealmResponse)
|
|
||||||
err := c.cc.Invoke(ctx, Realms_GetRealm_FullMethodName, in, out, opts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *realmsClient) ListRealmMember(ctx context.Context, in *RealmMemberLookupRequest, opts ...grpc.CallOption) (*ListRealmMemberResponse, error) {
|
|
||||||
out := new(ListRealmMemberResponse)
|
|
||||||
err := c.cc.Invoke(ctx, Realms_ListRealmMember_FullMethodName, in, out, opts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *realmsClient) GetRealmMember(ctx context.Context, in *RealmMemberLookupRequest, opts ...grpc.CallOption) (*RealmMemberResponse, error) {
|
|
||||||
out := new(RealmMemberResponse)
|
|
||||||
err := c.cc.Invoke(ctx, Realms_GetRealmMember_FullMethodName, in, out, opts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// RealmsServer is the server API for Realms service.
|
|
||||||
// All implementations must embed UnimplementedRealmsServer
|
|
||||||
// for forward compatibility
|
|
||||||
type RealmsServer interface {
|
|
||||||
ListCommunityRealm(context.Context, *emptypb.Empty) (*ListRealmResponse, error)
|
|
||||||
ListAvailableRealm(context.Context, *RealmLookupWithUserRequest) (*ListRealmResponse, error)
|
|
||||||
ListOwnedRealm(context.Context, *RealmLookupWithUserRequest) (*ListRealmResponse, error)
|
|
||||||
GetRealm(context.Context, *RealmLookupRequest) (*RealmResponse, error)
|
|
||||||
ListRealmMember(context.Context, *RealmMemberLookupRequest) (*ListRealmMemberResponse, error)
|
|
||||||
GetRealmMember(context.Context, *RealmMemberLookupRequest) (*RealmMemberResponse, error)
|
|
||||||
mustEmbedUnimplementedRealmsServer()
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnimplementedRealmsServer must be embedded to have forward compatible implementations.
|
|
||||||
type UnimplementedRealmsServer struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (UnimplementedRealmsServer) ListCommunityRealm(context.Context, *emptypb.Empty) (*ListRealmResponse, error) {
|
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method ListCommunityRealm not implemented")
|
|
||||||
}
|
|
||||||
func (UnimplementedRealmsServer) ListAvailableRealm(context.Context, *RealmLookupWithUserRequest) (*ListRealmResponse, error) {
|
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method ListAvailableRealm not implemented")
|
|
||||||
}
|
|
||||||
func (UnimplementedRealmsServer) ListOwnedRealm(context.Context, *RealmLookupWithUserRequest) (*ListRealmResponse, error) {
|
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method ListOwnedRealm not implemented")
|
|
||||||
}
|
|
||||||
func (UnimplementedRealmsServer) GetRealm(context.Context, *RealmLookupRequest) (*RealmResponse, error) {
|
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method GetRealm not implemented")
|
|
||||||
}
|
|
||||||
func (UnimplementedRealmsServer) ListRealmMember(context.Context, *RealmMemberLookupRequest) (*ListRealmMemberResponse, error) {
|
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method ListRealmMember not implemented")
|
|
||||||
}
|
|
||||||
func (UnimplementedRealmsServer) GetRealmMember(context.Context, *RealmMemberLookupRequest) (*RealmMemberResponse, error) {
|
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method GetRealmMember not implemented")
|
|
||||||
}
|
|
||||||
func (UnimplementedRealmsServer) mustEmbedUnimplementedRealmsServer() {}
|
|
||||||
|
|
||||||
// UnsafeRealmsServer may be embedded to opt out of forward compatibility for this service.
|
|
||||||
// Use of this interface is not recommended, as added methods to RealmsServer will
|
|
||||||
// result in compilation errors.
|
|
||||||
type UnsafeRealmsServer interface {
|
|
||||||
mustEmbedUnimplementedRealmsServer()
|
|
||||||
}
|
|
||||||
|
|
||||||
func RegisterRealmsServer(s grpc.ServiceRegistrar, srv RealmsServer) {
|
|
||||||
s.RegisterService(&Realms_ServiceDesc, srv)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _Realms_ListCommunityRealm_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(emptypb.Empty)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(RealmsServer).ListCommunityRealm(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{
|
|
||||||
Server: srv,
|
|
||||||
FullMethod: Realms_ListCommunityRealm_FullMethodName,
|
|
||||||
}
|
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(RealmsServer).ListCommunityRealm(ctx, req.(*emptypb.Empty))
|
|
||||||
}
|
|
||||||
return interceptor(ctx, in, info, handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _Realms_ListAvailableRealm_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(RealmLookupWithUserRequest)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(RealmsServer).ListAvailableRealm(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{
|
|
||||||
Server: srv,
|
|
||||||
FullMethod: Realms_ListAvailableRealm_FullMethodName,
|
|
||||||
}
|
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(RealmsServer).ListAvailableRealm(ctx, req.(*RealmLookupWithUserRequest))
|
|
||||||
}
|
|
||||||
return interceptor(ctx, in, info, handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _Realms_ListOwnedRealm_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(RealmLookupWithUserRequest)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(RealmsServer).ListOwnedRealm(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{
|
|
||||||
Server: srv,
|
|
||||||
FullMethod: Realms_ListOwnedRealm_FullMethodName,
|
|
||||||
}
|
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(RealmsServer).ListOwnedRealm(ctx, req.(*RealmLookupWithUserRequest))
|
|
||||||
}
|
|
||||||
return interceptor(ctx, in, info, handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _Realms_GetRealm_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(RealmLookupRequest)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(RealmsServer).GetRealm(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{
|
|
||||||
Server: srv,
|
|
||||||
FullMethod: Realms_GetRealm_FullMethodName,
|
|
||||||
}
|
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(RealmsServer).GetRealm(ctx, req.(*RealmLookupRequest))
|
|
||||||
}
|
|
||||||
return interceptor(ctx, in, info, handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _Realms_ListRealmMember_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(RealmMemberLookupRequest)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(RealmsServer).ListRealmMember(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{
|
|
||||||
Server: srv,
|
|
||||||
FullMethod: Realms_ListRealmMember_FullMethodName,
|
|
||||||
}
|
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(RealmsServer).ListRealmMember(ctx, req.(*RealmMemberLookupRequest))
|
|
||||||
}
|
|
||||||
return interceptor(ctx, in, info, handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _Realms_GetRealmMember_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(RealmMemberLookupRequest)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(RealmsServer).GetRealmMember(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{
|
|
||||||
Server: srv,
|
|
||||||
FullMethod: Realms_GetRealmMember_FullMethodName,
|
|
||||||
}
|
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(RealmsServer).GetRealmMember(ctx, req.(*RealmMemberLookupRequest))
|
|
||||||
}
|
|
||||||
return interceptor(ctx, in, info, handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Realms_ServiceDesc is the grpc.ServiceDesc for Realms service.
|
|
||||||
// It's only intended for direct use with grpc.RegisterService,
|
|
||||||
// and not to be introspected or modified (even as a copy)
|
|
||||||
var Realms_ServiceDesc = grpc.ServiceDesc{
|
|
||||||
ServiceName: "proto.Realms",
|
|
||||||
HandlerType: (*RealmsServer)(nil),
|
|
||||||
Methods: []grpc.MethodDesc{
|
|
||||||
{
|
|
||||||
MethodName: "ListCommunityRealm",
|
|
||||||
Handler: _Realms_ListCommunityRealm_Handler,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
MethodName: "ListAvailableRealm",
|
|
||||||
Handler: _Realms_ListAvailableRealm_Handler,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
MethodName: "ListOwnedRealm",
|
|
||||||
Handler: _Realms_ListOwnedRealm_Handler,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
MethodName: "GetRealm",
|
|
||||||
Handler: _Realms_GetRealm_Handler,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
MethodName: "ListRealmMember",
|
|
||||||
Handler: _Realms_ListRealmMember_Handler,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
MethodName: "GetRealmMember",
|
|
||||||
Handler: _Realms_GetRealmMember_Handler,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Streams: []grpc.StreamDesc{},
|
|
||||||
Metadata: "realms.proto",
|
|
||||||
}
|
|
@ -1,151 +0,0 @@
|
|||||||
package grpc
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"git.solsynth.dev/hydrogen/passport/pkg/database"
|
|
||||||
"git.solsynth.dev/hydrogen/passport/pkg/grpc/proto"
|
|
||||||
"git.solsynth.dev/hydrogen/passport/pkg/models"
|
|
||||||
"git.solsynth.dev/hydrogen/passport/pkg/services"
|
|
||||||
"github.com/samber/lo"
|
|
||||||
"google.golang.org/protobuf/types/known/emptypb"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (v *Server) ListCommunityRealm(ctx context.Context, empty *emptypb.Empty) (*proto.ListRealmResponse, error) {
|
|
||||||
realms, err := services.ListCommunityRealm()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &proto.ListRealmResponse{
|
|
||||||
Data: lo.Map(realms, func(item models.Realm, index int) *proto.RealmResponse {
|
|
||||||
return &proto.RealmResponse{
|
|
||||||
Id: uint64(item.ID),
|
|
||||||
Alias: item.Alias,
|
|
||||||
Name: item.Name,
|
|
||||||
Description: item.Description,
|
|
||||||
IsPublic: item.IsPublic,
|
|
||||||
IsCommunity: item.IsCommunity,
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Server) ListAvailableRealm(ctx context.Context, request *proto.RealmLookupWithUserRequest) (*proto.ListRealmResponse, error) {
|
|
||||||
account, err := services.GetAccount(uint(request.GetUserId()))
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("unable to find target account: %v", err)
|
|
||||||
}
|
|
||||||
realms, err := services.ListAvailableRealm(account)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &proto.ListRealmResponse{
|
|
||||||
Data: lo.Map(realms, func(item models.Realm, index int) *proto.RealmResponse {
|
|
||||||
return &proto.RealmResponse{
|
|
||||||
Id: uint64(item.ID),
|
|
||||||
Alias: item.Alias,
|
|
||||||
Name: item.Name,
|
|
||||||
Description: item.Description,
|
|
||||||
IsPublic: item.IsPublic,
|
|
||||||
IsCommunity: item.IsCommunity,
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Server) ListOwnedRealm(ctx context.Context, request *proto.RealmLookupWithUserRequest) (*proto.ListRealmResponse, error) {
|
|
||||||
account, err := services.GetAccount(uint(request.GetUserId()))
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("unable to find target account: %v", err)
|
|
||||||
}
|
|
||||||
realms, err := services.ListOwnedRealm(account)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &proto.ListRealmResponse{
|
|
||||||
Data: lo.Map(realms, func(item models.Realm, index int) *proto.RealmResponse {
|
|
||||||
return &proto.RealmResponse{
|
|
||||||
Id: uint64(item.ID),
|
|
||||||
Alias: item.Alias,
|
|
||||||
Name: item.Name,
|
|
||||||
Description: item.Description,
|
|
||||||
IsPublic: item.IsPublic,
|
|
||||||
IsCommunity: item.IsCommunity,
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Server) GetRealm(ctx context.Context, request *proto.RealmLookupRequest) (*proto.RealmResponse, error) {
|
|
||||||
var realm models.Realm
|
|
||||||
|
|
||||||
tx := database.C.Model(&models.Realm{})
|
|
||||||
if request.Id != nil {
|
|
||||||
tx = tx.Where("id = ?", request.GetId())
|
|
||||||
}
|
|
||||||
if request.Alias != nil {
|
|
||||||
tx = tx.Where("alias = ?", request.GetAlias())
|
|
||||||
}
|
|
||||||
if request.IsPublic != nil {
|
|
||||||
tx = tx.Where("is_public = ?", request.GetIsPublic())
|
|
||||||
}
|
|
||||||
if request.IsCommunity != nil {
|
|
||||||
tx = tx.Where("is_community = ?", request.GetIsCommunity())
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := tx.First(&realm).Error; err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &proto.RealmResponse{
|
|
||||||
Id: uint64(realm.ID),
|
|
||||||
Alias: realm.Alias,
|
|
||||||
Name: realm.Name,
|
|
||||||
Description: realm.Description,
|
|
||||||
IsPublic: realm.IsPublic,
|
|
||||||
IsCommunity: realm.IsCommunity,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Server) ListRealmMember(ctx context.Context, request *proto.RealmMemberLookupRequest) (*proto.ListRealmMemberResponse, error) {
|
|
||||||
var members []models.RealmMember
|
|
||||||
tx := database.C.Where("realm_id = ?", request.GetRealmId())
|
|
||||||
if request.UserId != nil {
|
|
||||||
tx = tx.Where("account_id = ?", request.GetUserId())
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := tx.Find(&members).Error; err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &proto.ListRealmMemberResponse{
|
|
||||||
Data: lo.Map(members, func(item models.RealmMember, index int) *proto.RealmMemberResponse {
|
|
||||||
return &proto.RealmMemberResponse{
|
|
||||||
RealmId: uint64(item.RealmID),
|
|
||||||
UserId: uint64(item.AccountID),
|
|
||||||
PowerLevel: int32(item.PowerLevel),
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Server) GetRealmMember(ctx context.Context, request *proto.RealmMemberLookupRequest) (*proto.RealmMemberResponse, error) {
|
|
||||||
var member models.RealmMember
|
|
||||||
tx := database.C.Where("realm_id = ?", request.GetRealmId())
|
|
||||||
if request.UserId != nil {
|
|
||||||
tx = tx.Where("account_id = ?", request.GetUserId())
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := tx.First(&member).Error; err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &proto.RealmMemberResponse{
|
|
||||||
RealmId: uint64(member.RealmID),
|
|
||||||
UserId: uint64(member.AccountID),
|
|
||||||
PowerLevel: int32(member.PowerLevel),
|
|
||||||
}, nil
|
|
||||||
}
|
|
@ -1,35 +0,0 @@
|
|||||||
package grpc
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
|
|
||||||
"git.solsynth.dev/hydrogen/passport/pkg/grpc/proto"
|
|
||||||
"github.com/spf13/viper"
|
|
||||||
"google.golang.org/grpc"
|
|
||||||
"google.golang.org/grpc/reflection"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Server struct {
|
|
||||||
proto.UnimplementedAuthServer
|
|
||||||
proto.UnimplementedNotifyServer
|
|
||||||
proto.UnimplementedFriendshipsServer
|
|
||||||
proto.UnimplementedRealmsServer
|
|
||||||
}
|
|
||||||
|
|
||||||
func StartGrpc() error {
|
|
||||||
listen, err := net.Listen("tcp", viper.GetString("grpc_bind"))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
server := grpc.NewServer()
|
|
||||||
|
|
||||||
proto.RegisterAuthServer(server, &Server{})
|
|
||||||
proto.RegisterNotifyServer(server, &Server{})
|
|
||||||
proto.RegisterFriendshipsServer(server, &Server{})
|
|
||||||
proto.RegisterRealmsServer(server, &Server{})
|
|
||||||
|
|
||||||
reflection.Register(server)
|
|
||||||
|
|
||||||
return server.Serve(listen)
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
package i18n
|
|
||||||
|
|
||||||
import (
|
|
||||||
jsoniter "github.com/json-iterator/go"
|
|
||||||
"github.com/nicksnyder/go-i18n/v2/i18n"
|
|
||||||
"golang.org/x/text/language"
|
|
||||||
)
|
|
||||||
|
|
||||||
var Bundle *i18n.Bundle
|
|
||||||
|
|
||||||
func InitInternationalization() {
|
|
||||||
Bundle = i18n.NewBundle(language.English)
|
|
||||||
Bundle.RegisterUnmarshalFunc("json", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal)
|
|
||||||
Bundle.LoadMessageFileFS(FS, "locale.en.json")
|
|
||||||
Bundle.LoadMessageFileFS(FS, "locale.zh.json")
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
package i18n
|
|
||||||
|
|
||||||
import "embed"
|
|
||||||
|
|
||||||
//go:embed locale.*.json
|
|
||||||
var FS embed.FS
|
|
@ -1,23 +0,0 @@
|
|||||||
{
|
|
||||||
"next": "Next",
|
|
||||||
"email": "Email",
|
|
||||||
"username": "Username",
|
|
||||||
"nickname": "Nickname",
|
|
||||||
"password": "Password",
|
|
||||||
"unknown": "Unknown",
|
|
||||||
"apply": "Apply",
|
|
||||||
"back": "Back",
|
|
||||||
"approve": "Approve",
|
|
||||||
"decline": "Decline",
|
|
||||||
"magicToken": "Magic Token",
|
|
||||||
"signinTitle": "Sign In",
|
|
||||||
"signinCaption": "Sign in to Solarpass to explore entire Solar Network. Explore posts, discover communities, talk with your best friends. All these things in the Solar Network!",
|
|
||||||
"signinRequired": "You need to sign in before do that.",
|
|
||||||
"signupTitle": "Sign Up",
|
|
||||||
"signupCaption": "Sign up to create an account on Solarpass, then you can explore the entire Solar Network! Enjoy the next-generation Internet Ecosystem!",
|
|
||||||
"authorizeTitle": "Authorize",
|
|
||||||
"authorizeCaption": "One Solarpass, get entire network.",
|
|
||||||
"mfaTitle": "Multi Factor Authenticate",
|
|
||||||
"mfaCaption": "We need use one more way to verify it is you.",
|
|
||||||
"mfaFactorEmail": "OTP through your email"
|
|
||||||
}
|
|
@ -1,23 +0,0 @@
|
|||||||
{
|
|
||||||
"next": "下一步",
|
|
||||||
"email": "邮件地址",
|
|
||||||
"username": "用户名",
|
|
||||||
"nickname": "昵称",
|
|
||||||
"password": "密码",
|
|
||||||
"unknown": "未知",
|
|
||||||
"apply": "应用",
|
|
||||||
"back": "返回",
|
|
||||||
"approve": "接受",
|
|
||||||
"decline": "拒绝",
|
|
||||||
"magicToken": "魔法令牌",
|
|
||||||
"signinTitle": "登陆",
|
|
||||||
"signinCaption": "登陆 Solarpass 以探索整个 Solar Network,浏览帖子、探索社区、和你的好朋友聊八卦,一切尽在 Solar Network!",
|
|
||||||
"signinRequired": "你需要在那之前登陆",
|
|
||||||
"signupTitle": "注册",
|
|
||||||
"signupCaption": "注册以在 Solarpass 创建一个账号,之后你就可以探索整个 Solar Network,享受下一代互联网生态系统!",
|
|
||||||
"authorizeTitle": "授权",
|
|
||||||
"authorizeCaption": "一个 Solarpass,整个网络。",
|
|
||||||
"mfaTitle": "多因素验证",
|
|
||||||
"mfaCaption": "我们需要另一个方法来确认你是你。",
|
|
||||||
"mfaFactorEmail": "电子邮寄一次性验证码"
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
package i18n
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gofiber/fiber/v2"
|
|
||||||
"github.com/nicksnyder/go-i18n/v2/i18n"
|
|
||||||
)
|
|
||||||
|
|
||||||
func I18nMiddleware(c *fiber.Ctx) error {
|
|
||||||
accept := c.Get(fiber.HeaderAcceptLanguage)
|
|
||||||
localizer := i18n.NewLocalizer(Bundle, accept)
|
|
||||||
|
|
||||||
c.Locals("localizer", localizer)
|
|
||||||
|
|
||||||
return c.Next()
|
|
||||||
}
|
|
44
pkg/internal/database/migrator.go
Normal file
44
pkg/internal/database/migrator.go
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
package database
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/authkit/models"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
var AutoMaintainRange = []any{
|
||||||
|
&models.Account{},
|
||||||
|
&models.AccountGroup{},
|
||||||
|
&models.AccountGroupMember{},
|
||||||
|
&models.AuthFactor{},
|
||||||
|
&models.AccountProfile{},
|
||||||
|
&models.AccountPage{},
|
||||||
|
&models.AccountContact{},
|
||||||
|
&models.AccountRelationship{},
|
||||||
|
&models.Status{},
|
||||||
|
&models.Badge{},
|
||||||
|
&models.Realm{},
|
||||||
|
&models.RealmMember{},
|
||||||
|
&models.AuthTicket{},
|
||||||
|
&models.MagicToken{},
|
||||||
|
&models.ThirdClient{},
|
||||||
|
&models.ActionEvent{},
|
||||||
|
&models.Notification{},
|
||||||
|
&models.NotificationSubscriber{},
|
||||||
|
&models.AuditRecord{},
|
||||||
|
&models.ApiKey{},
|
||||||
|
&models.CheckInRecord{},
|
||||||
|
&models.PreferenceNotification{},
|
||||||
|
&models.PreferenceAuth{},
|
||||||
|
&models.AbuseReport{},
|
||||||
|
&models.Program{},
|
||||||
|
&models.ProgramMember{},
|
||||||
|
&models.Punishment{},
|
||||||
|
}
|
||||||
|
|
||||||
|
func RunMigration(source *gorm.DB) error {
|
||||||
|
if err := source.AutoMigrate(AutoMaintainRange...); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
43
pkg/internal/database/source.go
Normal file
43
pkg/internal/database/source.go
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
package database
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"git.solsynth.dev/hypernet/nexus/pkg/nex/cruda"
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/internal/gap"
|
||||||
|
"github.com/oschwald/geoip2-golang"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
"github.com/samber/lo"
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
"gorm.io/driver/postgres"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
"gorm.io/gorm/logger"
|
||||||
|
)
|
||||||
|
|
||||||
|
var C *gorm.DB
|
||||||
|
|
||||||
|
func NewGorm() error {
|
||||||
|
dsn, err := cruda.NewCrudaConn(gap.Nx).AllocDatabase("passport")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to alloc database from nexus: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
C, err = gorm.Open(postgres.Open(dsn), &gorm.Config{Logger: logger.New(&log.Logger, logger.Config{
|
||||||
|
Colorful: true,
|
||||||
|
IgnoreRecordNotFoundError: true,
|
||||||
|
LogLevel: lo.Ternary(viper.GetBool("debug.database"), logger.Info, logger.Silent),
|
||||||
|
})})
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var Gc *geoip2.Reader
|
||||||
|
|
||||||
|
func NewGeoDB() error {
|
||||||
|
conn, err := geoip2.Open(viper.GetString("geoip_db"))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to open geoip database: %v", err)
|
||||||
|
}
|
||||||
|
Gc = conn
|
||||||
|
return nil
|
||||||
|
}
|
77
pkg/internal/gap/server.go
Normal file
77
pkg/internal/gap/server.go
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
package gap
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"git.solsynth.dev/hypernet/nexus/pkg/nex/cachekit"
|
||||||
|
"git.solsynth.dev/hypernet/nexus/pkg/nex/localize"
|
||||||
|
|
||||||
|
"git.solsynth.dev/hypernet/nexus/pkg/nex"
|
||||||
|
"git.solsynth.dev/hypernet/nexus/pkg/nex/rx"
|
||||||
|
"git.solsynth.dev/hypernet/nexus/pkg/proto"
|
||||||
|
"git.solsynth.dev/hypernet/pusher/pkg/pushkit/pushcon"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
"github.com/samber/lo"
|
||||||
|
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
Nx *nex.Conn
|
||||||
|
Px *pushcon.Conn
|
||||||
|
Rx *rx.MqConn
|
||||||
|
Ca *cachekit.Conn
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
FactorOtpPrefix = "auth-otp"
|
||||||
|
)
|
||||||
|
|
||||||
|
func InitializeToNexus() error {
|
||||||
|
grpcBind := strings.SplitN(viper.GetString("grpc_bind"), ":", 2)
|
||||||
|
httpBind := strings.SplitN(viper.GetString("bind"), ":", 2)
|
||||||
|
|
||||||
|
outboundIp, _ := nex.GetOutboundIP()
|
||||||
|
|
||||||
|
grpcOutbound := fmt.Sprintf("%s:%s", outboundIp, grpcBind[1])
|
||||||
|
httpOutbound := fmt.Sprintf("%s:%s", outboundIp, httpBind[1])
|
||||||
|
|
||||||
|
var err error
|
||||||
|
Nx, err = nex.NewNexusConn(viper.GetString("nexus_addr"), &proto.ServiceInfo{
|
||||||
|
Id: viper.GetString("id"),
|
||||||
|
Type: nex.ServiceTypeAuth,
|
||||||
|
Label: "Passport",
|
||||||
|
GrpcAddr: grpcOutbound,
|
||||||
|
HttpAddr: lo.ToPtr("http://" + httpOutbound + "/api"),
|
||||||
|
})
|
||||||
|
if err == nil {
|
||||||
|
go func() {
|
||||||
|
err := Nx.RunRegistering()
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msg("An error occurred while registering service...")
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
Px, err = pushcon.NewConn(Nx)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error during initialize pushcon: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
Rx, err = rx.NewMqConn(Nx)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error during initialize nexus rx module: %v", err)
|
||||||
|
}
|
||||||
|
Ca, err = cachekit.NewConn(Nx, time.Second*3)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error during initialize nexus cache module: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func LoadLocalization() error {
|
||||||
|
return localize.LoadLocalization(viper.GetString("locales_dir"), viper.GetString("templates_dir"))
|
||||||
|
}
|
75
pkg/internal/grpc/auth.go
Normal file
75
pkg/internal/grpc/auth.go
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
package grpc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"git.solsynth.dev/hypernet/nexus/pkg/nex"
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/authkit/models"
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/internal/services"
|
||||||
|
jsoniter "github.com/json-iterator/go"
|
||||||
|
|
||||||
|
"git.solsynth.dev/hypernet/nexus/pkg/proto"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (v *App) Authenticate(_ context.Context, in *proto.AuthRequest) (*proto.AuthReply, error) {
|
||||||
|
ticket, perms, err := services.Authenticate(uint(in.GetSessionId()))
|
||||||
|
if err != nil {
|
||||||
|
return &proto.AuthReply{
|
||||||
|
IsValid: false,
|
||||||
|
}, nil
|
||||||
|
} else {
|
||||||
|
user := ticket.Account
|
||||||
|
userinfo := &proto.UserInfo{
|
||||||
|
Id: uint64(user.ID),
|
||||||
|
Name: user.Name,
|
||||||
|
PermNodes: nex.EncodeMap(perms),
|
||||||
|
Metadata: nex.EncodeMap(user),
|
||||||
|
}
|
||||||
|
|
||||||
|
return &proto.AuthReply{
|
||||||
|
IsValid: true,
|
||||||
|
Info: &proto.AuthInfo{
|
||||||
|
SessionId: uint64(ticket.ID),
|
||||||
|
Info: userinfo,
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *App) EnsurePermGranted(_ context.Context, in *proto.CheckPermRequest) (*proto.CheckPermResponse, error) {
|
||||||
|
ctx, err := services.GetAuthContext(uint(in.GetSessionId()))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var heldPerms map[string]any
|
||||||
|
rawHeldPerms, _ := jsoniter.Marshal(ctx.Account.PermNodes)
|
||||||
|
_ = jsoniter.Unmarshal(rawHeldPerms, &heldPerms)
|
||||||
|
|
||||||
|
var value any
|
||||||
|
_ = jsoniter.Unmarshal(in.GetValue(), &value)
|
||||||
|
perms := services.FilterPermNodes(heldPerms, ctx.Claims)
|
||||||
|
valid := services.HasPermNode(perms, in.GetKey(), value)
|
||||||
|
|
||||||
|
return &proto.CheckPermResponse{
|
||||||
|
IsValid: valid,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *App) EnsureUserPermGranted(_ context.Context, in *proto.CheckUserPermRequest) (*proto.CheckUserPermResponse, error) {
|
||||||
|
relation, err := services.GetRelationWithTwoNode(uint(in.GetUserId()), uint(in.GetOtherId()))
|
||||||
|
if err != nil {
|
||||||
|
return &proto.CheckUserPermResponse{
|
||||||
|
IsValid: false,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultPerm := relation.Status == models.RelationshipFriend
|
||||||
|
|
||||||
|
var value any
|
||||||
|
_ = jsoniter.Unmarshal(in.GetValue(), &value)
|
||||||
|
valid := services.HasPermNodeWithDefault(relation.PermNodes, in.GetKey(), value, defaultPerm)
|
||||||
|
|
||||||
|
return &proto.CheckUserPermResponse{
|
||||||
|
IsValid: valid,
|
||||||
|
}, nil
|
||||||
|
}
|
21
pkg/internal/grpc/events.go
Normal file
21
pkg/internal/grpc/events.go
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package grpc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"git.solsynth.dev/hypernet/nexus/pkg/nex"
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/internal/services"
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/proto"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (v *App) RecordEvent(ctx context.Context, request *proto.RecordEventRequest) (*proto.RecordEventResponse, error) {
|
||||||
|
services.AddEvent(
|
||||||
|
uint(request.GetUserId()),
|
||||||
|
request.GetAction(),
|
||||||
|
nex.DecodeMap(request.GetMetadata()),
|
||||||
|
request.GetIp(),
|
||||||
|
request.GetUserAgent(),
|
||||||
|
)
|
||||||
|
|
||||||
|
return &proto.RecordEventResponse{IsSuccess: true}, nil
|
||||||
|
}
|
26
pkg/internal/grpc/health.go
Normal file
26
pkg/internal/grpc/health.go
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
package grpc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
health "google.golang.org/grpc/health/grpc_health_v1"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (v *App) Check(ctx context.Context, request *health.HealthCheckRequest) (*health.HealthCheckResponse, error) {
|
||||||
|
return &health.HealthCheckResponse{
|
||||||
|
Status: health.HealthCheckResponse_SERVING,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *App) Watch(request *health.HealthCheckRequest, server health.Health_WatchServer) error {
|
||||||
|
for {
|
||||||
|
if server.Send(&health.HealthCheckResponse{
|
||||||
|
Status: health.HealthCheckResponse_SERVING,
|
||||||
|
}) != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
time.Sleep(1000 * time.Millisecond)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
140
pkg/internal/grpc/notify.go
Normal file
140
pkg/internal/grpc/notify.go
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
package grpc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/authkit/models"
|
||||||
|
"git.solsynth.dev/hypernet/pusher/pkg/pushkit"
|
||||||
|
"github.com/goccy/go-json"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/internal/database"
|
||||||
|
"github.com/samber/lo"
|
||||||
|
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/internal/services"
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/proto"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (v *App) NotifyUser(_ context.Context, in *proto.NotifyUserRequest) (*proto.NotifyResponse, error) {
|
||||||
|
var err error
|
||||||
|
var user models.Account
|
||||||
|
if user, err = services.GetAccount(uint(in.GetUserId())); err != nil {
|
||||||
|
return nil, fmt.Errorf("unable to get account: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var nty pushkit.Notification
|
||||||
|
if err = json.Unmarshal(in.GetNotify().GetData(), &nty); err != nil {
|
||||||
|
return nil, fmt.Errorf("unable to unmarshal notification: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
notification := models.NewNotificationFromPushkit(nty)
|
||||||
|
notification.Account = user
|
||||||
|
notification.AccountID = user.ID
|
||||||
|
|
||||||
|
log.Debug().Str("topic", notification.Topic).Uint("uid", notification.AccountID).Msg("Notifying user...")
|
||||||
|
|
||||||
|
if in.GetNotify().GetUnsaved() {
|
||||||
|
if err := services.PushNotification(notification); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if err := services.NewNotification(notification); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &proto.NotifyResponse{
|
||||||
|
IsSuccess: true,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *App) NotifyUserBatch(_ context.Context, in *proto.NotifyUserBatchRequest) (*proto.NotifyResponse, error) {
|
||||||
|
var err error
|
||||||
|
var users []models.Account
|
||||||
|
if users, err = services.GetAccountList(lo.Map(in.GetUserId(), func(item uint64, index int) uint {
|
||||||
|
return uint(item)
|
||||||
|
})); err != nil {
|
||||||
|
return nil, fmt.Errorf("unable to get account: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var nty pushkit.Notification
|
||||||
|
if err = json.Unmarshal(in.GetNotify().GetData(), &nty); err != nil {
|
||||||
|
return nil, fmt.Errorf("unable to unmarshal notification: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var checklist = make(map[uint]bool, len(users))
|
||||||
|
var notifications []models.Notification
|
||||||
|
for _, user := range users {
|
||||||
|
if _, ok := checklist[user.ID]; ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
notification := models.NewNotificationFromPushkit(nty)
|
||||||
|
notification.Account = user
|
||||||
|
notification.AccountID = user.ID
|
||||||
|
checklist[user.ID] = true
|
||||||
|
|
||||||
|
notifications = append(notifications, notification)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(notifications) == 0 {
|
||||||
|
return &proto.NotifyResponse{
|
||||||
|
IsSuccess: true,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debug().Str("topic", notifications[0].Topic).Any("uid", lo.Keys(checklist)).Msg("Notifying users...")
|
||||||
|
|
||||||
|
if in.GetNotify().GetUnsaved() {
|
||||||
|
services.PushNotificationBatch(notifications)
|
||||||
|
} else {
|
||||||
|
if err := services.NewNotificationBatch(notifications); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &proto.NotifyResponse{
|
||||||
|
IsSuccess: true,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *App) NotifyAllUser(_ context.Context, in *proto.NotifyInfoPayload) (*proto.NotifyResponse, error) {
|
||||||
|
var users []models.Account
|
||||||
|
if err := database.C.Find(&users).Error; err != nil {
|
||||||
|
return nil, fmt.Errorf("unable to get account: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var nty pushkit.Notification
|
||||||
|
if err := json.Unmarshal(in.GetData(), &nty); err != nil {
|
||||||
|
return nil, fmt.Errorf("unable to unmarshal notification: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var checklist = make(map[uint]bool, len(users))
|
||||||
|
var notifications []models.Notification
|
||||||
|
for _, user := range users {
|
||||||
|
if checklist[user.ID] {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
notification := models.NewNotificationFromPushkit(nty)
|
||||||
|
notification.Account = user
|
||||||
|
notification.AccountID = user.ID
|
||||||
|
checklist[user.ID] = true
|
||||||
|
|
||||||
|
notifications = append(notifications, notification)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debug().Str("topic", notifications[0].Topic).Any("uid", lo.Keys(checklist)).Msg("Notifying users...")
|
||||||
|
|
||||||
|
if in.GetUnsaved() {
|
||||||
|
services.PushNotificationBatch(notifications)
|
||||||
|
} else {
|
||||||
|
if err := services.NewNotificationBatch(notifications); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &proto.NotifyResponse{
|
||||||
|
IsSuccess: true,
|
||||||
|
}, nil
|
||||||
|
}
|
216
pkg/internal/grpc/realms.go
Normal file
216
pkg/internal/grpc/realms.go
Normal file
@ -0,0 +1,216 @@
|
|||||||
|
package grpc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"git.solsynth.dev/hypernet/nexus/pkg/nex"
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/authkit/models"
|
||||||
|
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/internal/database"
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/internal/services"
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/proto"
|
||||||
|
"github.com/samber/lo"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (v *App) ListAvailableRealm(ctx context.Context, request *proto.LookupUserRealmRequest) (*proto.ListRealmResponse, error) {
|
||||||
|
account, err := services.GetAccount(uint(request.GetUserId()))
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("unable to find target account: %v", err)
|
||||||
|
}
|
||||||
|
realms, err := services.ListAvailableRealm(account, request.GetIncludePublic())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &proto.ListRealmResponse{
|
||||||
|
Data: lo.Map(realms, func(item models.Realm, index int) *proto.RealmInfo {
|
||||||
|
info := &proto.RealmInfo{
|
||||||
|
Id: uint64(item.ID),
|
||||||
|
Alias: item.Alias,
|
||||||
|
Name: item.Name,
|
||||||
|
Description: item.Description,
|
||||||
|
IsPublic: item.IsPublic,
|
||||||
|
IsCommunity: item.IsCommunity,
|
||||||
|
AccessPolicy: nex.EncodeMap(item.AccessPolicy),
|
||||||
|
}
|
||||||
|
if item.Avatar != nil {
|
||||||
|
info.Avatar = *item.Avatar
|
||||||
|
}
|
||||||
|
if item.Banner != nil {
|
||||||
|
info.Banner = *item.Banner
|
||||||
|
}
|
||||||
|
return info
|
||||||
|
}),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *App) ListOwnedRealm(ctx context.Context, request *proto.LookupUserRealmRequest) (*proto.ListRealmResponse, error) {
|
||||||
|
account, err := services.GetAccount(uint(request.GetUserId()))
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("unable to find target account: %v", err)
|
||||||
|
}
|
||||||
|
realms, err := services.ListOwnedRealm(account)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &proto.ListRealmResponse{
|
||||||
|
Data: lo.Map(realms, func(item models.Realm, index int) *proto.RealmInfo {
|
||||||
|
info := &proto.RealmInfo{
|
||||||
|
Id: uint64(item.ID),
|
||||||
|
Alias: item.Alias,
|
||||||
|
Name: item.Name,
|
||||||
|
Description: item.Description,
|
||||||
|
IsPublic: item.IsPublic,
|
||||||
|
IsCommunity: item.IsCommunity,
|
||||||
|
AccessPolicy: nex.EncodeMap(item.AccessPolicy),
|
||||||
|
}
|
||||||
|
if item.Avatar != nil {
|
||||||
|
info.Avatar = *item.Avatar
|
||||||
|
}
|
||||||
|
if item.Banner != nil {
|
||||||
|
info.Banner = *item.Banner
|
||||||
|
}
|
||||||
|
return info
|
||||||
|
}),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *App) ListRealm(ctx context.Context, request *proto.ListRealmRequest) (*proto.ListRealmResponse, error) {
|
||||||
|
var realms []models.Realm
|
||||||
|
if err := database.C.Where("id IN ?", request.GetId()).Find(&realms).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &proto.ListRealmResponse{
|
||||||
|
Data: lo.Map(realms, func(item models.Realm, index int) *proto.RealmInfo {
|
||||||
|
info := &proto.RealmInfo{
|
||||||
|
Id: uint64(item.ID),
|
||||||
|
Alias: item.Alias,
|
||||||
|
Name: item.Name,
|
||||||
|
Description: item.Description,
|
||||||
|
IsPublic: item.IsPublic,
|
||||||
|
IsCommunity: item.IsCommunity,
|
||||||
|
AccessPolicy: nex.EncodeMap(item.AccessPolicy),
|
||||||
|
}
|
||||||
|
if item.Avatar != nil {
|
||||||
|
info.Avatar = *item.Avatar
|
||||||
|
}
|
||||||
|
if item.Banner != nil {
|
||||||
|
info.Banner = *item.Banner
|
||||||
|
}
|
||||||
|
return info
|
||||||
|
}),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *App) GetRealm(ctx context.Context, request *proto.LookupRealmRequest) (*proto.RealmInfo, error) {
|
||||||
|
var realm models.Realm
|
||||||
|
|
||||||
|
tx := database.C.Model(&models.Realm{})
|
||||||
|
if request.Id != nil {
|
||||||
|
tx = tx.Where("id = ?", request.GetId())
|
||||||
|
}
|
||||||
|
if request.Alias != nil {
|
||||||
|
tx = tx.Where("alias = ?", request.GetAlias())
|
||||||
|
}
|
||||||
|
if request.IsPublic != nil {
|
||||||
|
tx = tx.Where("is_public = ?", request.GetIsPublic())
|
||||||
|
}
|
||||||
|
if request.IsCommunity != nil {
|
||||||
|
tx = tx.Where("is_community = ?", request.GetIsCommunity())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := tx.First(&realm).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
info := &proto.RealmInfo{
|
||||||
|
Id: uint64(realm.ID),
|
||||||
|
Alias: realm.Alias,
|
||||||
|
Name: realm.Name,
|
||||||
|
Description: realm.Description,
|
||||||
|
IsPublic: realm.IsPublic,
|
||||||
|
IsCommunity: realm.IsCommunity,
|
||||||
|
AccessPolicy: nex.EncodeMap(realm.AccessPolicy),
|
||||||
|
}
|
||||||
|
if realm.Avatar != nil {
|
||||||
|
info.Avatar = *realm.Avatar
|
||||||
|
}
|
||||||
|
if realm.Banner != nil {
|
||||||
|
info.Banner = *realm.Banner
|
||||||
|
}
|
||||||
|
return info, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *App) ListRealmMember(ctx context.Context, request *proto.RealmMemberLookupRequest) (*proto.ListRealmMemberResponse, error) {
|
||||||
|
var members []models.RealmMember
|
||||||
|
if request.UserId == nil && request.RealmId == nil {
|
||||||
|
return nil, fmt.Errorf("either user id or realm id must be provided")
|
||||||
|
}
|
||||||
|
tx := database.C
|
||||||
|
if request.RealmId != nil {
|
||||||
|
tx = tx.Where("realm_id = ?", request.GetRealmId())
|
||||||
|
}
|
||||||
|
if request.UserId != nil {
|
||||||
|
tx = tx.Where("account_id = ?", request.GetUserId())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := tx.Find(&members).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &proto.ListRealmMemberResponse{
|
||||||
|
Data: lo.Map(members, func(item models.RealmMember, index int) *proto.RealmMemberInfo {
|
||||||
|
return &proto.RealmMemberInfo{
|
||||||
|
Id: uint64(item.ID),
|
||||||
|
RealmId: uint64(item.RealmID),
|
||||||
|
UserId: uint64(item.AccountID),
|
||||||
|
PowerLevel: int32(item.PowerLevel),
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *App) GetRealmMember(ctx context.Context, request *proto.RealmMemberLookupRequest) (*proto.RealmMemberInfo, error) {
|
||||||
|
var member models.RealmMember
|
||||||
|
if request.UserId == nil && request.RealmId == nil {
|
||||||
|
return nil, fmt.Errorf("either user id or realm id must be provided")
|
||||||
|
}
|
||||||
|
tx := database.C
|
||||||
|
if request.RealmId != nil {
|
||||||
|
tx = tx.Where("realm_id = ?", request.GetRealmId())
|
||||||
|
}
|
||||||
|
if request.UserId != nil {
|
||||||
|
tx = tx.Where("account_id = ?", request.GetUserId())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := tx.First(&member).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &proto.RealmMemberInfo{
|
||||||
|
Id: uint64(member.ID),
|
||||||
|
RealmId: uint64(member.RealmID),
|
||||||
|
UserId: uint64(member.AccountID),
|
||||||
|
PowerLevel: int32(member.PowerLevel),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *App) CheckRealmMemberPerm(ctx context.Context, request *proto.CheckRealmPermRequest) (*proto.CheckRealmPermResponse, error) {
|
||||||
|
var member models.RealmMember
|
||||||
|
tx := database.C.
|
||||||
|
Where("realm_id = ?", request.GetRealmId()).
|
||||||
|
Where("account_id = ?", request.GetUserId())
|
||||||
|
|
||||||
|
if err := tx.First(&member).Error; err != nil {
|
||||||
|
return &proto.CheckRealmPermResponse{
|
||||||
|
IsSuccess: false,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return &proto.CheckRealmPermResponse{
|
||||||
|
IsSuccess: member.PowerLevel >= int(request.GetPowerLevel()),
|
||||||
|
}, nil
|
||||||
|
}
|
57
pkg/internal/grpc/server.go
Normal file
57
pkg/internal/grpc/server.go
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
package grpc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
|
||||||
|
"google.golang.org/grpc/reflection"
|
||||||
|
|
||||||
|
nroto "git.solsynth.dev/hypernet/nexus/pkg/proto"
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/proto"
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
"google.golang.org/grpc"
|
||||||
|
|
||||||
|
health "google.golang.org/grpc/health/grpc_health_v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
type App struct {
|
||||||
|
nroto.UnimplementedAuthServiceServer
|
||||||
|
nroto.UnimplementedDirectoryServiceServer
|
||||||
|
nroto.UnimplementedUserServiceServer
|
||||||
|
nroto.UnimplementedStreamServiceServer
|
||||||
|
proto.UnimplementedRealmServiceServer
|
||||||
|
proto.UnimplementedAuditServiceServer
|
||||||
|
proto.UnimplementedNotifyServiceServer
|
||||||
|
proto.UnimplementedThirdClientServiceServer
|
||||||
|
health.UnimplementedHealthServer
|
||||||
|
|
||||||
|
srv *grpc.Server
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewServer() *App {
|
||||||
|
server := &App{
|
||||||
|
srv: grpc.NewServer(),
|
||||||
|
}
|
||||||
|
|
||||||
|
nroto.RegisterAuthServiceServer(server.srv, server)
|
||||||
|
nroto.RegisterUserServiceServer(server.srv, server)
|
||||||
|
nroto.RegisterDirectoryServiceServer(server.srv, server)
|
||||||
|
nroto.RegisterStreamServiceServer(server.srv, server)
|
||||||
|
proto.RegisterNotifyServiceServer(server.srv, server)
|
||||||
|
proto.RegisterRealmServiceServer(server.srv, server)
|
||||||
|
proto.RegisterAuditServiceServer(server.srv, server)
|
||||||
|
proto.RegisterThirdClientServiceServer(server.srv, server)
|
||||||
|
health.RegisterHealthServer(server.srv, server)
|
||||||
|
|
||||||
|
reflection.Register(server.srv)
|
||||||
|
|
||||||
|
return server
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *App) Listen() error {
|
||||||
|
listener, err := net.Listen("tcp", viper.GetString("grpc_bind"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return v.srv.Serve(listener)
|
||||||
|
}
|
125
pkg/internal/grpc/stream.go
Normal file
125
pkg/internal/grpc/stream.go
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
package grpc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"git.solsynth.dev/hypernet/nexus/pkg/nex"
|
||||||
|
"git.solsynth.dev/hypernet/nexus/pkg/proto"
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/internal/gap"
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/internal/services"
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/internal/web/exts"
|
||||||
|
jsoniter "github.com/json-iterator/go"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
"github.com/samber/lo"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (v *App) BroadcastEvent(ctx context.Context, request *proto.EventInfo) (*proto.EventResponse, error) {
|
||||||
|
log.Debug().Str("event", request.GetEvent()).
|
||||||
|
Msg("Got a broadcasting event...")
|
||||||
|
|
||||||
|
switch request.GetEvent() {
|
||||||
|
// Last seen at
|
||||||
|
case "ws.client.register":
|
||||||
|
// No longer need update user online status
|
||||||
|
// Based on realtime sever connection status
|
||||||
|
break
|
||||||
|
case "ws.client.unregister":
|
||||||
|
// Update user last seen at
|
||||||
|
data := nex.DecodeMap(request.GetData())
|
||||||
|
err := services.SetAccountLastSeen(uint(data["user"].(float64)))
|
||||||
|
log.Debug().Err(err).Any("event", data).Msg("Setting account last seen...")
|
||||||
|
}
|
||||||
|
|
||||||
|
return &proto.EventResponse{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *App) PushStream(_ context.Context, request *proto.PushStreamRequest) (*proto.PushStreamResponse, error) {
|
||||||
|
sc := proto.NewStreamServiceClient(gap.Nx.GetNexusGrpcConn())
|
||||||
|
|
||||||
|
var in nex.WebSocketPackage
|
||||||
|
if err := jsoniter.Unmarshal(request.GetBody(), &in); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
switch in.Action {
|
||||||
|
// PaKex (Key Exchange)
|
||||||
|
case "kex.ask":
|
||||||
|
var data struct {
|
||||||
|
UserID uint `json:"user_id" validate:"required"`
|
||||||
|
KeypairID string `json:"keypair_id" validate:"required"`
|
||||||
|
ClientID string `json:"client_id" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
err := jsoniter.Unmarshal(in.RawPayload(), &data)
|
||||||
|
if request.ClientId != nil {
|
||||||
|
data.ClientID = *request.ClientId
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
err = exts.ValidateStruct(data)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
_, _ = sc.PushStream(context.Background(), &proto.PushStreamRequest{
|
||||||
|
ClientId: request.ClientId,
|
||||||
|
Body: nex.WebSocketPackage{
|
||||||
|
Action: "error",
|
||||||
|
Message: fmt.Sprintf("unable parse payload: %v", err),
|
||||||
|
}.Marshal(),
|
||||||
|
})
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// Forward ask request
|
||||||
|
sc.PushStream(context.Background(), &proto.PushStreamRequest{
|
||||||
|
UserId: lo.ToPtr(uint64(data.UserID)),
|
||||||
|
Body: nex.WebSocketPackage{
|
||||||
|
Action: "kex.ask",
|
||||||
|
Payload: data,
|
||||||
|
}.Marshal(),
|
||||||
|
})
|
||||||
|
case "kex.ack":
|
||||||
|
var data struct {
|
||||||
|
UserID uint `json:"user_id" validate:"required"`
|
||||||
|
KeypairID string `json:"keypair_id" validate:"required"`
|
||||||
|
PublicKey string `json:"public_key"`
|
||||||
|
PrivateKey string `json:"private_key"`
|
||||||
|
ClientID string `json:"client_id" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
err := jsoniter.Unmarshal(in.RawPayload(), &data)
|
||||||
|
if err == nil {
|
||||||
|
err = exts.ValidateStruct(data)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
_, _ = sc.PushStream(context.Background(), &proto.PushStreamRequest{
|
||||||
|
ClientId: request.ClientId,
|
||||||
|
Body: nex.WebSocketPackage{
|
||||||
|
Action: "error",
|
||||||
|
Message: fmt.Sprintf("unable parse payload: %v", err),
|
||||||
|
}.Marshal(),
|
||||||
|
})
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if len(data.PublicKey) == 0 && len(data.PrivateKey) == 0 {
|
||||||
|
_, _ = sc.PushStream(context.Background(), &proto.PushStreamRequest{
|
||||||
|
ClientId: request.ClientId,
|
||||||
|
Body: nex.WebSocketPackage{
|
||||||
|
Action: "error",
|
||||||
|
Message: "one of public key and private key is required",
|
||||||
|
}.Marshal(),
|
||||||
|
})
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// Forward ack request
|
||||||
|
sc.PushStream(context.Background(), &proto.PushStreamRequest{
|
||||||
|
ClientId: &data.ClientID,
|
||||||
|
Body: nex.WebSocketPackage{
|
||||||
|
Action: "kex.ack",
|
||||||
|
Payload: data,
|
||||||
|
}.Marshal(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return &proto.PushStreamResponse{}, nil
|
||||||
|
}
|
42
pkg/internal/grpc/third_client.go
Normal file
42
pkg/internal/grpc/third_client.go
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
package grpc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/authkit/models"
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/internal/database"
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/proto"
|
||||||
|
"google.golang.org/grpc/codes"
|
||||||
|
"google.golang.org/grpc/status"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (v *App) GetThirdClient(ctx context.Context, request *proto.GetThirdClientRequest) (*proto.GetThirdClientResponse, error) {
|
||||||
|
tx := database.C
|
||||||
|
if request.Id == nil && request.Alias == nil {
|
||||||
|
return nil, status.Error(codes.InvalidArgument, "either id or alias must be specified")
|
||||||
|
}
|
||||||
|
if request.Id != nil {
|
||||||
|
tx = tx.Where("id = ?", request.Id)
|
||||||
|
} else if request.Alias != nil {
|
||||||
|
tx = tx.Where("alias = ?", request.Alias)
|
||||||
|
}
|
||||||
|
|
||||||
|
var client models.ThirdClient
|
||||||
|
if err := tx.First(&client).Error; err != nil {
|
||||||
|
return nil, status.Errorf(codes.NotFound, "requested client was not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
if request.Secret != nil {
|
||||||
|
if client.Secret != request.GetSecret() {
|
||||||
|
return nil, status.Errorf(codes.PermissionDenied, "invalid secret")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &proto.GetThirdClientResponse{
|
||||||
|
Info: &proto.ThirdClientInfo{
|
||||||
|
Id: uint64(client.ID),
|
||||||
|
Name: client.Name,
|
||||||
|
Description: client.Description,
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
77
pkg/internal/grpc/user.go
Normal file
77
pkg/internal/grpc/user.go
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
package grpc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"git.solsynth.dev/hypernet/nexus/pkg/proto"
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/authkit/models"
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/internal/database"
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/internal/services"
|
||||||
|
"github.com/samber/lo"
|
||||||
|
"google.golang.org/grpc/codes"
|
||||||
|
"google.golang.org/grpc/status"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (v *App) GetUser(ctx context.Context, request *proto.GetUserRequest) (*proto.UserInfo, error) {
|
||||||
|
var account models.Account
|
||||||
|
var err error
|
||||||
|
if request.UserId != nil {
|
||||||
|
account, err = services.GetAccountForEnd(uint(request.GetUserId()))
|
||||||
|
} else if request.Name != nil {
|
||||||
|
account, err = services.GetAccountForEnd(request.GetName())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Errorf(codes.NotFound, fmt.Sprintf("unable to get account punishments: %v", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
return account.EncodeToUserInfo(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *App) ListUser(ctx context.Context, request *proto.ListUserRequest) (*proto.MultipleUserInfo, error) {
|
||||||
|
var accounts []models.Account
|
||||||
|
if err := database.C.
|
||||||
|
Where("id IN ?", lo.Map(request.GetUserId(), func(id uint64, _ int) interface{} { return id })).
|
||||||
|
Find(&accounts).Error; err != nil {
|
||||||
|
return nil, status.Errorf(codes.Internal, fmt.Sprintf("failed to list users: %v", err))
|
||||||
|
}
|
||||||
|
return &proto.MultipleUserInfo{
|
||||||
|
Data: lo.Map(request.GetUserId(), func(item uint64, index int) *proto.UserInfo {
|
||||||
|
val, ok := lo.Find(accounts, func(x models.Account) bool {
|
||||||
|
return uint(item) == x.ID
|
||||||
|
})
|
||||||
|
if !ok {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return val.EncodeToUserInfo()
|
||||||
|
}),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *App) ListUserRelative(ctx context.Context, request *proto.ListUserRelativeRequest) (*proto.ListUserRelativeResponse, error) {
|
||||||
|
tx := database.C.Preload("Account").Preload("Related").Where("status = ?", request.GetStatus())
|
||||||
|
|
||||||
|
if request.GetIsRelated() {
|
||||||
|
tx = tx.Where("related_id = ?", request.GetUserId())
|
||||||
|
} else {
|
||||||
|
tx = tx.Where("account_id = ?", request.GetUserId())
|
||||||
|
}
|
||||||
|
|
||||||
|
var data []models.AccountRelationship
|
||||||
|
if err := tx.Find(&data).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &proto.ListUserRelativeResponse{
|
||||||
|
Data: lo.Map(data, func(item models.AccountRelationship, index int) *proto.UserInfo {
|
||||||
|
account := lo.Ternary(request.GetIsRelated(), item.Account, item.Related)
|
||||||
|
val := &proto.UserInfo{
|
||||||
|
Id: uint64(account.ID),
|
||||||
|
Name: account.Name,
|
||||||
|
}
|
||||||
|
|
||||||
|
return val
|
||||||
|
}),
|
||||||
|
}, nil
|
||||||
|
}
|
25
pkg/internal/services/account_groups.go
Normal file
25
pkg/internal/services/account_groups.go
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
package services
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/authkit/models"
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/internal/database"
|
||||||
|
"github.com/samber/lo"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetUserAccountGroup(user models.Account) ([]models.AccountGroup, error) {
|
||||||
|
var members []models.AccountGroupMember
|
||||||
|
if err := database.C.Where(&models.AccountGroupMember{
|
||||||
|
AccountID: user.ID,
|
||||||
|
}).Find(&members).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var groups []models.AccountGroup
|
||||||
|
if err := database.C.Where("id IN ?", lo.Map(members, func(item models.AccountGroupMember, index int) uint {
|
||||||
|
return item.GroupID
|
||||||
|
})).Find(&groups).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return groups, nil
|
||||||
|
}
|
433
pkg/internal/services/accounts.go
Normal file
433
pkg/internal/services/accounts.go
Normal file
@ -0,0 +1,433 @@
|
|||||||
|
package services
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"maps"
|
||||||
|
"time"
|
||||||
|
"unicode"
|
||||||
|
|
||||||
|
"git.solsynth.dev/hypernet/nexus/pkg/nex"
|
||||||
|
"git.solsynth.dev/hypernet/nexus/pkg/nex/cachekit"
|
||||||
|
"git.solsynth.dev/hypernet/nexus/pkg/proto"
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/authkit/models"
|
||||||
|
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/internal/gap"
|
||||||
|
|
||||||
|
"gorm.io/gorm"
|
||||||
|
"gorm.io/gorm/clause"
|
||||||
|
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
"gorm.io/datatypes"
|
||||||
|
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/internal/database"
|
||||||
|
"github.com/samber/lo"
|
||||||
|
)
|
||||||
|
|
||||||
|
func KgAccountCache(query any) string {
|
||||||
|
return cachekit.FKey(cachekit.DAUser, query)
|
||||||
|
}
|
||||||
|
|
||||||
|
func CacheAccount(account models.Account) {
|
||||||
|
cachekit.Set[models.Account](
|
||||||
|
gap.Ca,
|
||||||
|
KgAccountCache(account.Name),
|
||||||
|
account,
|
||||||
|
60*time.Minute,
|
||||||
|
fmt.Sprintf("user#%d", account.ID),
|
||||||
|
)
|
||||||
|
cachekit.Set[models.Account](
|
||||||
|
gap.Ca,
|
||||||
|
KgAccountCache(account.ID),
|
||||||
|
account,
|
||||||
|
60*time.Minute,
|
||||||
|
fmt.Sprintf("user#%d", account.ID),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ValidateAccountName(val string, min, max int) bool {
|
||||||
|
actualLength := 0
|
||||||
|
for _, r := range val {
|
||||||
|
if unicode.Is(unicode.Han, r) || unicode.Is(unicode.Hiragana, r) || unicode.Is(unicode.Katakana, r) || unicode.Is(unicode.Hangul, r) {
|
||||||
|
actualLength += 2
|
||||||
|
} else {
|
||||||
|
actualLength += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return actualLength >= min && max >= actualLength
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetAccountForEnd(id any) (models.Account, error) {
|
||||||
|
if val, err := cachekit.Get[models.Account](gap.Ca, KgAccountCache(id)); err == nil {
|
||||||
|
return val, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var account models.Account
|
||||||
|
tx := database.C
|
||||||
|
switch id.(type) {
|
||||||
|
case uint:
|
||||||
|
tx = tx.Where("id = ?", id)
|
||||||
|
case string:
|
||||||
|
tx = tx.Where("name = ?", id)
|
||||||
|
default:
|
||||||
|
return account, fmt.Errorf("invalid account id type")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := tx.
|
||||||
|
Preload("Profile").
|
||||||
|
Preload("Badges", func(db *gorm.DB) *gorm.DB {
|
||||||
|
return db.Order("badges.is_active DESC, badges.type DESC")
|
||||||
|
}).
|
||||||
|
First(&account).Error; err != nil {
|
||||||
|
return account, fmt.Errorf("requested user with id %d was not found", id)
|
||||||
|
}
|
||||||
|
|
||||||
|
groups, err := GetUserAccountGroup(account)
|
||||||
|
if err != nil {
|
||||||
|
return account, fmt.Errorf("unable to get account groups: %v", err)
|
||||||
|
}
|
||||||
|
for _, group := range groups {
|
||||||
|
for k, v := range group.PermNodes {
|
||||||
|
if _, ok := account.PermNodes[k]; !ok {
|
||||||
|
account.PermNodes[k] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
punishments, err := ListPunishments(account)
|
||||||
|
if err != nil {
|
||||||
|
return account, fmt.Errorf("unable to get account punishments: %v", err)
|
||||||
|
}
|
||||||
|
account.Punishments = punishments
|
||||||
|
for _, punishment := range punishments {
|
||||||
|
if punishment.Type == models.PunishmentTypeLimited && len(punishment.PermNodes) > 0 {
|
||||||
|
maps.Copy(account.PermNodes, punishment.PermNodes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CacheAccount(account)
|
||||||
|
|
||||||
|
return account, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetAccount(id uint) (models.Account, error) {
|
||||||
|
var account models.Account
|
||||||
|
if err := database.C.Where(models.Account{
|
||||||
|
BaseModel: models.BaseModel{ID: id},
|
||||||
|
}).First(&account).Error; err != nil {
|
||||||
|
return account, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return account, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetAccountList(id []uint) ([]models.Account, error) {
|
||||||
|
var accounts []models.Account
|
||||||
|
if err := database.C.Where("id IN ?", id).Find(&accounts).Error; err != nil {
|
||||||
|
return accounts, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return accounts, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetAccountWithName(alias string) (models.Account, error) {
|
||||||
|
var account models.Account
|
||||||
|
if err := database.C.Where(models.Account{
|
||||||
|
Name: alias,
|
||||||
|
}).First(&account).Error; err != nil {
|
||||||
|
return account, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return account, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func LookupAccount(probe string) (models.Account, error) {
|
||||||
|
var account models.Account
|
||||||
|
if err := database.C.Where(models.Account{Name: probe}).First(&account).Error; err == nil {
|
||||||
|
return account, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var contact models.AccountContact
|
||||||
|
if err := database.C.Where(models.AccountContact{Content: probe}).First(&contact).Error; err == nil {
|
||||||
|
if err := database.C.
|
||||||
|
Where(models.Account{
|
||||||
|
BaseModel: models.BaseModel{ID: contact.AccountID},
|
||||||
|
}).First(&account).Error; err == nil {
|
||||||
|
return account, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return account, fmt.Errorf("account was not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
func SearchAccount(probe string) ([]models.Account, error) {
|
||||||
|
probe = "%" + probe + "%"
|
||||||
|
var accounts []models.Account
|
||||||
|
if err := database.C.Where("name LIKE ? OR nick LIKE ?", probe, probe).Find(&accounts).Error; err != nil {
|
||||||
|
return accounts, err
|
||||||
|
}
|
||||||
|
return accounts, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreateAccount(name, nick, email, password, lang string) (models.Account, error) {
|
||||||
|
user := models.Account{
|
||||||
|
Name: name,
|
||||||
|
Nick: nick,
|
||||||
|
Profile: models.AccountProfile{
|
||||||
|
Experience: 100,
|
||||||
|
},
|
||||||
|
Factors: []models.AuthFactor{
|
||||||
|
{
|
||||||
|
Type: models.PasswordAuthFactor,
|
||||||
|
Secret: HashPassword(password),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Contacts: []models.AccountContact{
|
||||||
|
{
|
||||||
|
Type: models.EmailAccountContact,
|
||||||
|
Content: email,
|
||||||
|
IsPrimary: true,
|
||||||
|
VerifiedAt: nil,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Language: lang,
|
||||||
|
PermNodes: datatypes.JSONMap{},
|
||||||
|
ConfirmedAt: nil,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := database.C.Create(&user).Error; err != nil {
|
||||||
|
return user, err
|
||||||
|
}
|
||||||
|
// Only gave user permission group after they confiremd the registeration
|
||||||
|
|
||||||
|
if tk, err := NewMagicToken(models.ConfirmMagicToken, &user, nil); err != nil {
|
||||||
|
return user, err
|
||||||
|
} else if err := NotifyMagicToken(tk); err != nil {
|
||||||
|
return user, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return user, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConfirmAccount(code string) error {
|
||||||
|
token, err := ValidateMagicToken(code, models.ConfirmMagicToken)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
} else if token.AccountID == nil {
|
||||||
|
return fmt.Errorf("magic token didn't assign a valid account")
|
||||||
|
}
|
||||||
|
|
||||||
|
var user models.Account
|
||||||
|
if err := database.C.Where(&models.Account{
|
||||||
|
BaseModel: models.BaseModel{ID: *token.AccountID},
|
||||||
|
}).First(&user).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = ForceConfirmAccount(user); err != nil {
|
||||||
|
return err
|
||||||
|
} else {
|
||||||
|
database.C.Delete(&token)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ForceConfirmAccount(user models.Account) error {
|
||||||
|
user.ConfirmedAt = lo.ToPtr(time.Now())
|
||||||
|
|
||||||
|
if viper.GetInt("default_user_group") > 0 {
|
||||||
|
database.C.Create(&models.AccountGroupMember{
|
||||||
|
AccountID: user.ID,
|
||||||
|
GroupID: uint(viper.GetInt("default_user_group")),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = database.C.Model(&models.AccountContact{}).Where("account_id = ?", user.ID).Updates(&models.AccountContact{
|
||||||
|
VerifiedAt: lo.ToPtr(time.Now()),
|
||||||
|
})
|
||||||
|
|
||||||
|
if err := database.C.Save(&user).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
InvalidUserAuthCache(user.ID)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func CheckAbleToDeleteAccount(user models.Account) error {
|
||||||
|
if user.AutomatedID != nil {
|
||||||
|
return fmt.Errorf("bot cannot request delete account, head to developer portal and dispose bot")
|
||||||
|
}
|
||||||
|
|
||||||
|
var count int64
|
||||||
|
if err := database.C.
|
||||||
|
Where("account_id = ?", user.ID).
|
||||||
|
Where("expired_at < ?", time.Now()).
|
||||||
|
Where("type = ?", models.DeleteAccountMagicToken).
|
||||||
|
Model(&models.MagicToken{}).
|
||||||
|
Count(&count).Error; err != nil {
|
||||||
|
return fmt.Errorf("unable to check delete account ability: %v", err)
|
||||||
|
} else if count > 0 {
|
||||||
|
return fmt.Errorf("you requested delete account recently")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func RequestDeleteAccount(user models.Account) error {
|
||||||
|
if tk, err := NewMagicToken(
|
||||||
|
models.DeleteAccountMagicToken,
|
||||||
|
&user,
|
||||||
|
lo.ToPtr(time.Now().Add(24*time.Hour)),
|
||||||
|
); err != nil {
|
||||||
|
return err
|
||||||
|
} else if err := NotifyMagicToken(tk); err != nil {
|
||||||
|
log.Error().
|
||||||
|
Err(err).
|
||||||
|
Str("code", tk.Code).
|
||||||
|
Uint("user", user.ID).
|
||||||
|
Msg("Failed to notify delete account magic token...")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConfirmDeleteAccount(code string) error {
|
||||||
|
token, err := ValidateMagicToken(code, models.DeleteAccountMagicToken)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
} else if token.AccountID == nil {
|
||||||
|
return fmt.Errorf("magic token didn't assign a valid account")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := DeleteAccount(*token.AccountID); err != nil {
|
||||||
|
return err
|
||||||
|
} else {
|
||||||
|
database.C.Delete(&token)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func CheckAbleToResetPassword(user models.Account) error {
|
||||||
|
var count int64
|
||||||
|
if err := database.C.
|
||||||
|
Where("account_id = ?", user.ID).
|
||||||
|
Where("expired_at < ?", time.Now()).
|
||||||
|
Where("type = ?", models.ResetPasswordMagicToken).
|
||||||
|
Model(&models.MagicToken{}).
|
||||||
|
Count(&count).Error; err != nil {
|
||||||
|
return fmt.Errorf("unable to check reset password ability: %v", err)
|
||||||
|
} else if count > 0 {
|
||||||
|
return fmt.Errorf("you requested reset password recently")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func RequestResetPassword(user models.Account) error {
|
||||||
|
if tk, err := NewMagicToken(
|
||||||
|
models.ResetPasswordMagicToken,
|
||||||
|
&user,
|
||||||
|
lo.ToPtr(time.Now().Add(24*time.Hour)),
|
||||||
|
); err != nil {
|
||||||
|
return err
|
||||||
|
} else if err := NotifyMagicToken(tk); err != nil {
|
||||||
|
log.Error().
|
||||||
|
Err(err).
|
||||||
|
Str("code", tk.Code).
|
||||||
|
Uint("user", user.ID).
|
||||||
|
Msg("Failed to notify password reset magic token...")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConfirmResetPassword(code, newPassword string) error {
|
||||||
|
token, err := ValidateMagicToken(code, models.ResetPasswordMagicToken)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
} else if token.AccountID == nil {
|
||||||
|
return fmt.Errorf("magic token didn't assign a valid account")
|
||||||
|
}
|
||||||
|
|
||||||
|
factor, err := GetPasswordTypeFactor(*token.AccountID)
|
||||||
|
if err != nil {
|
||||||
|
factor = models.AuthFactor{
|
||||||
|
Type: models.PasswordAuthFactor,
|
||||||
|
Secret: HashPassword(newPassword),
|
||||||
|
AccountID: *token.AccountID,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
factor.Secret = HashPassword(newPassword)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = database.C.Save(&factor).Error; err != nil {
|
||||||
|
return err
|
||||||
|
} else {
|
||||||
|
database.C.Delete(&token)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeleteAccount(id uint) error {
|
||||||
|
tx := database.C.Begin()
|
||||||
|
|
||||||
|
if err := tx.Delete(&models.AuthTicket{}, "account_id = ?", id).Error; err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := tx.Select(clause.Associations).Delete(&models.Account{}, "id = ?", id).Error; err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := tx.Commit().Error; err != nil {
|
||||||
|
return err
|
||||||
|
} else {
|
||||||
|
InvalidUserAuthCache(id)
|
||||||
|
conn := gap.Nx.GetNexusGrpcConn()
|
||||||
|
_, _ = proto.NewDirectoryServiceClient(conn).BroadcastEvent(context.Background(), &proto.EventInfo{
|
||||||
|
Event: "deletion",
|
||||||
|
Data: nex.EncodeMap(map[string]any{
|
||||||
|
"type": "account",
|
||||||
|
"id": id,
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func RecycleUnConfirmAccount() {
|
||||||
|
deadline := time.Now().Add(-24 * time.Hour)
|
||||||
|
|
||||||
|
var hitList []models.Account
|
||||||
|
if err := database.C.Where("confirmed_at IS NULL AND created_at <= ?", deadline).Find(&hitList).Error; err != nil {
|
||||||
|
log.Error().Err(err).Msg("An error occurred while recycling accounts...")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(hitList) > 0 {
|
||||||
|
log.Info().Int("count", len(hitList)).Msg("Going to recycle those un-confirmed accounts...")
|
||||||
|
for _, entry := range hitList {
|
||||||
|
if err := DeleteAccount(entry.ID); err != nil {
|
||||||
|
log.Error().Err(err).Msg("An error occurred while recycling accounts...")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetAccountLastSeen(uid uint) error {
|
||||||
|
var profile models.AccountProfile
|
||||||
|
if err := database.C.Where("account_id = ?", uid).First(&profile).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
profile.LastSeenAt = lo.ToPtr(time.Now())
|
||||||
|
|
||||||
|
return database.C.Save(&profile).Error
|
||||||
|
}
|
105
pkg/internal/services/auth.go
Normal file
105
pkg/internal/services/auth.go
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
package services
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"git.solsynth.dev/hypernet/nexus/pkg/nex/cachekit"
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/authkit/models"
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/internal/database"
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/internal/gap"
|
||||||
|
|
||||||
|
jsoniter "github.com/json-iterator/go"
|
||||||
|
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Authenticate(sessionId uint) (ctx models.AuthTicket, perms map[string]any, err error) {
|
||||||
|
if ctx, err = GetAuthContext(sessionId); err == nil {
|
||||||
|
var heldPerms map[string]any
|
||||||
|
rawHeldPerms, _ := jsoniter.Marshal(ctx.Account.PermNodes)
|
||||||
|
_ = jsoniter.Unmarshal(rawHeldPerms, &heldPerms)
|
||||||
|
|
||||||
|
perms = FilterPermNodes(heldPerms, ctx.Claims)
|
||||||
|
ctx.Account.PermNodes = perms
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = fiber.NewError(fiber.StatusUnauthorized, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func KgAuthContextCache(sessionId uint) string {
|
||||||
|
return cachekit.FKey("auth-context", sessionId)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetAuthContext(sessionId uint) (models.AuthTicket, error) {
|
||||||
|
var err error
|
||||||
|
var ctx models.AuthTicket
|
||||||
|
|
||||||
|
key := KgAuthContextCache(sessionId)
|
||||||
|
if val, err := cachekit.Get[models.AuthTicket](gap.Ca, key); err == nil {
|
||||||
|
ctx = val
|
||||||
|
} else {
|
||||||
|
log.Error().Err(err).Msg("Unable to get auth context cache")
|
||||||
|
ctx, err = CacheAuthContext(sessionId)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msg("Unable to cache auth context")
|
||||||
|
} else {
|
||||||
|
log.Debug().Uint("session", sessionId).Msg("Created a new auth context cache")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ctx, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func CacheAuthContext(sessionId uint) (models.AuthTicket, error) {
|
||||||
|
// Query data from primary database
|
||||||
|
var ticket models.AuthTicket
|
||||||
|
if err := database.C.
|
||||||
|
Where("id = ?", sessionId).
|
||||||
|
First(&ticket).Error; err != nil {
|
||||||
|
return ticket, fmt.Errorf("invalid auth ticket: %v", err)
|
||||||
|
} else if err := ticket.IsAvailable(); err != nil {
|
||||||
|
return ticket, fmt.Errorf("unavailable auth ticket: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
user, err := GetAccount(ticket.AccountID)
|
||||||
|
if err != nil {
|
||||||
|
return ticket, fmt.Errorf("invalid account: %v", err)
|
||||||
|
}
|
||||||
|
groups, err := GetUserAccountGroup(user)
|
||||||
|
if err != nil {
|
||||||
|
return ticket, fmt.Errorf("unable to get account groups: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, group := range groups {
|
||||||
|
for k, v := range group.PermNodes {
|
||||||
|
if _, ok := user.PermNodes[k]; !ok {
|
||||||
|
user.PermNodes[k] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ticket.Account = user
|
||||||
|
|
||||||
|
// Put the data into the cache
|
||||||
|
key := KgAuthContextCache(sessionId)
|
||||||
|
err = cachekit.Set[models.AuthTicket](
|
||||||
|
gap.Ca,
|
||||||
|
key,
|
||||||
|
ticket,
|
||||||
|
time.Minute*10,
|
||||||
|
"auth-context",
|
||||||
|
fmt.Sprintf("user#%d", user.ID),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msg("Unable to cache auth context...")
|
||||||
|
}
|
||||||
|
|
||||||
|
return ticket, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func InvalidUserAuthCache(uid uint) {
|
||||||
|
cachekit.DeleteByTags(gap.Ca, "auth-context", fmt.Sprintf("user#%d", uid))
|
||||||
|
}
|
35
pkg/internal/services/badges.go
Normal file
35
pkg/internal/services/badges.go
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
package services
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/authkit/models"
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/internal/database"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GrantBadge(user models.Account, badge models.Badge) error {
|
||||||
|
badge.AccountID = user.ID
|
||||||
|
return database.C.Save(badge).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func RevokeBadge(badge models.Badge) error {
|
||||||
|
return database.C.Delete(&badge).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func ActiveBadge(badge models.Badge) error {
|
||||||
|
accountId := badge.AccountID
|
||||||
|
tx := database.C.Begin()
|
||||||
|
|
||||||
|
if err := tx.Model(&models.Badge{}).Where("account_id = ?", accountId).Update("is_active", false).Error; err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := tx.Model(&models.Badge{}).Where("id = ?", badge.ID).Update("is_active", true).Error; err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := tx.Commit().Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
56
pkg/internal/services/bot_token.go
Normal file
56
pkg/internal/services/bot_token.go
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
package services
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/authkit/models"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/internal/database"
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/samber/lo"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewApiKey(user models.Account, key models.ApiKey, ip, ua string, claims []string) (models.ApiKey, error) {
|
||||||
|
key.Account = user
|
||||||
|
key.AccountID = user.ID
|
||||||
|
|
||||||
|
var expiredAt *time.Time
|
||||||
|
if key.Lifecycle != nil {
|
||||||
|
expiredAt = lo.ToPtr(time.Now().Add(time.Duration(*key.Lifecycle) * time.Second))
|
||||||
|
}
|
||||||
|
|
||||||
|
key.Ticket = models.AuthTicket{
|
||||||
|
IpAddress: ip,
|
||||||
|
UserAgent: ua,
|
||||||
|
StepRemain: 0,
|
||||||
|
Claims: claims,
|
||||||
|
Audiences: []string{InternalTokenAudience},
|
||||||
|
GrantToken: lo.ToPtr(uuid.NewString()),
|
||||||
|
AccessToken: lo.ToPtr(uuid.NewString()),
|
||||||
|
RefreshToken: lo.ToPtr(uuid.NewString()),
|
||||||
|
AvailableAt: lo.ToPtr(time.Now()),
|
||||||
|
ExpiredAt: expiredAt,
|
||||||
|
Account: user,
|
||||||
|
AccountID: user.ID,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := database.C.Save(&key).Error; err != nil {
|
||||||
|
return key, err
|
||||||
|
}
|
||||||
|
return key, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func RollApiKey(key models.ApiKey) (models.ApiKey, error) {
|
||||||
|
var ticket models.AuthTicket
|
||||||
|
if err := database.C.Where("id = ?", key.TicketID).First(&ticket).Error; err != nil {
|
||||||
|
return key, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ticket, err := RotateTicket(ticket, true)
|
||||||
|
if err != nil {
|
||||||
|
return key, err
|
||||||
|
} else {
|
||||||
|
key.Ticket = ticket
|
||||||
|
}
|
||||||
|
|
||||||
|
return key, nil
|
||||||
|
}
|
24
pkg/internal/services/bots.go
Normal file
24
pkg/internal/services/bots.go
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package services
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/authkit/models"
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/internal/database"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetBotCount(user models.Account) (int64, error) {
|
||||||
|
var count int64
|
||||||
|
if err := database.C.Where("automated_id = ?", user.ID).Count(&count).Error; err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return count, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewBot(user models.Account, bot models.Account) (models.Account, error) {
|
||||||
|
bot.AutomatedBy = &user
|
||||||
|
bot.AutomatedID = &user.ID
|
||||||
|
|
||||||
|
if err := database.C.Save(&bot).Error; err != nil {
|
||||||
|
return bot, err
|
||||||
|
}
|
||||||
|
return bot, nil
|
||||||
|
}
|
139
pkg/internal/services/check_in.go
Normal file
139
pkg/internal/services/check_in.go
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
package services
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
"math/rand"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/authkit/models"
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/internal/database"
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/internal/gap"
|
||||||
|
"git.solsynth.dev/hypernet/wallet/pkg/proto"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
"github.com/samber/lo"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
func CheckCanCheckIn(user models.Account) error {
|
||||||
|
var record models.CheckInRecord
|
||||||
|
if err := database.C.Where("account_id = ? AND created_at::date = CURRENT_DATE", user.ID).First(&record).Error; err != nil {
|
||||||
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return fmt.Errorf("unable get check in record: %v", err)
|
||||||
|
}
|
||||||
|
return fmt.Errorf("today's check in record exists")
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetCheckInStreak(user models.Account) (int64, error) {
|
||||||
|
var streaks int64
|
||||||
|
if err := database.C.Raw(`WITH dates AS (
|
||||||
|
SELECT DISTINCT created_at::DATE AS created_date
|
||||||
|
FROM check_in_records
|
||||||
|
WHERE created_at::DATE <= CURRENT_DATE
|
||||||
|
AND account_id = ?
|
||||||
|
),
|
||||||
|
streak AS (
|
||||||
|
SELECT created_date,
|
||||||
|
created_date - INTERVAL '1 day' * (ROW_NUMBER() OVER (ORDER BY created_date)) AS grp
|
||||||
|
FROM dates
|
||||||
|
),
|
||||||
|
grouped_streaks AS (
|
||||||
|
SELECT grp, COUNT(*) AS streak_length, MAX(created_date) AS last_date
|
||||||
|
FROM streak
|
||||||
|
GROUP BY grp
|
||||||
|
),
|
||||||
|
last_streak AS (
|
||||||
|
SELECT streak_length
|
||||||
|
FROM grouped_streaks
|
||||||
|
WHERE last_date = (SELECT MAX(created_date) FROM dates)
|
||||||
|
)
|
||||||
|
SELECT COALESCE(streak_length, 0) FROM last_streak;`, user.ID).Scan(&streaks).Error; err != nil {
|
||||||
|
return streaks, err
|
||||||
|
}
|
||||||
|
return streaks, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetTodayCheckIn(user models.Account) (models.CheckInRecord, error) {
|
||||||
|
var record models.CheckInRecord
|
||||||
|
if err := database.C.Where("account_id = ? AND created_at::date = CURRENT_DATE", user.ID).First(&record).Error; err != nil {
|
||||||
|
return record, fmt.Errorf("unable get check in record: %v", err)
|
||||||
|
}
|
||||||
|
return record, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const CheckInResultModifiersLength = 4
|
||||||
|
|
||||||
|
func CheckIn(user models.Account) (models.CheckInRecord, error) {
|
||||||
|
var record models.CheckInRecord
|
||||||
|
if err := CheckCanCheckIn(user); err != nil {
|
||||||
|
return record, fmt.Errorf("today already signed")
|
||||||
|
}
|
||||||
|
|
||||||
|
tier := rand.Intn(5)
|
||||||
|
streak, _ := GetCheckInStreak(user)
|
||||||
|
|
||||||
|
expMin := 100
|
||||||
|
exp := expMin + int(math.Max(float64(streak)*5, 10*5))
|
||||||
|
|
||||||
|
coinMax := 10.0 * float64(tier+1)
|
||||||
|
coinMin := 10.0
|
||||||
|
rawCoins := coinMax + rand.Float64()*(coinMax-coinMin) + math.Max(float64(streak)*0.5, float64(100*0.5))
|
||||||
|
|
||||||
|
record = models.CheckInRecord{
|
||||||
|
ResultTier: tier,
|
||||||
|
ResultExperience: exp,
|
||||||
|
ResultCoin: float64(int(rawCoins*100)) / 100,
|
||||||
|
CurrentStreak: int(streak),
|
||||||
|
AccountID: user.ID,
|
||||||
|
}
|
||||||
|
|
||||||
|
modifiers := make([]int, CheckInResultModifiersLength)
|
||||||
|
for i := 0; i < CheckInResultModifiersLength; i++ {
|
||||||
|
modifiers[i] = rand.Intn(1025) // from 0 to 1024 as the comment said
|
||||||
|
}
|
||||||
|
record.ResultModifiers = modifiers
|
||||||
|
|
||||||
|
tx := database.C.Begin()
|
||||||
|
|
||||||
|
var profile models.AccountProfile
|
||||||
|
if err := database.C.Where("account_id = ?", user.ID).First(&profile).Error; err != nil {
|
||||||
|
return record, fmt.Errorf("unable get account profile: %v", err)
|
||||||
|
} else {
|
||||||
|
profile.Experience += uint64(record.ResultExperience)
|
||||||
|
if err := tx.Save(&profile).Error; err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return record, fmt.Errorf("unable update account profile: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
conn, err := gap.Nx.GetClientGrpcConn("wa")
|
||||||
|
if err != nil {
|
||||||
|
log.Warn().Err(err).Msg("Unable to connect with wallet to send daily rewards")
|
||||||
|
record.ResultCoin = 0
|
||||||
|
}
|
||||||
|
wc := proto.NewPaymentServiceClient(conn)
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
|
||||||
|
defer cancel()
|
||||||
|
_, err = wc.MakeTransactionWithAccount(ctx, &proto.MakeTransactionWithAccountRequest{
|
||||||
|
PayeeAccountId: lo.ToPtr(uint64(user.ID)),
|
||||||
|
Amount: record.ResultCoin,
|
||||||
|
Currency: "normal",
|
||||||
|
Remark: "Daily Check-In Rewards",
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Warn().Err(err).Msg("Unable to make transaction with account to send daily rewards")
|
||||||
|
record.ResultCoin = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := tx.Save(&record).Error; err != nil {
|
||||||
|
return record, fmt.Errorf("unable do check in: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
tx.Commit()
|
||||||
|
|
||||||
|
return record, nil
|
||||||
|
}
|
22
pkg/internal/services/cleaner.go
Normal file
22
pkg/internal/services/cleaner.go
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package services
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/authkit/models"
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/internal/database"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
func DoAutoDatabaseCleanup() {
|
||||||
|
log.Debug().Msg("Now cleaning up entire database...")
|
||||||
|
|
||||||
|
var count int64
|
||||||
|
|
||||||
|
deadline := time.Now().Add(-30 * 24 * time.Hour)
|
||||||
|
seenDeadline := time.Now().Add(-7 * 24 * time.Hour)
|
||||||
|
tx := database.C.Unscoped().Where("created_at <= ? OR read_at <= ?", deadline, seenDeadline).Delete(&models.Notification{})
|
||||||
|
count += tx.RowsAffected
|
||||||
|
|
||||||
|
log.Debug().Int64("affected", count).Msg("Clean up entire database accomplished.")
|
||||||
|
}
|
@ -2,9 +2,9 @@ package services
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/authkit/models"
|
||||||
|
|
||||||
"git.solsynth.dev/hydrogen/passport/pkg/database"
|
"git.solsynth.dev/hypernet/passport/pkg/internal/database"
|
||||||
"git.solsynth.dev/hydrogen/passport/pkg/models"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetThirdClient(id string) (models.ThirdClient, error) {
|
func GetThirdClient(id string) (models.ThirdClient, error) {
|
||||||
@ -18,6 +18,18 @@ func GetThirdClient(id string) (models.ThirdClient, error) {
|
|||||||
return client, nil
|
return client, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetThirdClientWithUser(id string, userId uint) (models.ThirdClient, error) {
|
||||||
|
var client models.ThirdClient
|
||||||
|
if err := database.C.Where(&models.ThirdClient{
|
||||||
|
Alias: id,
|
||||||
|
AccountID: &userId,
|
||||||
|
}).First(&client).Error; err != nil {
|
||||||
|
return client, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return client, nil
|
||||||
|
}
|
||||||
|
|
||||||
func GetThirdClientWithSecret(id, secret string) (models.ThirdClient, error) {
|
func GetThirdClientWithSecret(id, secret string) (models.ThirdClient, error) {
|
||||||
client, err := GetThirdClient(id)
|
client, err := GetThirdClient(id)
|
||||||
if err != nil {
|
if err != nil {
|
88
pkg/internal/services/events.go
Normal file
88
pkg/internal/services/events.go
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
package services
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/authkit/models"
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/internal/database"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
"github.com/samber/lo"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
writeEventQueue []models.ActionEvent
|
||||||
|
writeAuditQueue []models.AuditRecord
|
||||||
|
)
|
||||||
|
|
||||||
|
// AddEvent to keep operation logs by user themselves clear to query
|
||||||
|
func AddEvent(user uint, event string, meta map[string]any, ip, ua string) {
|
||||||
|
var location *string
|
||||||
|
var coordinateX, coordinateY *float64
|
||||||
|
netIp := net.ParseIP(ip)
|
||||||
|
record, err := database.Gc.City(netIp)
|
||||||
|
if err == nil {
|
||||||
|
var locationNames []string
|
||||||
|
locationNames = append(locationNames, record.City.Names["en"])
|
||||||
|
for _, subs := range record.Subdivisions {
|
||||||
|
locationNames = append(locationNames, subs.Names["en"])
|
||||||
|
}
|
||||||
|
location = lo.ToPtr(strings.Join(locationNames, ", "))
|
||||||
|
coordinateX = &record.Location.Latitude
|
||||||
|
coordinateY = &record.Location.Longitude
|
||||||
|
}
|
||||||
|
writeEventQueue = append(writeEventQueue, models.ActionEvent{
|
||||||
|
Type: event,
|
||||||
|
Metadata: meta,
|
||||||
|
IpAddress: ip,
|
||||||
|
UserAgent: ua,
|
||||||
|
Location: location,
|
||||||
|
CoordinateX: coordinateX,
|
||||||
|
CoordinateY: coordinateY,
|
||||||
|
AccountID: user,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddAuditRecord to keep logs to make administrators' operations clear to query
|
||||||
|
func AddAuditRecord(operator models.Account, act, ip, ua string, metadata map[string]any) {
|
||||||
|
var location *string
|
||||||
|
var coordinateX, coordinateY *float64
|
||||||
|
netIp := net.ParseIP(ip)
|
||||||
|
record, err := database.Gc.City(netIp)
|
||||||
|
if err == nil {
|
||||||
|
var locationNames []string
|
||||||
|
locationNames = append(locationNames, record.City.Names["en"])
|
||||||
|
for _, subs := range record.Subdivisions {
|
||||||
|
locationNames = append(locationNames, subs.Names["en"])
|
||||||
|
}
|
||||||
|
location = lo.ToPtr(strings.Join(locationNames, ", "))
|
||||||
|
coordinateX = &record.Location.Latitude
|
||||||
|
coordinateY = &record.Location.Longitude
|
||||||
|
}
|
||||||
|
writeAuditQueue = append(writeAuditQueue, models.AuditRecord{
|
||||||
|
Action: act,
|
||||||
|
Metadata: metadata,
|
||||||
|
IpAddress: ip,
|
||||||
|
UserAgent: ua,
|
||||||
|
Location: location,
|
||||||
|
CoordinateX: coordinateX,
|
||||||
|
CoordinateY: coordinateY,
|
||||||
|
AccountID: operator.ID,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// SaveEventChanges runs every 60 seconds to save events / audits changes into the database
|
||||||
|
func SaveEventChanges() {
|
||||||
|
if len(writeEventQueue) > 0 {
|
||||||
|
count := len(writeEventQueue)
|
||||||
|
database.C.CreateInBatches(writeEventQueue, min(count, 1000))
|
||||||
|
log.Info().Int("count", count).Msg("Saved action events changes into database...")
|
||||||
|
writeEventQueue = nil
|
||||||
|
}
|
||||||
|
if len(writeAuditQueue) > 0 {
|
||||||
|
count := len(writeAuditQueue)
|
||||||
|
database.C.CreateInBatches(writeAuditQueue, min(count, 1000))
|
||||||
|
log.Info().Int("count", count).Msg("Saved audit records changes into database...")
|
||||||
|
writeAuditQueue = nil
|
||||||
|
}
|
||||||
|
}
|
170
pkg/internal/services/factors.go
Normal file
170
pkg/internal/services/factors.go
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
package services
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"git.solsynth.dev/hypernet/nexus/pkg/nex/cachekit"
|
||||||
|
"git.solsynth.dev/hypernet/nexus/pkg/nex/localize"
|
||||||
|
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/authkit/models"
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/internal/database"
|
||||||
|
"git.solsynth.dev/hypernet/passport/pkg/internal/gap"
|
||||||
|
"git.solsynth.dev/hypernet/pusher/pkg/pushkit"
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/pquerna/otp/totp"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
"github.com/samber/lo"
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetPasswordTypeFactor(userId uint) (models.AuthFactor, error) {
|
||||||
|
var factor models.AuthFactor
|
||||||
|
err := database.C.Where(models.AuthFactor{
|
||||||
|
Type: models.PasswordAuthFactor,
|
||||||
|
AccountID: userId,
|
||||||
|
}).First(&factor).Error
|
||||||
|
|
||||||
|
return factor, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetFactor(id uint) (models.AuthFactor, error) {
|
||||||
|
var factor models.AuthFactor
|
||||||
|
err := database.C.Where(models.AuthFactor{
|
||||||
|
BaseModel: models.BaseModel{ID: id},
|
||||||
|
}).First(&factor).Error
|
||||||
|
|
||||||
|
return factor, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func ListUserFactor(userId uint) ([]models.AuthFactor, error) {
|
||||||
|
var factors []models.AuthFactor
|
||||||
|
err := database.C.Where(models.AuthFactor{
|
||||||
|
AccountID: userId,
|
||||||
|
}).Find(&factors).Error
|
||||||
|
|
||||||
|
return factors, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func CountUserFactor(userId uint) int64 {
|
||||||
|
var count int64
|
||||||
|
database.C.Where(models.AuthFactor{
|
||||||
|
AccountID: userId,
|
||||||
|
}).Model(&models.AuthFactor{}).Count(&count)
|
||||||
|
|
||||||
|
return count
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetFactorCode(factor models.AuthFactor, ip string) (bool, error) {
|
||||||
|
switch factor.Type {
|
||||||
|
case models.InAppNotifyFactor:
|
||||||
|
var user models.Account
|
||||||
|
if err := database.C.Where(&models.Account{
|
||||||
|
BaseModel: models.BaseModel{ID: factor.AccountID},
|
||||||
|
}).First(&user).Error; err != nil {
|
||||||
|
return true, err
|
||||||
|
}
|
||||||
|
|
||||||
|
secret := uuid.NewString()[:6]
|
||||||
|
|
||||||
|
identifier := fmt.Sprintf("%s#%d", gap.FactorOtpPrefix, factor.ID)
|
||||||
|
err := cachekit.Set(gap.Ca, identifier, secret, time.Minute*30, fmt.Sprintf("user#%d", factor.AccountID))
|
||||||
|
if err != nil {
|
||||||
|
return true, fmt.Errorf("error during creating otp: %v", err)
|
||||||
|
} else {
|
||||||
|
log.Info().Uint("factor", factor.ID).Str("secret", secret).Msg("Created one-time-password in cache...")
|
||||||
|
}
|
||||||
|
|
||||||
|
err = NewNotification(models.Notification{
|
||||||
|
Topic: "passport.security.otp",
|
||||||
|
Title: localize.L.GetLocalizedString("subjectLoginOneTimePassword", user.Language),
|
||||||
|
Body: fmt.Sprintf(localize.L.GetLocalizedString("shortBodyLoginOneTimePassword", user.Language), secret),
|
||||||
|
Account: user,
|
||||||
|
AccountID: user.ID,
|
||||||
|
Metadata: map[string]any{"secret": secret},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Warn().Err(err).Uint("factor", factor.ID).Msg("Failed to delivery one-time-password via notify...")
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
return true, nil
|
||||||
|
case models.EmailPasswordFactor:
|
||||||
|
var user models.Account
|
||||||
|
if err := database.C.Where(&models.Account{
|
||||||
|
BaseModel: models.BaseModel{ID: factor.AccountID},
|
||||||
|
}).Preload("Contacts").First(&user).Error; err != nil {
|
||||||
|
return true, err
|
||||||
|
}
|
||||||
|
|
||||||
|
secret := uuid.NewString()[:6]
|
||||||
|
|
||||||
|
identifier := fmt.Sprintf("%s#%d", gap.FactorOtpPrefix, factor.ID)
|
||||||
|
err := cachekit.Set(gap.Ca, identifier, secret, time.Minute*30, fmt.Sprintf("user#%d", factor.AccountID))
|
||||||
|
if err != nil {
|
||||||
|
return true, fmt.Errorf("error during creating otp: %v", err)
|
||||||
|
} else {
|
||||||
|
log.Info().Uint("factor", factor.ID).Str("secret", secret).Msg("Created one-time-password in cache...")
|
||||||
|
}
|
||||||
|
|
||||||
|
subject := fmt.Sprintf("[%s] %s", viper.GetString("name"), localize.L.GetLocalizedString("subjectLoginOneTimePassword", user.Language))
|
||||||
|
|
||||||
|
content := localize.L.RenderLocalizedTemplateHTML("email-otp.tmpl", user.Language, map[string]any{
|
||||||
|
"Code": secret,
|
||||||
|
"User": user,
|
||||||
|
"IP": ip,
|
||||||
|
"Date": time.Now().Format(time.DateTime),
|
||||||
|
})
|
||||||
|
|
||||||
|
err = gap.Px.PushEmail(pushkit.EmailDeliverRequest{
|
||||||
|
To: user.GetPrimaryEmail().Content,
|
||||||
|
Email: pushkit.EmailData{
|
||||||
|
Subject: subject,
|
||||||
|
HTML: &content,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Warn().Err(err).Uint("factor", factor.ID).Msg("Failed to delivery one-time-password via mail...")
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
return true, nil
|
||||||
|
default:
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func CheckFactor(factor models.AuthFactor, code string) error {
|
||||||
|
switch factor.Type {
|
||||||
|
case models.PasswordAuthFactor:
|
||||||
|
return lo.Ternary(
|
||||||
|
VerifyPassword(code, factor.Secret),
|
||||||
|
nil,
|
||||||
|
fmt.Errorf("invalid password"),
|
||||||
|
)
|
||||||
|
case models.TimeOtpFactor:
|
||||||
|
return lo.Ternary(
|
||||||
|
totp.Validate(code, factor.Secret),
|
||||||
|
nil,
|
||||||
|
fmt.Errorf("invalid verification code"),
|
||||||
|
)
|
||||||
|
case models.InAppNotifyFactor:
|
||||||
|
case models.EmailPasswordFactor:
|
||||||
|
identifier := fmt.Sprintf("%s#%d", gap.FactorOtpPrefix, factor.ID)
|
||||||
|
val, err := cachekit.Get[string](gap.Ca, identifier)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msg("Error fetching message when validating factor code...")
|
||||||
|
return fmt.Errorf("one-time-password not found or expired")
|
||||||
|
}
|
||||||
|
|
||||||
|
if !strings.EqualFold(code, val) {
|
||||||
|
return fmt.Errorf("invalid verification code")
|
||||||
|
}
|
||||||
|
log.Info().Uint("factor", factor.ID).Str("secret", code).Msg("Verified one-time-password...")
|
||||||
|
if err := cachekit.Delete(gap.Ca, identifier); err != nil {
|
||||||
|
log.Error().Err(err).Msg("Error deleting the otp from cache...")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user