Sign up & Sign in

This commit is contained in:
LittleSheep 2024-04-20 22:50:09 +08:00
parent 87cccefddb
commit e79441dbc5
26 changed files with 706 additions and 463 deletions

View File

@ -5,5 +5,6 @@
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="animate.css" level="application" />
</component>
</module>

View File

@ -10,8 +10,11 @@
<user-name>postgres</user-name>
<schema-mapping>
<introspection-scope>
<node kind="database" qname="@">
<node kind="schema" qname="@" />
<node negative="1">
<node kind="database" qname="@">
<node kind="schema" qname="@" />
</node>
<node kind="database" qname="hy_passport" />
</node>
</introspection-scope>
</schema-mapping>

File diff suppressed because it is too large Load Diff

View File

@ -1,2 +1,2 @@
#n:public
!<md> [6258, 0, null, null, -2147483648, -2147483648]
!<md> [6267, 0, null, null, -2147483648, -2147483648]

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JavaScriptLibraryMappings">
<file url="PROJECT" libraries="{animate.css}" />
</component>
</project>

View File

@ -5,11 +5,31 @@
</component>
<component name="ChangeListManager">
<list default="true" id="3fefb2c4-b6f9-466b-a523-53352e8d6f95" name="更改" comment=":sparkles: New ticket ways">
<change afterPath="$PROJECT_DIR$/pkg/server/ui/signin.go" afterDir="false" />
<change afterPath="$PROJECT_DIR$/pkg/server/ui/signup.go" afterDir="false" />
<change afterPath="$PROJECT_DIR$/pkg/views/signup.gohtml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/Passport.iml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/Passport.iml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/dataSources.local.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/dataSources.local.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/dataSources/74bcf3ef-a2b9-435b-b9e5-f32902a33b25.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/dataSources/74bcf3ef-a2b9-435b-b9e5-f32902a33b25.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/dataSources/74bcf3ef-a2b9-435b-b9e5-f32902a33b25/storage_v2/_src_/database/hy_passport.gNOKQQ/schema/public.abK9xQ.meta" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/dataSources/74bcf3ef-a2b9-435b-b9e5-f32902a33b25/storage_v2/_src_/database/hy_passport.gNOKQQ/schema/public.abK9xQ.meta" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/pkg/server/oauth_api.go" beforeDir="false" afterPath="$PROJECT_DIR$/pkg/server/oauth_api.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/pkg/server/security_api.go" beforeDir="false" afterPath="$PROJECT_DIR$/pkg/server/security_api.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/pkg/server/startup.go" beforeDir="false" afterPath="$PROJECT_DIR$/pkg/server/startup.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/go.mod" beforeDir="false" afterPath="$PROJECT_DIR$/go.mod" afterDir="false" />
<change beforePath="$PROJECT_DIR$/go.sum" beforeDir="false" afterPath="$PROJECT_DIR$/go.sum" afterDir="false" />
<change beforePath="$PROJECT_DIR$/pkg/i18n/locale.en.json" beforeDir="false" afterPath="$PROJECT_DIR$/pkg/i18n/locale.en.json" afterDir="false" />
<change beforePath="$PROJECT_DIR$/pkg/i18n/locale.zh.json" beforeDir="false" afterPath="$PROJECT_DIR$/pkg/i18n/locale.zh.json" afterDir="false" />
<change beforePath="$PROJECT_DIR$/pkg/server/accounts_api.go" beforeDir="false" afterPath="$PROJECT_DIR$/pkg/server/accounts_api.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/pkg/server/auth_api.go" beforeDir="false" afterPath="$PROJECT_DIR$/pkg/server/auth_api.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/pkg/server/friendships_api.go" beforeDir="false" afterPath="$PROJECT_DIR$/pkg/server/friendships_api.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/server/notify_api.go" beforeDir="false" afterPath="$PROJECT_DIR$/pkg/server/notify_api.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/pkg/server/page_api.go" beforeDir="false" afterPath="$PROJECT_DIR$/pkg/server/page_api.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/pkg/server/ui/auth.go" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/pkg/server/ui/index.go" beforeDir="false" afterPath="$PROJECT_DIR$/pkg/server/ui/index.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/pkg/server/utils.go" beforeDir="false" afterPath="$PROJECT_DIR$/pkg/utils/request.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/pkg/services/ticket.go" beforeDir="false" afterPath="$PROJECT_DIR$/pkg/services/ticket.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/pkg/views/layouts/auth.gohtml" beforeDir="false" afterPath="$PROJECT_DIR$/pkg/views/layouts/auth.gohtml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/pkg/views/partials/header.gohtml" beforeDir="false" afterPath="$PROJECT_DIR$/pkg/views/partials/header.gohtml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/pkg/views/signin.gohtml" beforeDir="false" afterPath="$PROJECT_DIR$/pkg/views/signin.gohtml" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
@ -56,7 +76,7 @@
"git-widget-placeholder": "refactor/ux",
"go.import.settings.migrated": "true",
"go.sdk.automatically.set": "true",
"last_opened_file_path": "/Users/littlesheep/Documents/Projects/Hydrogen/Passport/pkg",
"last_opened_file_path": "/Users/littlesheep/Documents/Projects/Hydrogen/Passport/pkg/views",
"node.js.detected.package.eslint": "true",
"node.js.selected.package.eslint": "(autodetect)",
"nodejs_package_manager_path": "npm",
@ -72,9 +92,11 @@
}]]></component>
<component name="RecentsManager">
<key name="CopyFile.RECENT_KEYS">
<recent name="$PROJECT_DIR$/pkg/views" />
<recent name="$PROJECT_DIR$/pkg" />
</key>
<key name="MoveFile.RECENT_KEYS">
<recent name="$PROJECT_DIR$/pkg/utils" />
<recent name="$PROJECT_DIR$/pkg/services" />
</key>
</component>

5
go.mod
View File

@ -55,7 +55,7 @@ require (
github.com/jackc/puddle/v2 v2.2.1 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/klauspost/compress v1.17.7 // indirect
github.com/klauspost/compress v1.17.8 // indirect
github.com/leodido/go-urn v1.2.4 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
@ -76,6 +76,7 @@ require (
github.com/spf13/cast v1.6.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
github.com/sujit-baniya/flash v0.1.8 // indirect
github.com/tinylib/msgp v1.1.8 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasthttp v1.52.0 // indirect
@ -86,7 +87,7 @@ require (
golang.org/x/net v0.22.0 // indirect
golang.org/x/oauth2 v0.15.0 // indirect
golang.org/x/sync v0.5.0 // indirect
golang.org/x/sys v0.18.0 // indirect
golang.org/x/sys v0.19.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/time v0.5.0 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect

18
go.sum
View File

@ -16,6 +16,7 @@ cloud.google.com/go/storage v1.35.1/go.mod h1:M6M/3V/D3KpzMTJyPOR/HU6n2Si5QdaXYE
firebase.google.com/go v3.13.0+incompatible h1:3TdYC3DDi6aHn20qoRkxwGqNgdjtblwVAyRLQwGn/+4=
firebase.google.com/go v3.13.0+incompatible/go.mod h1:xlah6XbEyW6tbfSklcfe5FHJIwjt8toICdV5Wh9ptHs=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
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.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
@ -52,6 +53,7 @@ github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9
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/websocket v1.3.0/go.mod h1:xguaOzn2ZZ759LavtosEP+rcxIgBEE/rdumPINhR+Xo=
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.4/go.mod h1:KEOE+cXMhXG0zHc9d8+E38hoX+ZN7bhOtgeF2oT6jrQ=
github.com/gofiber/template v1.8.3 h1:hzHdvMwMo/T2kouz2pPCA0zGiLCeMnoGsQZBTSYgZxc=
@ -123,8 +125,12 @@ github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible
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/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
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.17.7 h1:ehO88t2UGzQK66LMdE8tibEd1ErmzZjNEqWkjLAKQQg=
github.com/klauspost/compress v1.17.7/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
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/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
@ -204,10 +210,13 @@ github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcU
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/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
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/tinylib/msgp v1.1.8 h1:FCXC1xanKO4I8plpHGH2P7koL/RzZs12l/+r7vakfm0=
github.com/tinylib/msgp v1.1.8/go.mod h1:qkpG+2ldGg4xRFmx+jfTvZPxfGFhi64BcnL9vkCm/Tw=
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/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.52.0/go.mod h1:hf5C4QnVMkNXMspnsUlfM3WitlgYflyhHYoKol/szxQ=
github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8=
@ -222,6 +231,7 @@ go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN8
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-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.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@ -241,6 +251,8 @@ golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR
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-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-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.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc=
@ -260,7 +272,10 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h
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-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-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-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=
@ -269,12 +284,15 @@ 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.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/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.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.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.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.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=

View File

@ -1,7 +1,12 @@
{
"next": "Next",
"email": "Email",
"username": "Username",
"nickname": "Nickname",
"password": "Password",
"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!"
"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!",
"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!"
}

View File

@ -1,7 +1,12 @@
{
"next": "下一步",
"email": "邮件地址",
"username": "用户名",
"nickname": "昵称",
"password": "密码",
"magicToken": "魔法令牌",
"signinTitle": "登陆",
"signinCaption": "登陆 Solarpass 以探索整个 Solar Network浏览帖子、探索社区、和你的好朋友聊八卦一切尽在 Solar Network!"
"signinCaption": "登陆 Solarpass 以探索整个 Solar Network浏览帖子、探索社区、和你的好朋友聊八卦一切尽在 Solar Network!",
"signupTitle": "注册",
"signupCaption": "注册以在 Solarpass 创建一个账号,之后你就可以探索整个 Solar Network享受下一代互联网生态系统"
}

View File

@ -2,6 +2,7 @@ package server
import (
"fmt"
"git.solsynth.dev/hydrogen/passport/pkg/utils"
"strconv"
"time"
@ -83,7 +84,7 @@ func editUserinfo(c *fiber.Ctx) error {
Birthday time.Time `json:"birthday"`
}
if err := BindAndValidate(c, &data); err != nil {
if err := utils.BindAndValidate(c, &data); err != nil {
return err
}
@ -133,7 +134,7 @@ func doRegister(c *fiber.Ctx) error {
MagicToken string `json:"magic_token"`
}
if err := BindAndValidate(c, &data); err != nil {
if err := utils.BindAndValidate(c, &data); err != nil {
return err
} else if viper.GetBool("use_registration_magic_token") && len(data.MagicToken) <= 0 {
return fmt.Errorf("missing magic token in request")
@ -162,7 +163,7 @@ func doRegisterConfirm(c *fiber.Ctx) error {
Code string `json:"code" validate:"required"`
}
if err := BindAndValidate(c, &data); err != nil {
if err := utils.BindAndValidate(c, &data); err != nil {
return err
}

View File

@ -2,6 +2,7 @@ package server
import (
"fmt"
"git.solsynth.dev/hydrogen/passport/pkg/utils"
"time"
"github.com/gofiber/fiber/v2"
@ -15,7 +16,7 @@ func doAuthenticate(c *fiber.Ctx) error {
Password string `json:"password" validate:"required"`
}
if err := BindAndValidate(c, &data); err != nil {
if err := utils.BindAndValidate(c, &data); err != nil {
return err
}
@ -47,7 +48,7 @@ func doMultiFactorAuthenticate(c *fiber.Ctx) error {
Code string `json:"code" validate:"required"`
}
if err := BindAndValidate(c, &data); err != nil {
if err := utils.BindAndValidate(c, &data); err != nil {
return err
}
@ -84,7 +85,7 @@ func getToken(c *fiber.Ctx) error {
GrantType string `json:"grant_type" form:"grant_type"`
}
if err := BindAndValidate(c, &data); err != nil {
if err := utils.BindAndValidate(c, &data); err != nil {
return err
}

View File

@ -3,6 +3,7 @@ package server
import (
"git.solsynth.dev/hydrogen/passport/pkg/models"
"git.solsynth.dev/hydrogen/passport/pkg/services"
"git.solsynth.dev/hydrogen/passport/pkg/utils"
"github.com/gofiber/fiber/v2"
)
@ -70,7 +71,7 @@ func editFriendship(c *fiber.Ctx) error {
Status uint8 `json:"status"`
}
if err := BindAndValidate(c, &data); err != nil {
if err := utils.BindAndValidate(c, &data); err != nil {
return fiber.NewError(fiber.StatusBadRequest, err.Error())
}

View File

@ -1,6 +1,7 @@
package server
import (
"git.solsynth.dev/hydrogen/passport/pkg/utils"
"time"
"git.solsynth.dev/hydrogen/passport/pkg/database"
@ -72,7 +73,7 @@ func addNotifySubscriber(c *fiber.Ctx) error {
DeviceID string `json:"device_id" validate:"required"`
}
if err := BindAndValidate(c, &data); err != nil {
if err := utils.BindAndValidate(c, &data); err != nil {
return err
}

View File

@ -3,6 +3,7 @@ package server
import (
"git.solsynth.dev/hydrogen/passport/pkg/models"
"git.solsynth.dev/hydrogen/passport/pkg/services"
"git.solsynth.dev/hydrogen/passport/pkg/utils"
"github.com/gofiber/fiber/v2"
)
@ -18,7 +19,7 @@ func notifyUser(c *fiber.Ctx) error {
UserID uint `json:"user_id" validate:"required"`
}
if err := BindAndValidate(c, &data); err != nil {
if err := utils.BindAndValidate(c, &data); err != nil {
return err
}

View File

@ -3,6 +3,7 @@ package server
import (
"git.solsynth.dev/hydrogen/passport/pkg/database"
"git.solsynth.dev/hydrogen/passport/pkg/models"
"git.solsynth.dev/hydrogen/passport/pkg/utils"
"github.com/gofiber/fiber/v2"
)
@ -47,7 +48,7 @@ func editPersonalPage(c *fiber.Ctx) error {
Links []models.AccountPageLinks `json:"links"`
}
if err := BindAndValidate(c, &data); err != nil {
if err := utils.BindAndValidate(c, &data); err != nil {
return err
}

View File

@ -1,26 +0,0 @@
package ui
import (
"github.com/gofiber/fiber/v2"
"github.com/nicksnyder/go-i18n/v2/i18n"
)
func signinPage(c *fiber.Ctx) error {
localizer := c.Locals("localizer").(*i18n.Localizer)
next, _ := localizer.LocalizeMessage(&i18n.Message{ID: "next"})
username, _ := localizer.LocalizeMessage(&i18n.Message{ID: "username"})
password, _ := localizer.LocalizeMessage(&i18n.Message{ID: "password"})
title, _ := localizer.LocalizeMessage(&i18n.Message{ID: "signinTitle"})
caption, _ := localizer.LocalizeMessage(&i18n.Message{ID: "signinCaption"})
return c.Render("views/signin", fiber.Map{
"i18n": fiber.Map{
"next": next,
"username": username,
"password": password,
"title": title,
"caption": caption,
},
}, "views/layouts/auth")
}

View File

@ -4,5 +4,10 @@ import "github.com/gofiber/fiber/v2"
func MapUserInterface(A *fiber.App) {
pages := A.Group("/").Name("Pages")
pages.Get("/sign-up", signupPage)
pages.Get("/sign-in", signinPage)
pages.Post("/sign-up", signupAction)
pages.Post("/sign-in", signinAction)
}

77
pkg/server/ui/signin.go Normal file
View File

@ -0,0 +1,77 @@
package ui
import (
"fmt"
"git.solsynth.dev/hydrogen/passport/pkg/services"
"git.solsynth.dev/hydrogen/passport/pkg/utils"
"github.com/gofiber/fiber/v2"
"github.com/nicksnyder/go-i18n/v2/i18n"
"github.com/sujit-baniya/flash"
)
func signinPage(c *fiber.Ctx) error {
localizer := c.Locals("localizer").(*i18n.Localizer)
next, _ := localizer.LocalizeMessage(&i18n.Message{ID: "next"})
username, _ := localizer.LocalizeMessage(&i18n.Message{ID: "username"})
password, _ := localizer.LocalizeMessage(&i18n.Message{ID: "password"})
signup, _ := localizer.LocalizeMessage(&i18n.Message{ID: "signupTitle"})
title, _ := localizer.LocalizeMessage(&i18n.Message{ID: "signinTitle"})
caption, _ := localizer.LocalizeMessage(&i18n.Message{ID: "signinCaption"})
return c.Render("views/signin", fiber.Map{
"info": flash.Get(c)["message"],
"i18n": fiber.Map{
"next": next,
"username": username,
"password": password,
"signup": signup,
"title": title,
"caption": caption,
},
}, "views/layouts/auth")
}
func signinAction(c *fiber.Ctx) error {
var data struct {
Username string `form:"username" validate:"required"`
Password string `form:"password" validate:"required"`
}
if err := utils.BindAndValidate(c, &data); err != nil {
return flash.WithInfo(c, fiber.Map{
"message": err.Error(),
}).Redirect("/sign-in")
}
user, err := services.LookupAccount(data.Username)
if err != nil {
return flash.WithInfo(c, fiber.Map{
"message": fmt.Sprintf("account was not found: %v", err.Error()),
}).Redirect("/sign-in")
}
ticket, err := services.NewTicket(user, c.IP(), c.Get(fiber.HeaderUserAgent))
if err != nil {
return flash.WithInfo(c, fiber.Map{
"message": fmt.Sprintf("unable setup ticket: %v", err.Error()),
}).Redirect("/sign-in")
}
ticket, err = services.ActiveTicketWithPassword(ticket, data.Password)
if err != nil {
return flash.WithInfo(c, fiber.Map{
"message": fmt.Sprintf("invalid password: %v", err.Error()),
}).Redirect("/sign-in")
}
if ticket.IsAvailable() != nil {
return flash.WithInfo(c, fiber.Map{
"message": "multi factor authenticate required",
}).Redirect("/sign-in")
} else {
return flash.WithInfo(c, fiber.Map{
"message": "done",
}).Redirect("/sign-in")
}
}

86
pkg/server/ui/signup.go Normal file
View File

@ -0,0 +1,86 @@
package ui
import (
"fmt"
"git.solsynth.dev/hydrogen/passport/pkg/database"
"git.solsynth.dev/hydrogen/passport/pkg/models"
"git.solsynth.dev/hydrogen/passport/pkg/services"
"git.solsynth.dev/hydrogen/passport/pkg/utils"
"github.com/gofiber/fiber/v2"
"github.com/nicksnyder/go-i18n/v2/i18n"
"github.com/spf13/viper"
"github.com/sujit-baniya/flash"
)
func signupPage(c *fiber.Ctx) error {
localizer := c.Locals("localizer").(*i18n.Localizer)
next, _ := localizer.LocalizeMessage(&i18n.Message{ID: "next"})
email, _ := localizer.LocalizeMessage(&i18n.Message{ID: "email"})
nickname, _ := localizer.LocalizeMessage(&i18n.Message{ID: "nickname"})
username, _ := localizer.LocalizeMessage(&i18n.Message{ID: "username"})
password, _ := localizer.LocalizeMessage(&i18n.Message{ID: "password"})
magicToken, _ := localizer.LocalizeMessage(&i18n.Message{ID: "magicToken"})
signin, _ := localizer.LocalizeMessage(&i18n.Message{ID: "signinTitle"})
title, _ := localizer.LocalizeMessage(&i18n.Message{ID: "signupTitle"})
caption, _ := localizer.LocalizeMessage(&i18n.Message{ID: "signupCaption"})
return c.Render("views/signup", fiber.Map{
"info": flash.Get(c)["message"],
"use_magic_token": viper.GetBool("use_registration_magic_token"),
"i18n": fiber.Map{
"next": next,
"email": email,
"username": username,
"nickname": nickname,
"password": password,
"magic_token": magicToken,
"signin": signin,
"title": title,
"caption": caption,
},
}, "views/layouts/auth")
}
func signupAction(c *fiber.Ctx) error {
var data struct {
Name string `form:"name" validate:"required,lowercase,alphanum,min=4,max=16"`
Nick string `form:"nick" validate:"required,min=4,max=24"`
Email string `form:"email" validate:"required,email"`
Password string `form:"password" validate:"required,min=4,max=32"`
MagicToken string `form:"magic_token"`
}
if err := utils.BindAndValidate(c, &data); err != nil {
return flash.WithInfo(c, fiber.Map{
"message": err.Error(),
}).Redirect("/sign-up")
} else if viper.GetBool("use_registration_magic_token") && len(data.MagicToken) <= 0 {
return flash.WithInfo(c, fiber.Map{
"message": "magic token was required",
}).Redirect("/sign-up")
} else if viper.GetBool("use_registration_magic_token") {
if tk, err := services.ValidateMagicToken(data.MagicToken, models.RegistrationMagicToken); err != nil {
return flash.WithInfo(c, fiber.Map{
"message": fmt.Sprintf("magic token was invalid: %v", err.Error()),
}).Redirect("/sign-up")
} else {
database.C.Delete(&tk)
}
}
if _, err := services.CreateAccount(
data.Name,
data.Nick,
data.Email,
data.Password,
); err != nil {
return flash.WithInfo(c, fiber.Map{
"message": err.Error(),
}).Redirect("/sign-up")
} else {
return flash.WithInfo(c, fiber.Map{
"message": "account has been created. now you can sign in!",
}).Redirect("/sign-in")
}
}

View File

@ -34,14 +34,15 @@ func NewTicket(user models.Account, ip, ua string) (models.AuthTicket, error) {
}
ticket = models.AuthTicket{
Claims: []string{"*"},
Audiences: []string{"passport"},
IpAddress: ip,
UserAgent: ua,
RequireMFA: DetectRisk(user, ip, ua),
ExpiredAt: lo.ToPtr(time.Now().Add(2 * time.Hour)),
AvailableAt: nil,
AccountID: user.ID,
Claims: []string{"*"},
Audiences: []string{"passport"},
IpAddress: ip,
UserAgent: ua,
RequireMFA: DetectRisk(user, ip, ua),
RequireAuthenticate: true,
ExpiredAt: lo.ToPtr(time.Now().Add(2 * time.Hour)),
AvailableAt: nil,
AccountID: user.ID,
}
err := database.C.Save(&ticket).Error
@ -81,7 +82,7 @@ func ActiveTicketWithPassword(ticket models.AuthTicket, password string) (models
if ticket.AvailableAt != nil {
return ticket, nil
} else if !ticket.RequireAuthenticate {
return ticket, fmt.Errorf("detected risk, multi factor authentication required")
return ticket, nil
}
if factor, err := GetPasswordFactor(ticket.AccountID); err != nil {

View File

@ -1,4 +1,4 @@
package server
package utils
import (
"github.com/go-playground/validator/v10"

View File

@ -5,8 +5,16 @@
<body>
<div class="wrapper-container">
<div class="wrapper-card">
{{embed}}
<div class="wrapper-middleware">
{{if ne .info nil}}
<div class="animate__animated animate__fadeInDown alert">
<div class="content">{{.info}}</div>
</div>
{{end}}
<div class="wrapper-card">
{{embed}}
</div>
</div>
</div>
</body>
@ -20,9 +28,19 @@
align-items: center;
}
.wrapper-card {
.wrapper-middleware {
width: 100%;
max-width: 720px;
min-width: 0;
max-width: min(800px, 100dvw);
margin: 1rem;
display: flex;
flex-direction: column;
gap: 1rem;
}
.wrapper-card {
transition: all .3s;
height: auto;
overflow: auto;
@ -31,9 +49,25 @@
justify-content: center;
border-radius: 28px;
padding: 56px;
margin: 2rem;
gap: 0 2rem;
background-color: #ebf1fa;
background-color: var(--md-sys-color-surface);
color: var(--md-sys-color-on-surface)
}
.alert {
width: 100%;
max-width: 800px;
padding: 16px;
border-radius: 16px;
background-color: var(--md-sys-color-secondary-container);
color: var(--md-sys-color-on-secondary-container);
display: flex;
gap: 8px;
}
.alert .content {
flex-grow: 1;
text-transform: capitalize;
}
.logo {

View File

@ -10,6 +10,11 @@
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap" rel="stylesheet">
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"
/>
<script type="importmap">
{
"imports": {
@ -28,10 +33,49 @@
<title>Solarpass</title>
<style>
:root, :host {
--md-sys-color-background: #fbf8ff;
--md-sys-color-on-background: #1b1b20;
--md-sys-color-surface: #fbf8ff;
--md-sys-color-surface-dim: #dcd9df;
--md-sys-color-surface-bright: #fbf8ff;
--md-sys-color-surface-container-lowest: #ffffff;
--md-sys-color-surface-container-low: #f6f2f9;
--md-sys-color-surface-container: #f0edf3;
--md-sys-color-surface-container-high: #eae7ed;
--md-sys-color-surface-container-highest: #e4e1e8;
--md-sys-color-on-surface: #1b1b20;
--md-sys-color-surface-variant: #e3e1ee;
--md-sys-color-on-surface-variant: #464650;
--md-sys-color-inverse-surface: #303035;
--md-sys-color-inverse-on-surface: #f3eff6;
--md-sys-color-outline: #777681;
--md-sys-color-outline-variant: #c7c5d2;
--md-sys-color-shadow: #000000;
--md-sys-color-scrim: #000000;
--md-sys-color-surface-tint: #53589d;
--md-sys-color-primary: #373c7e;
--md-sys-color-on-primary: #ffffff;
--md-sys-color-primary-container: #5b60a5;
--md-sys-color-on-primary-container: #ffffff;
--md-sys-color-inverse-primary: #bec2ff;
--md-sys-color-secondary: #5b5c79;
--md-sys-color-on-secondary: #ffffff;
--md-sys-color-secondary-container: #e2e1ff;
--md-sys-color-on-secondary-container: #454662;
--md-sys-color-tertiary: #662d5e;
--md-sys-color-on-tertiary: #ffffff;
--md-sys-color-tertiary-container: #8e5084;
--md-sys-color-on-tertiary-container: #ffffff;
--md-sys-color-error: #ba1a1a;
--md-sys-color-on-error: #ffffff;
--md-sys-color-error-container: #ffdad6;
--md-sys-color-on-error-container: #410002;
}
html, body {
padding: 0;
margin: 0;
font-family: Roboto Mono, monospace;
}
</style>
</head>

View File

@ -8,7 +8,7 @@
<div class="right-part">
<div class="responsive-title-gap"></div>
<form class="action-form">
<form class="action-form" action="/sign-in" method="POST">
<md-outlined-text-field
class="block-field"
name="username"
@ -28,6 +28,7 @@
</md-outlined-text-field>
<div class="action-form-buttons">
<md-text-button type="button" href="/sign-up">{{.i18n.signup}}</md-text-button>
<md-filled-button type="submit">{{.i18n.next}}</md-filled-button>
</div>
</form>

75
pkg/views/signup.gohtml Normal file
View File

@ -0,0 +1,75 @@
<div class="left-part">
<img class="logo" src="/favicon.png" width="64" height="64"/>
<h1 class="title">{{.i18n.title}}</h1>
<p class="caption">{{.i18n.caption}}</p>
</div>
<div class="right-part">
<div class="responsive-title-gap"></div>
<form class="action-form" action="/sign-up" method="POST">
<div class="columns-two">
<md-outlined-text-field
class="block-field"
name="name"
type="text"
autocomplete="username"
label={{.i18n.username}}
>
</md-outlined-text-field>
<md-outlined-text-field
class="block-field"
name="nick"
type="text"
autocomplete="nickname"
label={{.i18n.nickname}}
>
</md-outlined-text-field>
</div>
<md-outlined-text-field
class="block-field"
name="email"
type="email"
autocomplete="email"
label={{.i18n.email}}
>
</md-outlined-text-field>
<md-outlined-text-field
class="block-field"
name="password"
type="password"
autocomplete="new-password"
label={{.i18n.password}}
>
</md-outlined-text-field>
{{if eq .use_magic_token true}}
<md-outlined-text-field
class="block-field"
name="magic_token"
type="password"
autocomplete="off"
label={{.i18n.magic_token}}
>
</md-outlined-text-field>
{{end}}
<div class="action-form-buttons">
<md-text-button type="button" href="/sign-in">{{.i18n.signin}}</md-text-button>
<md-filled-button type="submit">{{.i18n.next}}</md-filled-button>
</div>
</form>
</div>
<style>
.columns-two {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1rem;
}
</style>