From 38d15208c33faba244ab8d62b2df6ebba9a26479 Mon Sep 17 00:00:00 2001 From: 0XCY Date: Thu, 3 Oct 2024 10:48:41 +0800 Subject: [PATCH] [render preview][FEAT] support for signature 1 & 2 (#32) * wip * nonce rename to ticket * doc * WIP * update DDL for airaccount_chains * precisely reg by email; for supporting other ways * refactor passkey * sigin refactor * bugfix: restore wallet to user * support customer challenge * bugfix: txdata empty * bugfix: duplicated response * support discoverable login * demo support discoverable login * support discoverable signin * update swagger * update swagger * support one user multiple passkeys * update passkey * WIP * bugfix: txSigRlt address * WIP * one chain support multip aa by alias * update pkg * bugfix: signup in different PASSKEY for each User * bugfix: creat_aa with alias * WIP: more hd wallets for one email * support more hdwallets for one account * update unit tests * WIP: 1:N wallets and account * Fix wallet usage check for specific network * bugfix: re-use wallet if network is different * bugfix and code clean * changelog add * update demo * specify -7 and -257 only in registration session * Update dependencies in go.mod file; fix critical vul * replace http 404 to biz code 404 but http code 200 --- CHANGELOG_CN.md | 88 + Dockerfile | 4 +- conf/db.go | 6 +- docs/docs.go | 252 +- docs/passkey-er.drawio | 373 +++ docs/signature-flow.drawio | 144 + docs/swagger.json | 252 +- docs/swagger.yaml | 209 +- example/one-click-deploy/docker-compose.yaml | 2 +- example/webauthn-relay-test/app/api/api.ts | 1 + example/webauthn-relay-test/app/form.tsx | 38 +- example/webauthn-relay-test/app/loginform.tsx | 5 +- example/webauthn-relay-test/app/passkey.tsx | 13 +- .../app/payment/payform.tsx | 46 + .../app/payment/payment.tsx | 16 +- example/webauthn-relay-test/package-lock.json | 127 +- example/webauthn-relay-test/package.json | 1 + example/webauthn-relay-test/yarn.lock | 2908 +++++++++++++++++ go.mod | 86 +- go.sum | 70 +- internal/common_util/crypto.go | 1 + internal/common_util/crypto_test.go | 29 +- internal/community/account/hdwallet.go | 74 +- internal/community/account/hdwallet_test.go | 38 +- internal/community/account/impl/alchemy.go | 2 +- .../community/account/impl/alchemy_test.go | 14 +- internal/community/chain/account.go | 4 +- internal/community/chain/account_test.go | 37 +- internal/web_server/pkg/response/model.go | 18 +- internal/web_server/routers/boot.go | 9 +- plugins/passkey_relay_party/account_info.go | 41 +- .../passkey_relay_party/authoractor_api.go | 2 +- plugins/passkey_relay_party/challenge.go | 9 +- plugins/passkey_relay_party/conf/db.go | 2 +- plugins/passkey_relay_party/create_aa.go | 78 + plugins/passkey_relay_party/jwt_middleware.go | 22 +- plugins/passkey_relay_party/relay.go | 29 +- .../passkey_relay_party/seedworks/account.go | 9 +- .../seedworks/create_aa.go | 8 + .../seedworks/encrypt_test.go | 40 - .../passkey_relay_party/seedworks/errors.go | 18 + plugins/passkey_relay_party/seedworks/reg.go | 15 +- .../passkey_relay_party/seedworks/session.go | 73 +- .../passkey_relay_party/seedworks/sigin.go | 2 +- .../seedworks/tx_signature.go | 21 +- plugins/passkey_relay_party/seedworks/user.go | 209 +- .../seedworks/user_test.go | 71 - plugins/passkey_relay_party/signin.go | 34 +- plugins/passkey_relay_party/signup.go | 147 +- .../passkey_relay_party/storage/inmemory.go | 90 - .../passkey_relay_party/storage/interface.go | 14 +- .../storage/migrations/migrate.go | 1 + .../storage/migrations/migrate_20240711.go | 25 - .../storage/migrations/migrate_20240828.go | 69 + .../storage/model/airaccount.go | 17 + .../storage/model/airaccount_chain.go | 19 + .../storage/model/captcha_challenge.go | 13 +- .../storage/model/hdwallet.go | 14 + .../storage/model/passkey.go | 18 + .../passkey_relay_party/storage/model/user.go | 17 - .../storage/model/user_account.go | 18 - plugins/passkey_relay_party/storage/pgsql.go | 208 +- plugins/passkey_relay_party/support_chain.go | 13 +- plugins/passkey_relay_party/tx_signature.go | 44 +- .../passkey_relay_party/tx_signature_sig.go | 28 + push-service/package.json | 8 - 66 files changed, 5335 insertions(+), 978 deletions(-) create mode 100644 CHANGELOG_CN.md create mode 100644 docs/passkey-er.drawio create mode 100644 docs/signature-flow.drawio create mode 100644 example/webauthn-relay-test/yarn.lock create mode 100644 plugins/passkey_relay_party/create_aa.go create mode 100644 plugins/passkey_relay_party/seedworks/create_aa.go delete mode 100644 plugins/passkey_relay_party/seedworks/encrypt_test.go delete mode 100644 plugins/passkey_relay_party/seedworks/user_test.go delete mode 100644 plugins/passkey_relay_party/storage/inmemory.go create mode 100644 plugins/passkey_relay_party/storage/migrations/migrate_20240828.go create mode 100644 plugins/passkey_relay_party/storage/model/airaccount.go create mode 100644 plugins/passkey_relay_party/storage/model/airaccount_chain.go create mode 100644 plugins/passkey_relay_party/storage/model/hdwallet.go create mode 100644 plugins/passkey_relay_party/storage/model/passkey.go delete mode 100644 plugins/passkey_relay_party/storage/model/user.go delete mode 100644 plugins/passkey_relay_party/storage/model/user_account.go create mode 100644 plugins/passkey_relay_party/tx_signature_sig.go delete mode 100644 push-service/package.json diff --git a/CHANGELOG_CN.md b/CHANGELOG_CN.md new file mode 100644 index 0000000..3305203 --- /dev/null +++ b/CHANGELOG_CN.md @@ -0,0 +1,88 @@ +# Change Logs + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](http://keepachangelog.com/) +and this project adheres to [Semantic Versioning](http://semver.org/). + +[TOC] + +> Unrelease + +## [变更逻辑] + +1. 注册成功后,不会自动创建AA钱包,需要调用新增接口 [POST /api/passkey/v1/account/chain](#post-apipasskeyv1accountchain) +2. 同一个邮件,在不同设备允许再次注册(本质是注册该账户的Passkey),注册成功后依然是原用户 +3. 登录不再需要输入邮箱,现在会自动发现当前设备在该origin下的Passkeys + +## [变更接口] + +### GET /api/passkey/v1/account/info + +1. query增加参数:alias, 默认为空 + +### POST /api/passkey/v1/reg/verify + +1. query增加参数:alias, 默认为空 + +### POST /api/passkey/v1/sign + +1. body移除email,只保留origin + +### POST /api/passkey/v1/sign/verify + +1. query参数只保留origin + +### POST /api/passkey/v1/tx/sign + +1. body参数中nonce改名为ticket +2. body参数中增加network,表示链名称,必填 +3. body参数中增加network_alias,表示链别名,非必填参数 + +### POST /api/passkey/v1/tx/sign/verify + +1. query参数中nonce改名为ticket +2. query参数中增加network,表示链名称,必填 +3. query参数中增加network_alias,表示链别名,非必填参数 + +## [新增接口] + +### GET /api/passkey/v1/chains/support + +> 获取支持的链名称 + +入参:无 + +*data*对象里的key表示链名称,在其他接口参数中的network需符合该键名,value为true时表示支持,*data*中没有列出的链表示不支持 + +出参: + +```json +{ + "code": 200, + "message": "", + "data": { + "base-sepolia": true, + "ethereum-sepolia": true, + "optimism-sepolia": true + }, + "cost": "2562047h47m16.854775807s" +} +``` + +### POST /api/passkey/v1/account/chain + +> 创建指定链的AA钱包 + +入参: + +body: + +```json +{ + "alias": "string", + "network": "ethereum-mainnet" +} +``` + +alias: 别名,允许为空,同一个链支持不同别名的钱包,目前上限为10个 \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 1fbfcad..1209673 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ ## build -FROM golang:1.23.0-alpine3.20 AS build-env +FROM golang:1.23.1-alpine3.20 AS build-env RUN apk add build-base @@ -12,7 +12,7 @@ RUN go env -w GO111MODULE=on \ && go build -o cnode ## run -FROM alpine:3.20.2 +FROM alpine:3.20 RUN mkdir -p /aa && mkdir -p /aa/log diff --git a/conf/db.go b/conf/db.go index da722f9..279887b 100644 --- a/conf/db.go +++ b/conf/db.go @@ -9,7 +9,7 @@ import ( var ( dbClient *gorm.DB - dbOnce = sync.Once{} + dbOnce = sync.Once{} ) func GetDbClient() *gorm.DB { @@ -20,6 +20,10 @@ func GetDbClient() *gorm.DB { panic(err) } dbClient = configDBVar + + if Environment.IsDevelopment() { + dbClient = dbClient.Debug() + } }) return dbClient } diff --git a/docs/docs.go b/docs/docs.go index be1e59d..82d4d5b 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -149,6 +149,39 @@ const docTemplate = `{ } } }, + "/api/passkey/v1/account/chain": { + "post": { + "security": [ + { + "JWT": [] + } + ], + "description": "create aa by sepcify network(chain)", + "consumes": [ + "application/json" + ], + "tags": [ + "Plugins Passkey" + ], + "summary": "Create AA with Alias, default empty", + "parameters": [ + { + "description": "Create AA", + "name": "createAABody", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/seedworks.CreateAARequest" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, "/api/passkey/v1/account/info": { "get": { "security": [ @@ -166,7 +199,7 @@ const docTemplate = `{ "tags": [ "Plugins Passkey" ], - "summary": "get user account info", + "summary": "Get User Account Info", "parameters": [ { "type": "string", @@ -174,6 +207,12 @@ const docTemplate = `{ "name": "network", "in": "query", "required": true + }, + { + "type": "string", + "description": "alias", + "name": "alias", + "in": "query" } ], "responses": { @@ -192,6 +231,23 @@ const docTemplate = `{ } } }, + "/api/passkey/v1/chains/support": { + "get": { + "description": "get support chains", + "consumes": [ + "application/json" + ], + "tags": [ + "Plugins Passkey" + ], + "summary": "Get support chains in relay party", + "responses": { + "200": { + "description": "OK" + } + } + } + }, "/api/passkey/v1/imauthz": { "get": { "security": [ @@ -236,7 +292,7 @@ const docTemplate = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/seedworks.Registration" + "$ref": "#/definitions/seedworks.RegistrationByEmail" } } ], @@ -267,7 +323,7 @@ const docTemplate = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/seedworks.RegistrationPrepare" + "$ref": "#/definitions/seedworks.RegistrationByEmail" } } ], @@ -287,7 +343,7 @@ const docTemplate = `{ "tags": [ "Plugins Passkey" ], - "summary": "Finish SignUp", + "summary": "Finish SignUp By Email", "parameters": [ { "type": "string", @@ -310,6 +366,12 @@ const docTemplate = `{ "name": "network", "in": "query" }, + { + "type": "string", + "description": "network", + "name": "alias", + "in": "query" + }, { "description": "Verify Registration", "name": "registrationBody", @@ -396,14 +458,6 @@ const docTemplate = `{ ], "summary": "Finish SingIn", "parameters": [ - { - "type": "string", - "format": "email", - "description": "user email", - "name": "email", - "in": "query", - "required": true - }, { "type": "string", "description": "origin", @@ -513,10 +567,23 @@ const docTemplate = `{ }, { "type": "string", - "description": "nonce", - "name": "nonce", + "description": "ticket", + "name": "ticket", + "in": "query", + "required": true + }, + { + "type": "string", + "description": "chain network", + "name": "network", "in": "query", "required": true + }, + { + "type": "string", + "description": "chain network alias", + "name": "alias", + "in": "query" } ], "responses": { @@ -604,13 +671,34 @@ const docTemplate = `{ } } }, + "protocol.AttestationFormat": { + "type": "string", + "enum": [ + "packed", + "tpm", + "android-key", + "android-safetynet", + "fido-u2f", + "apple", + "none" + ], + "x-enum-varnames": [ + "AttestationFormatPacked", + "AttestationFormatTPM", + "AttestationFormatAndroidKey", + "AttestationFormatAndroidSafetyNet", + "AttestationFormatFIDOUniversalSecondFactor", + "AttestationFormatApple", + "AttestationFormatNone" + ] + }, "protocol.AuthenticationExtensions": { "type": "object", - "additionalProperties": true + "additionalProperties": {} }, "protocol.AuthenticationExtensionsClientOutputs": { "type": "object", - "additionalProperties": true + "additionalProperties": {} }, "protocol.AuthenticatorAssertionResponse": { "type": "object", @@ -663,6 +751,12 @@ const docTemplate = `{ "type": "integer" } }, + "authenticatorData": { + "type": "array", + "items": { + "type": "integer" + } + }, "clientDataJSON": { "description": "From the spec https://www.w3.org/TR/webauthn/#dom-authenticatorresponse-clientdatajson\nThis attribute contains a JSON serialization of the client data passed to the authenticator\nby the client in its call to either create() or get().", "type": "array", @@ -670,6 +764,15 @@ const docTemplate = `{ "type": "integer" } }, + "publicKey": { + "type": "array", + "items": { + "type": "integer" + } + }, + "publicKeyAlgorithm": { + "type": "integer" + }, "transports": { "type": "array", "items": { @@ -717,6 +820,7 @@ const docTemplate = `{ "usb", "nfc", "ble", + "smart-card", "hybrid", "internal" ], @@ -724,6 +828,7 @@ const docTemplate = `{ "USB", "NFC", "BLE", + "SmartCard", "Hybrid", "Internal" ] @@ -793,13 +898,6 @@ const docTemplate = `{ "response": { "$ref": "#/definitions/protocol.AuthenticatorAttestationResponse" }, - "transports": { - "description": "Deprecated: Transports is deprecated due to upstream changes to the API.\nUse the Transports field of AuthenticatorAttestationResponse\ninstead. Transports is kept for backward compatibility, and should not\nbe used by new clients.", - "type": "array", - "items": { - "type": "string" - } - }, "type": { "description": "Type is the value of the object’s interface object's [[type]] slot,\nwhich specifies the credential type represented by this object.\nThis should be type \"public-key\" for Webauthn credentials.", "type": "string" @@ -859,6 +957,12 @@ const docTemplate = `{ "attestation": { "$ref": "#/definitions/protocol.ConveyancePreference" }, + "attestationFormats": { + "type": "array", + "items": { + "$ref": "#/definitions/protocol.AttestationFormat" + } + }, "authenticatorSelection": { "$ref": "#/definitions/protocol.AuthenticatorSelection" }, @@ -877,6 +981,12 @@ const docTemplate = `{ "extensions": { "$ref": "#/definitions/protocol.AuthenticationExtensions" }, + "hints": { + "type": "array", + "items": { + "$ref": "#/definitions/protocol.PublicKeyCredentialHints" + } + }, "pubKeyCredParams": { "type": "array", "items": { @@ -894,6 +1004,19 @@ const docTemplate = `{ } } }, + "protocol.PublicKeyCredentialHints": { + "type": "string", + "enum": [ + "security-key", + "client-device", + "hybrid" + ], + "x-enum-varnames": [ + "PublicKeyCredentialHintSecurityKey", + "PublicKeyCredentialHintClientDevice", + "PublicKeyCredentialHintHybrid" + ] + }, "protocol.PublicKeyCredentialRequestOptions": { "type": "object", "properties": { @@ -912,6 +1035,12 @@ const docTemplate = `{ "extensions": { "$ref": "#/definitions/protocol.AuthenticationExtensions" }, + "hints": { + "type": "array", + "items": { + "$ref": "#/definitions/protocol.PublicKeyCredentialHints" + } + }, "rpId": { "type": "string" }, @@ -926,10 +1055,6 @@ const docTemplate = `{ "protocol.RelyingPartyEntity": { "type": "object", "properties": { - "icon": { - "description": "A serialized URL which resolves to an image associated with the entity. For example,\nthis could be a user’s avatar or a Relying Party's logo. This URL MUST be an a priori\nauthenticated URL. Authenticators MUST accept and store a 128-byte minimum length for\nan icon member’s value. Authenticators MAY ignore an icon member’s value if its length\nis greater than 128 bytes. The URL’s scheme MAY be \"data\" to avoid fetches of the URL,\nat the cost of needing more storage.\n\nDeprecated: this has been removed from the specification recommendations.", - "type": "string" - }, "id": { "description": "A unique identifier for the Relying Party entity, which sets the RP ID.", "type": "string" @@ -960,10 +1085,6 @@ const docTemplate = `{ "description": "A human-palatable name for the user account, intended only for display.\nFor example, \"Alex P. Müller\" or \"田中 倫\". The Relying Party SHOULD let\nthe user choose this, and SHOULD NOT restrict the choice more than necessary.", "type": "string" }, - "icon": { - "description": "A serialized URL which resolves to an image associated with the entity. For example,\nthis could be a user’s avatar or a Relying Party's logo. This URL MUST be an a priori\nauthenticated URL. Authenticators MUST accept and store a 128-byte minimum length for\nan icon member’s value. Authenticators MAY ignore an icon member’s value if its length\nis greater than 128 bytes. The URL’s scheme MAY be \"data\" to avoid fetches of the URL,\nat the cost of needing more storage.\n\nDeprecated: this has been removed from the specification recommendations.", - "type": "string" - }, "id": { "description": "ID is the user handle of the user account entity. To ensure secure operation,\nauthentication and authorization decisions MUST be made on the basis of this id\nmember, not the displayName nor name members. See Section 6.1 of\n[RFC8266](https://www.w3.org/TR/webauthn/#biblio-rfc8266)." }, @@ -1043,37 +1164,67 @@ const docTemplate = `{ } } }, - "seedworks.Registration": { + "seedworks.Chain": { + "type": "string", + "enum": [ + "ethereum-mainnet", + "ethereum-sepolia", + "optimism-mainnet", + "optimism-sepolia", + "arbitrum-one", + "arbitrum-nova", + "arbitrum-sepolia", + "scroll-mainnet", + "scroll-sepolia", + "starknet-mainnet", + "starknet-sepolia", + "base-mainnet", + "base-sepolia" + ], + "x-enum-varnames": [ + "EthereumMainnet", + "EthereumSepolia", + "OptimismMainnet", + "OptimismSepolia", + "ArbitrumOne", + "ArbitrumNova", + "ArbitrumSpeolia", + "ScrollMainnet", + "ScrollSepolia", + "StarketMainnet", + "StarketSepolia", + "BaseMainnet", + "BaseSepolia" + ] + }, + "seedworks.CreateAARequest": { "type": "object", "properties": { - "captcha": { + "alias": { "type": "string" }, - "email": { - "type": "string" - }, - "origin": { - "type": "string" + "network": { + "$ref": "#/definitions/seedworks.Chain" } } }, - "seedworks.RegistrationPrepare": { + "seedworks.RegistrationByEmail": { "type": "object", "properties": { + "captcha": { + "type": "string" + }, "email": { "type": "string" + }, + "origin": { + "type": "string" } } }, "seedworks.SiginIn": { "type": "object", "properties": { - "captcha": { - "type": "string" - }, - "email": { - "type": "string" - }, "origin": { "type": "string" } @@ -1082,12 +1233,18 @@ const docTemplate = `{ "seedworks.TxSignature": { "type": "object", "properties": { - "nonce": { + "network": { + "$ref": "#/definitions/seedworks.Chain" + }, + "network_alias": { "type": "string" }, "origin": { "type": "string" }, + "ticket": { + "type": "string" + }, "txdata": { "type": "string" } @@ -1096,6 +1253,9 @@ const docTemplate = `{ "seedworks.TxSignatureResult": { "type": "object", "properties": { + "address": { + "type": "string" + }, "code": { "type": "integer" }, diff --git a/docs/passkey-er.drawio b/docs/passkey-er.drawio new file mode 100644 index 0000000..713c6d5 --- /dev/null +++ b/docs/passkey-er.drawio @@ -0,0 +1,373 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/signature-flow.drawio b/docs/signature-flow.drawio new file mode 100644 index 0000000..c5c5530 --- /dev/null +++ b/docs/signature-flow.drawio @@ -0,0 +1,144 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/swagger.json b/docs/swagger.json index 95b7fff..d26512e 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -138,6 +138,39 @@ } } }, + "/api/passkey/v1/account/chain": { + "post": { + "security": [ + { + "JWT": [] + } + ], + "description": "create aa by sepcify network(chain)", + "consumes": [ + "application/json" + ], + "tags": [ + "Plugins Passkey" + ], + "summary": "Create AA with Alias, default empty", + "parameters": [ + { + "description": "Create AA", + "name": "createAABody", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/seedworks.CreateAARequest" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, "/api/passkey/v1/account/info": { "get": { "security": [ @@ -155,7 +188,7 @@ "tags": [ "Plugins Passkey" ], - "summary": "get user account info", + "summary": "Get User Account Info", "parameters": [ { "type": "string", @@ -163,6 +196,12 @@ "name": "network", "in": "query", "required": true + }, + { + "type": "string", + "description": "alias", + "name": "alias", + "in": "query" } ], "responses": { @@ -181,6 +220,23 @@ } } }, + "/api/passkey/v1/chains/support": { + "get": { + "description": "get support chains", + "consumes": [ + "application/json" + ], + "tags": [ + "Plugins Passkey" + ], + "summary": "Get support chains in relay party", + "responses": { + "200": { + "description": "OK" + } + } + } + }, "/api/passkey/v1/imauthz": { "get": { "security": [ @@ -225,7 +281,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/seedworks.Registration" + "$ref": "#/definitions/seedworks.RegistrationByEmail" } } ], @@ -256,7 +312,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/seedworks.RegistrationPrepare" + "$ref": "#/definitions/seedworks.RegistrationByEmail" } } ], @@ -276,7 +332,7 @@ "tags": [ "Plugins Passkey" ], - "summary": "Finish SignUp", + "summary": "Finish SignUp By Email", "parameters": [ { "type": "string", @@ -299,6 +355,12 @@ "name": "network", "in": "query" }, + { + "type": "string", + "description": "network", + "name": "alias", + "in": "query" + }, { "description": "Verify Registration", "name": "registrationBody", @@ -385,14 +447,6 @@ ], "summary": "Finish SingIn", "parameters": [ - { - "type": "string", - "format": "email", - "description": "user email", - "name": "email", - "in": "query", - "required": true - }, { "type": "string", "description": "origin", @@ -502,10 +556,23 @@ }, { "type": "string", - "description": "nonce", - "name": "nonce", + "description": "ticket", + "name": "ticket", + "in": "query", + "required": true + }, + { + "type": "string", + "description": "chain network", + "name": "network", "in": "query", "required": true + }, + { + "type": "string", + "description": "chain network alias", + "name": "alias", + "in": "query" } ], "responses": { @@ -593,13 +660,34 @@ } } }, + "protocol.AttestationFormat": { + "type": "string", + "enum": [ + "packed", + "tpm", + "android-key", + "android-safetynet", + "fido-u2f", + "apple", + "none" + ], + "x-enum-varnames": [ + "AttestationFormatPacked", + "AttestationFormatTPM", + "AttestationFormatAndroidKey", + "AttestationFormatAndroidSafetyNet", + "AttestationFormatFIDOUniversalSecondFactor", + "AttestationFormatApple", + "AttestationFormatNone" + ] + }, "protocol.AuthenticationExtensions": { "type": "object", - "additionalProperties": true + "additionalProperties": {} }, "protocol.AuthenticationExtensionsClientOutputs": { "type": "object", - "additionalProperties": true + "additionalProperties": {} }, "protocol.AuthenticatorAssertionResponse": { "type": "object", @@ -652,6 +740,12 @@ "type": "integer" } }, + "authenticatorData": { + "type": "array", + "items": { + "type": "integer" + } + }, "clientDataJSON": { "description": "From the spec https://www.w3.org/TR/webauthn/#dom-authenticatorresponse-clientdatajson\nThis attribute contains a JSON serialization of the client data passed to the authenticator\nby the client in its call to either create() or get().", "type": "array", @@ -659,6 +753,15 @@ "type": "integer" } }, + "publicKey": { + "type": "array", + "items": { + "type": "integer" + } + }, + "publicKeyAlgorithm": { + "type": "integer" + }, "transports": { "type": "array", "items": { @@ -706,6 +809,7 @@ "usb", "nfc", "ble", + "smart-card", "hybrid", "internal" ], @@ -713,6 +817,7 @@ "USB", "NFC", "BLE", + "SmartCard", "Hybrid", "Internal" ] @@ -782,13 +887,6 @@ "response": { "$ref": "#/definitions/protocol.AuthenticatorAttestationResponse" }, - "transports": { - "description": "Deprecated: Transports is deprecated due to upstream changes to the API.\nUse the Transports field of AuthenticatorAttestationResponse\ninstead. Transports is kept for backward compatibility, and should not\nbe used by new clients.", - "type": "array", - "items": { - "type": "string" - } - }, "type": { "description": "Type is the value of the object’s interface object's [[type]] slot,\nwhich specifies the credential type represented by this object.\nThis should be type \"public-key\" for Webauthn credentials.", "type": "string" @@ -848,6 +946,12 @@ "attestation": { "$ref": "#/definitions/protocol.ConveyancePreference" }, + "attestationFormats": { + "type": "array", + "items": { + "$ref": "#/definitions/protocol.AttestationFormat" + } + }, "authenticatorSelection": { "$ref": "#/definitions/protocol.AuthenticatorSelection" }, @@ -866,6 +970,12 @@ "extensions": { "$ref": "#/definitions/protocol.AuthenticationExtensions" }, + "hints": { + "type": "array", + "items": { + "$ref": "#/definitions/protocol.PublicKeyCredentialHints" + } + }, "pubKeyCredParams": { "type": "array", "items": { @@ -883,6 +993,19 @@ } } }, + "protocol.PublicKeyCredentialHints": { + "type": "string", + "enum": [ + "security-key", + "client-device", + "hybrid" + ], + "x-enum-varnames": [ + "PublicKeyCredentialHintSecurityKey", + "PublicKeyCredentialHintClientDevice", + "PublicKeyCredentialHintHybrid" + ] + }, "protocol.PublicKeyCredentialRequestOptions": { "type": "object", "properties": { @@ -901,6 +1024,12 @@ "extensions": { "$ref": "#/definitions/protocol.AuthenticationExtensions" }, + "hints": { + "type": "array", + "items": { + "$ref": "#/definitions/protocol.PublicKeyCredentialHints" + } + }, "rpId": { "type": "string" }, @@ -915,10 +1044,6 @@ "protocol.RelyingPartyEntity": { "type": "object", "properties": { - "icon": { - "description": "A serialized URL which resolves to an image associated with the entity. For example,\nthis could be a user’s avatar or a Relying Party's logo. This URL MUST be an a priori\nauthenticated URL. Authenticators MUST accept and store a 128-byte minimum length for\nan icon member’s value. Authenticators MAY ignore an icon member’s value if its length\nis greater than 128 bytes. The URL’s scheme MAY be \"data\" to avoid fetches of the URL,\nat the cost of needing more storage.\n\nDeprecated: this has been removed from the specification recommendations.", - "type": "string" - }, "id": { "description": "A unique identifier for the Relying Party entity, which sets the RP ID.", "type": "string" @@ -949,10 +1074,6 @@ "description": "A human-palatable name for the user account, intended only for display.\nFor example, \"Alex P. Müller\" or \"田中 倫\". The Relying Party SHOULD let\nthe user choose this, and SHOULD NOT restrict the choice more than necessary.", "type": "string" }, - "icon": { - "description": "A serialized URL which resolves to an image associated with the entity. For example,\nthis could be a user’s avatar or a Relying Party's logo. This URL MUST be an a priori\nauthenticated URL. Authenticators MUST accept and store a 128-byte minimum length for\nan icon member’s value. Authenticators MAY ignore an icon member’s value if its length\nis greater than 128 bytes. The URL’s scheme MAY be \"data\" to avoid fetches of the URL,\nat the cost of needing more storage.\n\nDeprecated: this has been removed from the specification recommendations.", - "type": "string" - }, "id": { "description": "ID is the user handle of the user account entity. To ensure secure operation,\nauthentication and authorization decisions MUST be made on the basis of this id\nmember, not the displayName nor name members. See Section 6.1 of\n[RFC8266](https://www.w3.org/TR/webauthn/#biblio-rfc8266)." }, @@ -1032,37 +1153,67 @@ } } }, - "seedworks.Registration": { + "seedworks.Chain": { + "type": "string", + "enum": [ + "ethereum-mainnet", + "ethereum-sepolia", + "optimism-mainnet", + "optimism-sepolia", + "arbitrum-one", + "arbitrum-nova", + "arbitrum-sepolia", + "scroll-mainnet", + "scroll-sepolia", + "starknet-mainnet", + "starknet-sepolia", + "base-mainnet", + "base-sepolia" + ], + "x-enum-varnames": [ + "EthereumMainnet", + "EthereumSepolia", + "OptimismMainnet", + "OptimismSepolia", + "ArbitrumOne", + "ArbitrumNova", + "ArbitrumSpeolia", + "ScrollMainnet", + "ScrollSepolia", + "StarketMainnet", + "StarketSepolia", + "BaseMainnet", + "BaseSepolia" + ] + }, + "seedworks.CreateAARequest": { "type": "object", "properties": { - "captcha": { + "alias": { "type": "string" }, - "email": { - "type": "string" - }, - "origin": { - "type": "string" + "network": { + "$ref": "#/definitions/seedworks.Chain" } } }, - "seedworks.RegistrationPrepare": { + "seedworks.RegistrationByEmail": { "type": "object", "properties": { + "captcha": { + "type": "string" + }, "email": { "type": "string" + }, + "origin": { + "type": "string" } } }, "seedworks.SiginIn": { "type": "object", "properties": { - "captcha": { - "type": "string" - }, - "email": { - "type": "string" - }, "origin": { "type": "string" } @@ -1071,12 +1222,18 @@ "seedworks.TxSignature": { "type": "object", "properties": { - "nonce": { + "network": { + "$ref": "#/definitions/seedworks.Chain" + }, + "network_alias": { "type": "string" }, "origin": { "type": "string" }, + "ticket": { + "type": "string" + }, "txdata": { "type": "string" } @@ -1085,6 +1242,9 @@ "seedworks.TxSignatureResult": { "type": "object", "properties": { + "address": { + "type": "string" + }, "code": { "type": "integer" }, diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 03272d6..d632923 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -20,11 +20,29 @@ definitions: token: type: string type: object + protocol.AttestationFormat: + enum: + - packed + - tpm + - android-key + - android-safetynet + - fido-u2f + - apple + - none + type: string + x-enum-varnames: + - AttestationFormatPacked + - AttestationFormatTPM + - AttestationFormatAndroidKey + - AttestationFormatAndroidSafetyNet + - AttestationFormatFIDOUniversalSecondFactor + - AttestationFormatApple + - AttestationFormatNone protocol.AuthenticationExtensions: - additionalProperties: true + additionalProperties: {} type: object protocol.AuthenticationExtensionsClientOutputs: - additionalProperties: true + additionalProperties: {} type: object protocol.AuthenticatorAssertionResponse: properties: @@ -74,6 +92,10 @@ definitions: items: type: integer type: array + authenticatorData: + items: + type: integer + type: array clientDataJSON: description: |- From the spec https://www.w3.org/TR/webauthn/#dom-authenticatorresponse-clientdatajson @@ -82,6 +104,12 @@ definitions: items: type: integer type: array + publicKey: + items: + type: integer + type: array + publicKeyAlgorithm: + type: integer transports: items: type: string @@ -120,6 +148,7 @@ definitions: - usb - nfc - ble + - smart-card - hybrid - internal type: string @@ -127,6 +156,7 @@ definitions: - USB - NFC - BLE + - SmartCard - Hybrid - Internal protocol.ConveyancePreference: @@ -184,15 +214,6 @@ definitions: type: array response: $ref: '#/definitions/protocol.AuthenticatorAttestationResponse' - transports: - description: |- - Deprecated: Transports is deprecated due to upstream changes to the API. - Use the Transports field of AuthenticatorAttestationResponse - instead. Transports is kept for backward compatibility, and should not - be used by new clients. - items: - type: string - type: array type: description: |- Type is the value of the object’s interface object's [[type]] slot, @@ -234,6 +255,10 @@ definitions: properties: attestation: $ref: '#/definitions/protocol.ConveyancePreference' + attestationFormats: + items: + $ref: '#/definitions/protocol.AttestationFormat' + type: array authenticatorSelection: $ref: '#/definitions/protocol.AuthenticatorSelection' challenge: @@ -246,6 +271,10 @@ definitions: type: array extensions: $ref: '#/definitions/protocol.AuthenticationExtensions' + hints: + items: + $ref: '#/definitions/protocol.PublicKeyCredentialHints' + type: array pubKeyCredParams: items: $ref: '#/definitions/protocol.CredentialParameter' @@ -257,6 +286,16 @@ definitions: user: $ref: '#/definitions/protocol.UserEntity' type: object + protocol.PublicKeyCredentialHints: + enum: + - security-key + - client-device + - hybrid + type: string + x-enum-varnames: + - PublicKeyCredentialHintSecurityKey + - PublicKeyCredentialHintClientDevice + - PublicKeyCredentialHintHybrid protocol.PublicKeyCredentialRequestOptions: properties: allowCredentials: @@ -269,6 +308,10 @@ definitions: type: array extensions: $ref: '#/definitions/protocol.AuthenticationExtensions' + hints: + items: + $ref: '#/definitions/protocol.PublicKeyCredentialHints' + type: array rpId: type: string timeout: @@ -278,17 +321,6 @@ definitions: type: object protocol.RelyingPartyEntity: properties: - icon: - description: |- - A serialized URL which resolves to an image associated with the entity. For example, - this could be a user’s avatar or a Relying Party's logo. This URL MUST be an a priori - authenticated URL. Authenticators MUST accept and store a 128-byte minimum length for - an icon member’s value. Authenticators MAY ignore an icon member’s value if its length - is greater than 128 bytes. The URL’s scheme MAY be "data" to avoid fetches of the URL, - at the cost of needing more storage. - - Deprecated: this has been removed from the specification recommendations. - type: string id: description: A unique identifier for the Relying Party entity, which sets the RP ID. @@ -323,17 +355,6 @@ definitions: For example, "Alex P. Müller" or "田中 倫". The Relying Party SHOULD let the user choose this, and SHOULD NOT restrict the choice more than necessary. type: string - icon: - description: |- - A serialized URL which resolves to an image associated with the entity. For example, - this could be a user’s avatar or a Relying Party's logo. This URL MUST be an a priori - authenticated URL. Authenticators MUST accept and store a 128-byte minimum length for - an icon member’s value. Authenticators MAY ignore an icon member’s value if its length - is greater than 128 bytes. The URL’s scheme MAY be "data" to avoid fetches of the URL, - at the cost of needing more storage. - - Deprecated: this has been removed from the specification recommendations. - type: string id: description: |- ID is the user handle of the user account entity. To ensure secure operation, @@ -399,7 +420,44 @@ definitions: init_code: type: string type: object - seedworks.Registration: + seedworks.Chain: + enum: + - ethereum-mainnet + - ethereum-sepolia + - optimism-mainnet + - optimism-sepolia + - arbitrum-one + - arbitrum-nova + - arbitrum-sepolia + - scroll-mainnet + - scroll-sepolia + - starknet-mainnet + - starknet-sepolia + - base-mainnet + - base-sepolia + type: string + x-enum-varnames: + - EthereumMainnet + - EthereumSepolia + - OptimismMainnet + - OptimismSepolia + - ArbitrumOne + - ArbitrumNova + - ArbitrumSpeolia + - ScrollMainnet + - ScrollSepolia + - StarketMainnet + - StarketSepolia + - BaseMainnet + - BaseSepolia + seedworks.CreateAARequest: + properties: + alias: + type: string + network: + $ref: '#/definitions/seedworks.Chain' + type: object + seedworks.RegistrationByEmail: properties: captcha: type: string @@ -408,31 +466,28 @@ definitions: origin: type: string type: object - seedworks.RegistrationPrepare: - properties: - email: - type: string - type: object seedworks.SiginIn: properties: - captcha: - type: string - email: - type: string origin: type: string type: object seedworks.TxSignature: properties: - nonce: + network: + $ref: '#/definitions/seedworks.Chain' + network_alias: type: string origin: type: string + ticket: + type: string txdata: type: string type: object seedworks.TxSignatureResult: properties: + address: + type: string code: type: integer sign: @@ -557,6 +612,26 @@ paths: description: OK tags: - Healthz + /api/passkey/v1/account/chain: + post: + consumes: + - application/json + description: create aa by sepcify network(chain) + parameters: + - description: Create AA + in: body + name: createAABody + required: true + schema: + $ref: '#/definitions/seedworks.CreateAARequest' + responses: + "200": + description: OK + security: + - JWT: [] + summary: Create AA with Alias, default empty + tags: + - Plugins Passkey /api/passkey/v1/account/info: get: consumes: @@ -568,6 +643,10 @@ paths: name: network required: true type: string + - description: alias + in: query + name: alias + type: string produces: - application/json responses: @@ -581,7 +660,18 @@ paths: type: object security: - JWT: [] - summary: get user account info + summary: Get User Account Info + tags: + - Plugins Passkey + /api/passkey/v1/chains/support: + get: + consumes: + - application/json + description: get support chains + responses: + "200": + description: OK + summary: Get support chains in relay party tags: - Plugins Passkey /api/passkey/v1/imauthz: @@ -611,7 +701,7 @@ paths: name: registrationBody required: true schema: - $ref: '#/definitions/seedworks.Registration' + $ref: '#/definitions/seedworks.RegistrationByEmail' responses: "200": description: OK @@ -631,7 +721,7 @@ paths: name: registrationBody required: true schema: - $ref: '#/definitions/seedworks.RegistrationPrepare' + $ref: '#/definitions/seedworks.RegistrationByEmail' responses: "200": description: OK @@ -659,6 +749,10 @@ paths: in: query name: network type: string + - description: network + in: query + name: alias + type: string - description: Verify Registration in: body name: registrationBody @@ -670,7 +764,7 @@ paths: description: OK schema: $ref: '#/definitions/plugin_passkey_relay_party.SiginInResponse' - summary: Finish SignUp + summary: Finish SignUp By Email tags: - Plugins Passkey /api/passkey/v1/sign: @@ -713,12 +807,6 @@ paths: - application/json description: Verify attestations and return JWT parameters: - - description: user email - format: email - in: query - name: email - required: true - type: string - description: origin in: query name: origin @@ -785,11 +873,20 @@ paths: name: origin required: true type: string - - description: nonce + - description: ticket in: query - name: nonce + name: ticket required: true type: string + - description: chain network + in: query + name: network + required: true + type: string + - description: chain network alias + in: query + name: alias + type: string produces: - application/json responses: diff --git a/example/one-click-deploy/docker-compose.yaml b/example/one-click-deploy/docker-compose.yaml index 55fba79..4fcd1c4 100644 --- a/example/one-click-deploy/docker-compose.yaml +++ b/example/one-click-deploy/docker-compose.yaml @@ -11,7 +11,7 @@ services: pgadmin4: container_name: my_pgadmin4 - image: dpage/pgadmin4:8.9 + image: dpage/pgadmin4:latest restart: "always" environment: PGADMIN_DEFAULT_EMAIL: "aastar@gmail.com" diff --git a/example/webauthn-relay-test/app/api/api.ts b/example/webauthn-relay-test/app/api/api.ts index 200af1c..923922e 100644 --- a/example/webauthn-relay-test/app/api/api.ts +++ b/example/webauthn-relay-test/app/api/api.ts @@ -5,6 +5,7 @@ enum API { PASSKEY_AUTH_VERIFY = "/api/passkey/v1/sign/verify", PASSKEY_PAYMENT = "/api/passkey/v1/tx/sign", PASSKEY_PAYMENT_VERIFY = "/api/passkey/v1/tx/sign/verify", + SUPPORT_NETWORKS = "/api/passkey/v1/chains/support", } export default API; diff --git a/example/webauthn-relay-test/app/form.tsx b/example/webauthn-relay-test/app/form.tsx index b23a623..2b43130 100644 --- a/example/webauthn-relay-test/app/form.tsx +++ b/example/webauthn-relay-test/app/form.tsx @@ -1,32 +1,36 @@ export function Form({ action, children, + isDiscoverable, }: { action: any; children: React.ReactNode; + isDiscoverable: boolean; }) { return (
-
- - -
+ {!isDiscoverable && ( +
+ + +
+ )} {children}
); diff --git a/example/webauthn-relay-test/app/loginform.tsx b/example/webauthn-relay-test/app/loginform.tsx index 70b4661..a1a0cde 100644 --- a/example/webauthn-relay-test/app/loginform.tsx +++ b/example/webauthn-relay-test/app/loginform.tsx @@ -9,7 +9,10 @@ export default function LoginForm() {
{browserSupportsWebAuthn() ? (
abc
} + isDiscoverable={true} + action={ + browserSupportsWebAuthn() ? PasskeyLogin :
not support
+ } > Sign in

diff --git a/example/webauthn-relay-test/app/passkey.tsx b/example/webauthn-relay-test/app/passkey.tsx index e9b7ddf..65b1224 100644 --- a/example/webauthn-relay-test/app/passkey.tsx +++ b/example/webauthn-relay-test/app/passkey.tsx @@ -51,8 +51,7 @@ const generateRegPasskeyPublicKey = async (email: string) => { }; export const PasskeyLogin = async (formData: FormData) => { - let email = formData.get("email") as string; - let resp = await generateAuthPasskeyPublicKey(email); + let resp = await generateAuthPasskeyPublicKey(); if (resp) { window.location.href = "/payment"; @@ -61,18 +60,14 @@ export const PasskeyLogin = async (formData: FormData) => { } }; -const generateAuthPasskeyPublicKey = async (email: string) => { +const generateAuthPasskeyPublicKey = async () => { const origin = window.location.origin; - const resp = await api.post(API.PASSKEY_AUTH, { email, origin }); + const resp = await api.post(API.PASSKEY_AUTH, { origin }); const json = resp.data.data as PublicKeyCredentialRequestOptionsJSON; if (json !== null) { const attest = await startAuthentication(json); const verifyResp = await api.post( - API.PASSKEY_AUTH_VERIFY + - "?origin=" + - encodeURIComponent(origin) + - "&email=" + - email, + API.PASSKEY_AUTH_VERIFY + "?origin=" + encodeURIComponent(origin), attest ); diff --git a/example/webauthn-relay-test/app/payment/payform.tsx b/example/webauthn-relay-test/app/payment/payform.tsx index b2872e4..95a84cb 100644 --- a/example/webauthn-relay-test/app/payment/payform.tsx +++ b/example/webauthn-relay-test/app/payment/payform.tsx @@ -1,3 +1,7 @@ +import { useEffect, useState } from "react"; +import API from "../api/api"; +import api from "../api"; + export function PayForm({ action, children, @@ -5,6 +9,27 @@ export function PayForm({ action: any; children: React.ReactNode; }) { + const [networks, setNetworks] = useState<{id: string; name: string}[]>([]); + const [selectedNetwork, setSelectedNetwork] = useState(''); + + useEffect(() => { + api.get( + API.SUPPORT_NETWORKS, + ).then(response => { + const data: { [key: string]: boolean } = response.data.data; + const networksArray = Object.keys(data) + .filter(key => data[key] === true).map(key => ({ + id: key, + name: key, + })); + setNetworks(networksArray); + }) + }, []); + + const handleNetworkChange = (event: React.ChangeEvent) => { + setSelectedNetwork(event.target.value); + }; + return ( + + {children} diff --git a/example/webauthn-relay-test/app/payment/payment.tsx b/example/webauthn-relay-test/app/payment/payment.tsx index 096bcdf..114c1cc 100644 --- a/example/webauthn-relay-test/app/payment/payment.tsx +++ b/example/webauthn-relay-test/app/payment/payment.tsx @@ -8,18 +8,20 @@ import { PublicKeyCredentialRequestOptionsJSON } from "@simplewebauthn/types"; export const PasskeyPayment = async (formData: FormData) => { await isSecurePaymentConfirmationSupported(); let txdata = formData.get("txdata") as string; - await generateAuthPasskeyPublicKey(txdata); + let network = formData.get("network") as string; + await generateAuthPasskeyPublicKey(txdata, network); }; -const generateAuthPasskeyPublicKey = async (txdata: string) => { +const generateAuthPasskeyPublicKey = async (txdata: string, network: string) => { const origin = window.location.origin; - const nonce = Math.floor(Math.random() * 100001).toString(); + const ticket = Math.floor(Math.random() * 100001).toString(); const resp = await api.post( API.PASSKEY_PAYMENT, { origin, - nonce, + ticket, txdata: txdata, + network: network, }, { headers: { @@ -40,8 +42,10 @@ const generateAuthPasskeyPublicKey = async (txdata: string) => { API.PASSKEY_PAYMENT_VERIFY + "?origin=" + encodeURIComponent(origin) + - "&nonce=" + - nonce, + "&ticket=" + + ticket + + "&network=" + + network, attest, { headers: { diff --git a/example/webauthn-relay-test/package-lock.json b/example/webauthn-relay-test/package-lock.json index 37e160b..b8c18e7 100644 --- a/example/webauthn-relay-test/package-lock.json +++ b/example/webauthn-relay-test/package-lock.json @@ -4,6 +4,7 @@ "requires": true, "packages": { "": { + "license": "MIT", "dependencies": { "@simplewebauthn/browser": "^10.0.0", "@simplewebauthn/types": "^10.0.0", @@ -991,9 +992,9 @@ } }, "node_modules/axios": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz", - "integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==", + "version": "1.7.7", + "resolved": "https://registry.npmmirror.com/axios/-/axios-1.7.7.tgz", + "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -5364,6 +5365,126 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/@next/swc-darwin-x64": { + "version": "14.2.5", + "resolved": "https://registry.npmmirror.com/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.5.tgz", + "integrity": "sha512-vXHOPCwfDe9qLDuq7U1OYM2wUY+KQ4Ex6ozwsKxp26BlJ6XXbHleOUldenM67JRyBfVjv371oneEvYd3H2gNSA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "14.2.5", + "resolved": "https://registry.npmmirror.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.5.tgz", + "integrity": "sha512-vlhB8wI+lj8q1ExFW8lbWutA4M2ZazQNvMWuEDqZcuJJc78iUnLdPPunBPX8rC4IgT6lIx/adB+Cwrl99MzNaA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "14.2.5", + "resolved": "https://registry.npmmirror.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.5.tgz", + "integrity": "sha512-NpDB9NUR2t0hXzJJwQSGu1IAOYybsfeB+LxpGsXrRIb7QOrYmidJz3shzY8cM6+rO4Aojuef0N/PEaX18pi9OA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "14.2.5", + "resolved": "https://registry.npmmirror.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.5.tgz", + "integrity": "sha512-8XFikMSxWleYNryWIjiCX+gU201YS+erTUidKdyOVYi5qUQo/gRxv/3N1oZFCgqpesN6FPeqGM72Zve+nReVXQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "14.2.5", + "resolved": "https://registry.npmmirror.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.5.tgz", + "integrity": "sha512-6QLwi7RaYiQDcRDSU/os40r5o06b5ue7Jsk5JgdRBGGp8l37RZEh9JsLSM8QF0YDsgcosSeHjglgqi25+m04IQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "14.2.5", + "resolved": "https://registry.npmmirror.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.5.tgz", + "integrity": "sha512-1GpG2VhbspO+aYoMOQPQiqc/tG3LzmsdBH0LhnDS3JrtDx2QmzXe0B6mSZZiN3Bq7IOMXxv1nlsjzoS1+9mzZw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-ia32-msvc": { + "version": "14.2.5", + "resolved": "https://registry.npmmirror.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.5.tgz", + "integrity": "sha512-Igh9ZlxwvCDsu6438FXlQTHlRno4gFpJzqPjSIBZooD22tKeI4fE/YMRoHVJHmrQ2P5YL1DoZ0qaOKkbeFWeMg==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "14.2.5", + "resolved": "https://registry.npmmirror.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.5.tgz", + "integrity": "sha512-tEQ7oinq1/CjSG9uSTerca3v4AZ+dFa+4Yu6ihaG8Ud8ddqLQgFGcnwYls13H5X5CPDPZJdYxyeMui6muOLd4g==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } } } } diff --git a/example/webauthn-relay-test/package.json b/example/webauthn-relay-test/package.json index 666bfcd..9e4255d 100644 --- a/example/webauthn-relay-test/package.json +++ b/example/webauthn-relay-test/package.json @@ -1,5 +1,6 @@ { "private": true, + "license": "MIT", "scripts": { "dev": "next dev --turbo", "build": "next build", diff --git a/example/webauthn-relay-test/yarn.lock b/example/webauthn-relay-test/yarn.lock new file mode 100644 index 0000000..89c7f89 --- /dev/null +++ b/example/webauthn-relay-test/yarn.lock @@ -0,0 +1,2908 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@alloc/quick-lru@^5.2.0": + version "5.2.0" + resolved "https://registry.npmmirror.com/@alloc/quick-lru/-/quick-lru-5.2.0.tgz" + integrity sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw== + +"@auth/core@0.18.4": + version "0.18.4" + resolved "https://registry.npmmirror.com/@auth/core/-/core-0.18.4.tgz" + integrity sha512-GsNhsP1xE/3FoNS3dVkPjqRljLNJ4iyL2OLv3klQGNvw3bMpROFcK4lqhx7+pPHiamnVaYt2vg1xbB+lsNaevg== + dependencies: + "@panva/hkdf" "^1.1.1" + cookie "0.6.0" + jose "^5.1.0" + oauth4webapi "^2.3.0" + preact "10.11.3" + preact-render-to-string "5.2.3" + +"@eslint-community/eslint-utils@^4.2.0": + version "4.4.0" + resolved "https://registry.npmmirror.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz" + integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== + dependencies: + eslint-visitor-keys "^3.3.0" + +"@eslint-community/regexpp@^4.6.1": + version "4.11.0" + resolved "https://registry.npmmirror.com/@eslint-community/regexpp/-/regexpp-4.11.0.tgz" + integrity sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A== + +"@eslint/eslintrc@^2.1.4": + version "2.1.4" + resolved "https://registry.npmmirror.com/@eslint/eslintrc/-/eslintrc-2.1.4.tgz" + integrity sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ== + dependencies: + ajv "^6.12.4" + debug "^4.3.2" + espree "^9.6.0" + globals "^13.19.0" + ignore "^5.2.0" + import-fresh "^3.2.1" + js-yaml "^4.1.0" + minimatch "^3.1.2" + strip-json-comments "^3.1.1" + +"@eslint/js@8.56.0": + version "8.56.0" + resolved "https://registry.npmmirror.com/@eslint/js/-/js-8.56.0.tgz" + integrity sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A== + +"@humanwhocodes/config-array@^0.11.13": + version "0.11.14" + resolved "https://registry.npmmirror.com/@humanwhocodes/config-array/-/config-array-0.11.14.tgz" + integrity sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg== + dependencies: + "@humanwhocodes/object-schema" "^2.0.2" + debug "^4.3.1" + minimatch "^3.0.5" + +"@humanwhocodes/module-importer@^1.0.1": + version "1.0.1" + resolved "https://registry.npmmirror.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz" + integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== + +"@humanwhocodes/object-schema@^2.0.2": + version "2.0.3" + resolved "https://registry.npmmirror.com/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz" + integrity sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA== + +"@isaacs/cliui@^8.0.2": + version "8.0.2" + resolved "https://registry.npmmirror.com/@isaacs/cliui/-/cliui-8.0.2.tgz" + integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== + dependencies: + string-width "^5.1.2" + string-width-cjs "npm:string-width@^4.2.0" + strip-ansi "^7.0.1" + strip-ansi-cjs "npm:strip-ansi@^6.0.1" + wrap-ansi "^8.1.0" + wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" + +"@jridgewell/gen-mapping@^0.3.2": + version "0.3.5" + resolved "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz" + integrity sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg== + dependencies: + "@jridgewell/set-array" "^1.2.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.24" + +"@jridgewell/resolve-uri@^3.1.0": + version "3.1.2" + resolved "https://registry.npmmirror.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz" + integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== + +"@jridgewell/set-array@^1.2.1": + version "1.2.1" + resolved "https://registry.npmmirror.com/@jridgewell/set-array/-/set-array-1.2.1.tgz" + integrity sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A== + +"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14": + version "1.5.0" + resolved "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz" + integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ== + +"@jridgewell/trace-mapping@^0.3.24": + version "0.3.25" + resolved "https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz" + integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== + dependencies: + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" + +"@next/env@14.2.5": + version "14.2.5" + resolved "https://registry.npmmirror.com/@next/env/-/env-14.2.5.tgz" + integrity sha512-/zZGkrTOsraVfYjGP8uM0p6r0BDT6xWpkjdVbcz66PJVSpwXX3yNiRycxAuDfBKGWBrZBXRuK/YVlkNgxHGwmA== + +"@next/eslint-plugin-next@14.2.5": + version "14.2.5" + resolved "https://registry.npmmirror.com/@next/eslint-plugin-next/-/eslint-plugin-next-14.2.5.tgz" + integrity sha512-LY3btOpPh+OTIpviNojDpUdIbHW9j0JBYBjsIp8IxtDFfYFyORvw3yNq6N231FVqQA7n7lwaf7xHbVJlA1ED7g== + dependencies: + glob "10.3.10" + +"@next/swc-darwin-arm64@14.2.5": + version "14.2.5" + resolved "https://registry.npmmirror.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.5.tgz" + integrity sha512-/9zVxJ+K9lrzSGli1///ujyRfon/ZneeZ+v4ptpiPoOU+GKZnm8Wj8ELWU1Pm7GHltYRBklmXMTUqM/DqQ99FQ== + +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.npmmirror.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5": + version "2.0.5" + resolved "https://registry.npmmirror.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": + version "1.2.8" + resolved "https://registry.npmmirror.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + +"@panva/hkdf@^1.1.1": + version "1.2.1" + resolved "https://registry.npmmirror.com/@panva/hkdf/-/hkdf-1.2.1.tgz" + integrity sha512-6oclG6Y3PiDFcoyk8srjLfVKyMfVCKJ27JwNPViuXziFpmdz+MZnZN/aKY0JGXgYuO/VghU0jcOAZgWXZ1Dmrw== + +"@pkgjs/parseargs@^0.11.0": + version "0.11.0" + resolved "https://registry.npmmirror.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz" + integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== + +"@rushstack/eslint-patch@^1.3.3": + version "1.10.3" + resolved "https://registry.npmmirror.com/@rushstack/eslint-patch/-/eslint-patch-1.10.3.tgz" + integrity sha512-qC/xYId4NMebE6w/V33Fh9gWxLgURiNYgVNObbJl2LZv0GUUItCcCqC5axQSwRaAgaxl2mELq1rMzlswaQ0Zxg== + +"@simplewebauthn/browser@^10.0.0": + version "10.0.0" + resolved "https://registry.npmmirror.com/@simplewebauthn/browser/-/browser-10.0.0.tgz" + integrity sha512-hG0JMZD+LiLUbpQcAjS4d+t4gbprE/dLYop/CkE01ugU/9sKXflxV5s0DRjdz3uNMFecatRfb4ZLG3XvF8m5zg== + dependencies: + "@simplewebauthn/types" "^10.0.0" + +"@simplewebauthn/types@^10.0.0": + version "10.0.0" + resolved "https://registry.npmmirror.com/@simplewebauthn/types/-/types-10.0.0.tgz" + integrity sha512-SFXke7xkgPRowY2E+8djKbdEznTVnD5R6GO7GPTthpHrokLvNKw8C3lFZypTxLI7KkCfGPfhtqB3d7OVGGa9jQ== + +"@swc/counter@^0.1.3": + version "0.1.3" + resolved "https://registry.npmmirror.com/@swc/counter/-/counter-0.1.3.tgz" + integrity sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ== + +"@swc/helpers@0.5.5": + version "0.5.5" + resolved "https://registry.npmmirror.com/@swc/helpers/-/helpers-0.5.5.tgz" + integrity sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A== + dependencies: + "@swc/counter" "^0.1.3" + tslib "^2.4.0" + +"@types/json5@^0.0.29": + version "0.0.29" + resolved "https://registry.npmmirror.com/@types/json5/-/json5-0.0.29.tgz" + integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== + +"@types/node@^20.14.10": + version "20.14.10" + resolved "https://registry.npmmirror.com/@types/node/-/node-20.14.10.tgz" + integrity sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ== + dependencies: + undici-types "~5.26.4" + +"@types/prop-types@*": + version "15.7.12" + resolved "https://registry.npmmirror.com/@types/prop-types/-/prop-types-15.7.12.tgz" + integrity sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q== + +"@types/react-dom@^18.3.0": + version "18.3.0" + resolved "https://registry.npmmirror.com/@types/react-dom/-/react-dom-18.3.0.tgz" + integrity sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg== + dependencies: + "@types/react" "*" + +"@types/react@*", "@types/react@^18.3.3", "@types/react@>=18": + version "18.3.3" + resolved "https://registry.npmmirror.com/@types/react/-/react-18.3.3.tgz" + integrity sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw== + dependencies: + "@types/prop-types" "*" + csstype "^3.0.2" + +"@typescript-eslint/parser@^5.4.2 || ^6.0.0 || 7.0.0 - 7.2.0": + version "7.2.0" + resolved "https://registry.npmmirror.com/@typescript-eslint/parser/-/parser-7.2.0.tgz" + integrity sha512-5FKsVcHTk6TafQKQbuIVkXq58Fnbkd2wDL4LB7AURN7RUOu1utVP+G8+6u3ZhEroW3DF6hyo3ZEXxgKgp4KeCg== + dependencies: + "@typescript-eslint/scope-manager" "7.2.0" + "@typescript-eslint/types" "7.2.0" + "@typescript-eslint/typescript-estree" "7.2.0" + "@typescript-eslint/visitor-keys" "7.2.0" + debug "^4.3.4" + +"@typescript-eslint/scope-manager@7.2.0": + version "7.2.0" + resolved "https://registry.npmmirror.com/@typescript-eslint/scope-manager/-/scope-manager-7.2.0.tgz" + integrity sha512-Qh976RbQM/fYtjx9hs4XkayYujB/aPwglw2choHmf3zBjB4qOywWSdt9+KLRdHubGcoSwBnXUH2sR3hkyaERRg== + dependencies: + "@typescript-eslint/types" "7.2.0" + "@typescript-eslint/visitor-keys" "7.2.0" + +"@typescript-eslint/types@7.2.0": + version "7.2.0" + resolved "https://registry.npmmirror.com/@typescript-eslint/types/-/types-7.2.0.tgz" + integrity sha512-XFtUHPI/abFhm4cbCDc5Ykc8npOKBSJePY3a3s+lwumt7XWJuzP5cZcfZ610MIPHjQjNsOLlYK8ASPaNG8UiyA== + +"@typescript-eslint/typescript-estree@7.2.0": + version "7.2.0" + resolved "https://registry.npmmirror.com/@typescript-eslint/typescript-estree/-/typescript-estree-7.2.0.tgz" + integrity sha512-cyxS5WQQCoBwSakpMrvMXuMDEbhOo9bNHHrNcEWis6XHx6KF518tkF1wBvKIn/tpq5ZpUYK7Bdklu8qY0MsFIA== + dependencies: + "@typescript-eslint/types" "7.2.0" + "@typescript-eslint/visitor-keys" "7.2.0" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + minimatch "9.0.3" + semver "^7.5.4" + ts-api-utils "^1.0.1" + +"@typescript-eslint/visitor-keys@7.2.0": + version "7.2.0" + resolved "https://registry.npmmirror.com/@typescript-eslint/visitor-keys/-/visitor-keys-7.2.0.tgz" + integrity sha512-c6EIQRHhcpl6+tO8EMR+kjkkV+ugUNXOmeASA1rlzkd8EPIriavpWoiEz1HR/VLhbVIdhqnV6E7JZm00cBDx2A== + dependencies: + "@typescript-eslint/types" "7.2.0" + eslint-visitor-keys "^3.4.1" + +"@ungap/structured-clone@^1.2.0": + version "1.2.0" + resolved "https://registry.npmmirror.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz" + integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== + +acorn-jsx@^5.3.2: + version "5.3.2" + resolved "https://registry.npmmirror.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz" + integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== + +"acorn@^6.0.0 || ^7.0.0 || ^8.0.0", acorn@^8.9.0: + version "8.12.1" + resolved "https://registry.npmmirror.com/acorn/-/acorn-8.12.1.tgz" + integrity sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg== + +ajv@^6.12.4: + version "6.12.6" + resolved "https://registry.npmmirror.com/ajv/-/ajv-6.12.6.tgz" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-regex@^6.0.1: + version "6.0.1" + resolved "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-6.0.1.tgz" + integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +ansi-styles@^6.1.0: + version "6.2.1" + resolved "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-6.2.1.tgz" + integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== + +any-promise@^1.0.0: + version "1.3.0" + resolved "https://registry.npmmirror.com/any-promise/-/any-promise-1.3.0.tgz" + integrity sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A== + +anymatch@~3.1.2: + version "3.1.3" + resolved "https://registry.npmmirror.com/anymatch/-/anymatch-3.1.3.tgz" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +arg@^5.0.2: + version "5.0.2" + resolved "https://registry.npmmirror.com/arg/-/arg-5.0.2.tgz" + integrity sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg== + +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.npmmirror.com/argparse/-/argparse-2.0.1.tgz" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + +aria-query@~5.1.3: + version "5.1.3" + resolved "https://registry.npmmirror.com/aria-query/-/aria-query-5.1.3.tgz" + integrity sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ== + dependencies: + deep-equal "^2.0.5" + +array-buffer-byte-length@^1.0.0, array-buffer-byte-length@^1.0.1: + version "1.0.1" + resolved "https://registry.npmmirror.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz" + integrity sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg== + dependencies: + call-bind "^1.0.5" + is-array-buffer "^3.0.4" + +array-includes@^3.1.6, array-includes@^3.1.7, array-includes@^3.1.8: + version "3.1.8" + resolved "https://registry.npmmirror.com/array-includes/-/array-includes-3.1.8.tgz" + integrity sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.2" + es-object-atoms "^1.0.0" + get-intrinsic "^1.2.4" + is-string "^1.0.7" + +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.npmmirror.com/array-union/-/array-union-2.1.0.tgz" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + +array.prototype.findlast@^1.2.5: + version "1.2.5" + resolved "https://registry.npmmirror.com/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz" + integrity sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.2" + es-errors "^1.3.0" + es-object-atoms "^1.0.0" + es-shim-unscopables "^1.0.2" + +array.prototype.findlastindex@^1.2.3: + version "1.2.5" + resolved "https://registry.npmmirror.com/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz" + integrity sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.2" + es-errors "^1.3.0" + es-object-atoms "^1.0.0" + es-shim-unscopables "^1.0.2" + +array.prototype.flat@^1.3.1, array.prototype.flat@^1.3.2: + version "1.3.2" + resolved "https://registry.npmmirror.com/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz" + integrity sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + es-shim-unscopables "^1.0.0" + +array.prototype.flatmap@^1.3.2: + version "1.3.2" + resolved "https://registry.npmmirror.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz" + integrity sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + es-shim-unscopables "^1.0.0" + +array.prototype.toreversed@^1.1.2: + version "1.1.2" + resolved "https://registry.npmmirror.com/array.prototype.toreversed/-/array.prototype.toreversed-1.1.2.tgz" + integrity sha512-wwDCoT4Ck4Cz7sLtgUmzR5UV3YF5mFHUlbChCzZBQZ+0m2cl/DH3tKgvphv1nKgFsJ48oCSg6p91q2Vm0I/ZMA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + es-shim-unscopables "^1.0.0" + +array.prototype.tosorted@^1.1.4: + version "1.1.4" + resolved "https://registry.npmmirror.com/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz" + integrity sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.3" + es-errors "^1.3.0" + es-shim-unscopables "^1.0.2" + +arraybuffer.prototype.slice@^1.0.3: + version "1.0.3" + resolved "https://registry.npmmirror.com/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz" + integrity sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A== + dependencies: + array-buffer-byte-length "^1.0.1" + call-bind "^1.0.5" + define-properties "^1.2.1" + es-abstract "^1.22.3" + es-errors "^1.2.1" + get-intrinsic "^1.2.3" + is-array-buffer "^3.0.4" + is-shared-array-buffer "^1.0.2" + +ast-types-flow@^0.0.8: + version "0.0.8" + resolved "https://registry.npmmirror.com/ast-types-flow/-/ast-types-flow-0.0.8.tgz" + integrity sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ== + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz" + integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== + +autoprefixer@^10.4.19: + version "10.4.19" + resolved "https://registry.npmmirror.com/autoprefixer/-/autoprefixer-10.4.19.tgz" + integrity sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew== + dependencies: + browserslist "^4.23.0" + caniuse-lite "^1.0.30001599" + fraction.js "^4.3.7" + normalize-range "^0.1.2" + picocolors "^1.0.0" + postcss-value-parser "^4.2.0" + +available-typed-arrays@^1.0.7: + version "1.0.7" + resolved "https://registry.npmmirror.com/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz" + integrity sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ== + dependencies: + possible-typed-array-names "^1.0.0" + +axe-core@^4.9.1: + version "4.9.1" + resolved "https://registry.npmmirror.com/axe-core/-/axe-core-4.9.1.tgz" + integrity sha512-QbUdXJVTpvUTHU7871ppZkdOLBeGUKBQWHkHrvN2V9IQWGMt61zf3B45BtzjxEJzYuj0JBjBZP/hmYS/R9pmAw== + +axios@^1.7.4: + version "1.7.7" + resolved "https://registry.npmmirror.com/axios/-/axios-1.7.7.tgz" + integrity sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q== + dependencies: + follow-redirects "^1.15.6" + form-data "^4.0.0" + proxy-from-env "^1.1.0" + +axobject-query@~3.1.1: + version "3.1.1" + resolved "https://registry.npmmirror.com/axobject-query/-/axobject-query-3.1.1.tgz" + integrity sha512-goKlv8DZrK9hUh975fnHzhNIO4jUnFCfv/dszV5VwUGDFjI6vQ2VwoyjYjYNEbBE8AH87TduWP5uyDR1D+Iteg== + dependencies: + deep-equal "^2.0.5" + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +bcrypt-ts@^5.0.2: + version "5.0.2" + resolved "https://registry.npmmirror.com/bcrypt-ts/-/bcrypt-ts-5.0.2.tgz" + integrity sha512-gDwQ5784AkkfhHACh3jGcg1hUubyZyeq9AtVd5gXkcyHGVOC+mORjRIHSj+fHfqwY5vxwyBLXQpcfk8MpK0ROg== + +binary-extensions@^2.0.0: + version "2.3.0" + resolved "https://registry.npmmirror.com/binary-extensions/-/binary-extensions-2.3.0.tgz" + integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw== + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-1.1.11.tgz" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.0.1.tgz" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + +braces@^3.0.3, braces@~3.0.2: + version "3.0.3" + resolved "https://registry.npmmirror.com/braces/-/braces-3.0.3.tgz" + integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== + dependencies: + fill-range "^7.1.1" + +browserslist@^4.23.0, "browserslist@>= 4.21.0": + version "4.23.2" + resolved "https://registry.npmmirror.com/browserslist/-/browserslist-4.23.2.tgz" + integrity sha512-qkqSyistMYdxAcw+CzbZwlBy8AGmS/eEWs+sEV5TnLRGDOL+C5M2EnH6tlZyg0YoAxGJAFKh61En9BR941GnHA== + dependencies: + caniuse-lite "^1.0.30001640" + electron-to-chromium "^1.4.820" + node-releases "^2.0.14" + update-browserslist-db "^1.1.0" + +busboy@1.6.0: + version "1.6.0" + resolved "https://registry.npmmirror.com/busboy/-/busboy-1.6.0.tgz" + integrity sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA== + dependencies: + streamsearch "^1.1.0" + +call-bind@^1.0.2, call-bind@^1.0.5, call-bind@^1.0.6, call-bind@^1.0.7: + version "1.0.7" + resolved "https://registry.npmmirror.com/call-bind/-/call-bind-1.0.7.tgz" + integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w== + dependencies: + es-define-property "^1.0.0" + es-errors "^1.3.0" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" + set-function-length "^1.2.1" + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.npmmirror.com/callsites/-/callsites-3.1.0.tgz" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +camelcase-css@^2.0.1: + version "2.0.1" + resolved "https://registry.npmmirror.com/camelcase-css/-/camelcase-css-2.0.1.tgz" + integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA== + +caniuse-lite@^1.0.30001579, caniuse-lite@^1.0.30001599, caniuse-lite@^1.0.30001640: + version "1.0.30001642" + resolved "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001642.tgz" + integrity sha512-3XQ0DoRgLijXJErLSl+bLnJ+Et4KqV1PY6JJBGAFlsNsz31zeAIncyeZfLCabHK/jtSh+671RM9YMldxjUPZtA== + +chalk@^4.0.0: + version "4.1.2" + resolved "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chokidar@^3.5.3: + version "3.6.0" + resolved "https://registry.npmmirror.com/chokidar/-/chokidar-3.6.0.tgz" + integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +client-only@0.0.1: + version "0.0.1" + resolved "https://registry.npmmirror.com/client-only/-/client-only-0.0.1.tgz" + integrity sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA== + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +combined-stream@^1.0.8: + version "1.0.8" + resolved "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +commander@^4.0.0: + version "4.1.1" + resolved "https://registry.npmmirror.com/commander/-/commander-4.1.1.tgz" + integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.npmmirror.com/concat-map/-/concat-map-0.0.1.tgz" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +cookie@0.6.0: + version "0.6.0" + resolved "https://registry.npmmirror.com/cookie/-/cookie-0.6.0.tgz" + integrity sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw== + +cross-spawn@^7.0.0, cross-spawn@^7.0.2: + version "7.0.3" + resolved "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.3.tgz" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +cssesc@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/cssesc/-/cssesc-3.0.0.tgz" + integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== + +csstype@^3.0.2: + version "3.1.3" + resolved "https://registry.npmmirror.com/csstype/-/csstype-3.1.3.tgz" + integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== + +damerau-levenshtein@^1.0.8: + version "1.0.8" + resolved "https://registry.npmmirror.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz" + integrity sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA== + +data-view-buffer@^1.0.1: + version "1.0.1" + resolved "https://registry.npmmirror.com/data-view-buffer/-/data-view-buffer-1.0.1.tgz" + integrity sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA== + dependencies: + call-bind "^1.0.6" + es-errors "^1.3.0" + is-data-view "^1.0.1" + +data-view-byte-length@^1.0.1: + version "1.0.1" + resolved "https://registry.npmmirror.com/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz" + integrity sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ== + dependencies: + call-bind "^1.0.7" + es-errors "^1.3.0" + is-data-view "^1.0.1" + +data-view-byte-offset@^1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz" + integrity sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA== + dependencies: + call-bind "^1.0.6" + es-errors "^1.3.0" + is-data-view "^1.0.1" + +debug@^3.2.7: + version "3.2.7" + resolved "https://registry.npmmirror.com/debug/-/debug-3.2.7.tgz" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" + +debug@^4.3.1, debug@^4.3.2, debug@^4.3.4: + version "4.3.5" + resolved "https://registry.npmmirror.com/debug/-/debug-4.3.5.tgz" + integrity sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg== + dependencies: + ms "2.1.2" + +deep-equal@^2.0.5: + version "2.2.3" + resolved "https://registry.npmmirror.com/deep-equal/-/deep-equal-2.2.3.tgz" + integrity sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA== + dependencies: + array-buffer-byte-length "^1.0.0" + call-bind "^1.0.5" + es-get-iterator "^1.1.3" + get-intrinsic "^1.2.2" + is-arguments "^1.1.1" + is-array-buffer "^3.0.2" + is-date-object "^1.0.5" + is-regex "^1.1.4" + is-shared-array-buffer "^1.0.2" + isarray "^2.0.5" + object-is "^1.1.5" + object-keys "^1.1.1" + object.assign "^4.1.4" + regexp.prototype.flags "^1.5.1" + side-channel "^1.0.4" + which-boxed-primitive "^1.0.2" + which-collection "^1.0.1" + which-typed-array "^1.1.13" + +deep-is@^0.1.3: + version "0.1.4" + resolved "https://registry.npmmirror.com/deep-is/-/deep-is-0.1.4.tgz" + integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== + +define-data-property@^1.0.1, define-data-property@^1.1.4: + version "1.1.4" + resolved "https://registry.npmmirror.com/define-data-property/-/define-data-property-1.1.4.tgz" + integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A== + dependencies: + es-define-property "^1.0.0" + es-errors "^1.3.0" + gopd "^1.0.1" + +define-properties@^1.1.3, define-properties@^1.2.0, define-properties@^1.2.1: + version "1.2.1" + resolved "https://registry.npmmirror.com/define-properties/-/define-properties-1.2.1.tgz" + integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg== + dependencies: + define-data-property "^1.0.1" + has-property-descriptors "^1.0.0" + object-keys "^1.1.1" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz" + integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== + +didyoumean@^1.2.2: + version "1.2.2" + resolved "https://registry.npmmirror.com/didyoumean/-/didyoumean-1.2.2.tgz" + integrity sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw== + +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.npmmirror.com/dir-glob/-/dir-glob-3.0.1.tgz" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + +dlv@^1.1.3: + version "1.1.3" + resolved "https://registry.npmmirror.com/dlv/-/dlv-1.1.3.tgz" + integrity sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA== + +doctrine@^2.1.0: + version "2.1.0" + resolved "https://registry.npmmirror.com/doctrine/-/doctrine-2.1.0.tgz" + integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== + dependencies: + esutils "^2.0.2" + +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/doctrine/-/doctrine-3.0.0.tgz" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + +drizzle-orm@^0.29.5: + version "0.29.5" + resolved "https://registry.npmmirror.com/drizzle-orm/-/drizzle-orm-0.29.5.tgz" + integrity sha512-jS3+uyzTz4P0Y2CICx8FmRQ1eplURPaIMWDn/yq6k4ShRFj9V7vlJk67lSf2kyYPzQ60GkkNGXcJcwrxZ6QCRw== + +eastasianwidth@^0.2.0: + version "0.2.0" + resolved "https://registry.npmmirror.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz" + integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== + +electron-to-chromium@^1.4.820: + version "1.4.827" + resolved "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.4.827.tgz" + integrity sha512-VY+J0e4SFcNfQy19MEoMdaIcZLmDCprqvBtkii1WTCTQHpRvf5N8+3kTYCgL/PcntvwQvmMJWTuDPsq+IlhWKQ== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +emoji-regex@^9.2.2: + version "9.2.2" + resolved "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-9.2.2.tgz" + integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== + +enhanced-resolve@^5.12.0: + version "5.17.0" + resolved "https://registry.npmmirror.com/enhanced-resolve/-/enhanced-resolve-5.17.0.tgz" + integrity sha512-dwDPwZL0dmye8Txp2gzFmA6sxALaSvdRDjPH0viLcKrtlOL3tw62nWWweVD1SdILDTJrbrL6tdWVN58Wo6U3eA== + dependencies: + graceful-fs "^4.2.4" + tapable "^2.2.0" + +es-abstract@^1.17.5, es-abstract@^1.22.1, es-abstract@^1.22.3, es-abstract@^1.23.0, es-abstract@^1.23.1, es-abstract@^1.23.2, es-abstract@^1.23.3: + version "1.23.3" + resolved "https://registry.npmmirror.com/es-abstract/-/es-abstract-1.23.3.tgz" + integrity sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A== + dependencies: + array-buffer-byte-length "^1.0.1" + arraybuffer.prototype.slice "^1.0.3" + available-typed-arrays "^1.0.7" + call-bind "^1.0.7" + data-view-buffer "^1.0.1" + data-view-byte-length "^1.0.1" + data-view-byte-offset "^1.0.0" + es-define-property "^1.0.0" + es-errors "^1.3.0" + es-object-atoms "^1.0.0" + es-set-tostringtag "^2.0.3" + es-to-primitive "^1.2.1" + function.prototype.name "^1.1.6" + get-intrinsic "^1.2.4" + get-symbol-description "^1.0.2" + globalthis "^1.0.3" + gopd "^1.0.1" + has-property-descriptors "^1.0.2" + has-proto "^1.0.3" + has-symbols "^1.0.3" + hasown "^2.0.2" + internal-slot "^1.0.7" + is-array-buffer "^3.0.4" + is-callable "^1.2.7" + is-data-view "^1.0.1" + is-negative-zero "^2.0.3" + is-regex "^1.1.4" + is-shared-array-buffer "^1.0.3" + is-string "^1.0.7" + is-typed-array "^1.1.13" + is-weakref "^1.0.2" + object-inspect "^1.13.1" + object-keys "^1.1.1" + object.assign "^4.1.5" + regexp.prototype.flags "^1.5.2" + safe-array-concat "^1.1.2" + safe-regex-test "^1.0.3" + string.prototype.trim "^1.2.9" + string.prototype.trimend "^1.0.8" + string.prototype.trimstart "^1.0.8" + typed-array-buffer "^1.0.2" + typed-array-byte-length "^1.0.1" + typed-array-byte-offset "^1.0.2" + typed-array-length "^1.0.6" + unbox-primitive "^1.0.2" + which-typed-array "^1.1.15" + +es-define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/es-define-property/-/es-define-property-1.0.0.tgz" + integrity sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ== + dependencies: + get-intrinsic "^1.2.4" + +es-errors@^1.2.1, es-errors@^1.3.0: + version "1.3.0" + resolved "https://registry.npmmirror.com/es-errors/-/es-errors-1.3.0.tgz" + integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== + +es-get-iterator@^1.1.3: + version "1.1.3" + resolved "https://registry.npmmirror.com/es-get-iterator/-/es-get-iterator-1.1.3.tgz" + integrity sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.3" + has-symbols "^1.0.3" + is-arguments "^1.1.1" + is-map "^2.0.2" + is-set "^2.0.2" + is-string "^1.0.7" + isarray "^2.0.5" + stop-iteration-iterator "^1.0.0" + +es-iterator-helpers@^1.0.19: + version "1.0.19" + resolved "https://registry.npmmirror.com/es-iterator-helpers/-/es-iterator-helpers-1.0.19.tgz" + integrity sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.3" + es-errors "^1.3.0" + es-set-tostringtag "^2.0.3" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" + globalthis "^1.0.3" + has-property-descriptors "^1.0.2" + has-proto "^1.0.3" + has-symbols "^1.0.3" + internal-slot "^1.0.7" + iterator.prototype "^1.1.2" + safe-array-concat "^1.1.2" + +es-object-atoms@^1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/es-object-atoms/-/es-object-atoms-1.0.0.tgz" + integrity sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw== + dependencies: + es-errors "^1.3.0" + +es-set-tostringtag@^2.0.3: + version "2.0.3" + resolved "https://registry.npmmirror.com/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz" + integrity sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ== + dependencies: + get-intrinsic "^1.2.4" + has-tostringtag "^1.0.2" + hasown "^2.0.1" + +es-shim-unscopables@^1.0.0, es-shim-unscopables@^1.0.2: + version "1.0.2" + resolved "https://registry.npmmirror.com/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz" + integrity sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw== + dependencies: + hasown "^2.0.0" + +es-to-primitive@^1.2.1: + version "1.2.1" + resolved "https://registry.npmmirror.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz" + integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + +escalade@^3.1.2: + version "3.1.2" + resolved "https://registry.npmmirror.com/escalade/-/escalade-3.1.2.tgz" + integrity sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA== + +escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +eslint-config-next@^14.2.5: + version "14.2.5" + resolved "https://registry.npmmirror.com/eslint-config-next/-/eslint-config-next-14.2.5.tgz" + integrity sha512-zogs9zlOiZ7ka+wgUnmcM0KBEDjo4Jis7kxN1jvC0N4wynQ2MIx/KBkg4mVF63J5EK4W0QMCn7xO3vNisjaAoA== + dependencies: + "@next/eslint-plugin-next" "14.2.5" + "@rushstack/eslint-patch" "^1.3.3" + "@typescript-eslint/parser" "^5.4.2 || ^6.0.0 || 7.0.0 - 7.2.0" + eslint-import-resolver-node "^0.3.6" + eslint-import-resolver-typescript "^3.5.2" + eslint-plugin-import "^2.28.1" + eslint-plugin-jsx-a11y "^6.7.1" + eslint-plugin-react "^7.33.2" + eslint-plugin-react-hooks "^4.5.0 || 5.0.0-canary-7118f5dd7-20230705" + +eslint-import-resolver-node@^0.3.6, eslint-import-resolver-node@^0.3.9: + version "0.3.9" + resolved "https://registry.npmmirror.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz" + integrity sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g== + dependencies: + debug "^3.2.7" + is-core-module "^2.13.0" + resolve "^1.22.4" + +eslint-import-resolver-typescript@^3.5.2: + version "3.6.1" + resolved "https://registry.npmmirror.com/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.6.1.tgz" + integrity sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg== + dependencies: + debug "^4.3.4" + enhanced-resolve "^5.12.0" + eslint-module-utils "^2.7.4" + fast-glob "^3.3.1" + get-tsconfig "^4.5.0" + is-core-module "^2.11.0" + is-glob "^4.0.3" + +eslint-module-utils@^2.7.4, eslint-module-utils@^2.8.0: + version "2.8.1" + resolved "https://registry.npmmirror.com/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz" + integrity sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q== + dependencies: + debug "^3.2.7" + +eslint-plugin-import@*, eslint-plugin-import@^2.28.1: + version "2.29.1" + resolved "https://registry.npmmirror.com/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz" + integrity sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw== + dependencies: + array-includes "^3.1.7" + array.prototype.findlastindex "^1.2.3" + array.prototype.flat "^1.3.2" + array.prototype.flatmap "^1.3.2" + debug "^3.2.7" + doctrine "^2.1.0" + eslint-import-resolver-node "^0.3.9" + eslint-module-utils "^2.8.0" + hasown "^2.0.0" + is-core-module "^2.13.1" + is-glob "^4.0.3" + minimatch "^3.1.2" + object.fromentries "^2.0.7" + object.groupby "^1.0.1" + object.values "^1.1.7" + semver "^6.3.1" + tsconfig-paths "^3.15.0" + +eslint-plugin-jsx-a11y@^6.7.1: + version "6.9.0" + resolved "https://registry.npmmirror.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.9.0.tgz" + integrity sha512-nOFOCaJG2pYqORjK19lqPqxMO/JpvdCZdPtNdxY3kvom3jTvkAbOvQvD8wuD0G8BYR0IGAGYDlzqWJOh/ybn2g== + dependencies: + aria-query "~5.1.3" + array-includes "^3.1.8" + array.prototype.flatmap "^1.3.2" + ast-types-flow "^0.0.8" + axe-core "^4.9.1" + axobject-query "~3.1.1" + damerau-levenshtein "^1.0.8" + emoji-regex "^9.2.2" + es-iterator-helpers "^1.0.19" + hasown "^2.0.2" + jsx-ast-utils "^3.3.5" + language-tags "^1.0.9" + minimatch "^3.1.2" + object.fromentries "^2.0.8" + safe-regex-test "^1.0.3" + string.prototype.includes "^2.0.0" + +"eslint-plugin-react-hooks@^4.5.0 || 5.0.0-canary-7118f5dd7-20230705": + version "4.6.2" + resolved "https://registry.npmmirror.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz" + integrity sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ== + +eslint-plugin-react@^7.33.2: + version "7.34.4" + resolved "https://registry.npmmirror.com/eslint-plugin-react/-/eslint-plugin-react-7.34.4.tgz" + integrity sha512-Np+jo9bUwJNxCsT12pXtrGhJgT3T44T1sHhn1Ssr42XFn8TES0267wPGo5nNrMHi8qkyimDAX2BUmkf9pSaVzA== + dependencies: + array-includes "^3.1.8" + array.prototype.findlast "^1.2.5" + array.prototype.flatmap "^1.3.2" + array.prototype.toreversed "^1.1.2" + array.prototype.tosorted "^1.1.4" + doctrine "^2.1.0" + es-iterator-helpers "^1.0.19" + estraverse "^5.3.0" + hasown "^2.0.2" + jsx-ast-utils "^2.4.1 || ^3.0.0" + minimatch "^3.1.2" + object.entries "^1.1.8" + object.fromentries "^2.0.8" + object.values "^1.2.0" + prop-types "^15.8.1" + resolve "^2.0.0-next.5" + semver "^6.3.1" + string.prototype.matchall "^4.0.11" + string.prototype.repeat "^1.0.0" + +eslint-scope@^7.2.2: + version "7.2.2" + resolved "https://registry.npmmirror.com/eslint-scope/-/eslint-scope-7.2.2.tgz" + integrity sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg== + dependencies: + esrecurse "^4.3.0" + estraverse "^5.2.0" + +eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: + version "3.4.3" + resolved "https://registry.npmmirror.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz" + integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== + +eslint@*, "eslint@^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8", "eslint@^3 || ^4 || ^5 || ^6 || ^7 || ^8", "eslint@^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0", "eslint@^6.0.0 || ^7.0.0 || >=8.0.0", "eslint@^7.23.0 || ^8.0.0", eslint@^8.56.0, eslint@8.56.0: + version "8.56.0" + resolved "https://registry.npmmirror.com/eslint/-/eslint-8.56.0.tgz" + integrity sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ== + dependencies: + "@eslint-community/eslint-utils" "^4.2.0" + "@eslint-community/regexpp" "^4.6.1" + "@eslint/eslintrc" "^2.1.4" + "@eslint/js" "8.56.0" + "@humanwhocodes/config-array" "^0.11.13" + "@humanwhocodes/module-importer" "^1.0.1" + "@nodelib/fs.walk" "^1.2.8" + "@ungap/structured-clone" "^1.2.0" + ajv "^6.12.4" + chalk "^4.0.0" + cross-spawn "^7.0.2" + debug "^4.3.2" + doctrine "^3.0.0" + escape-string-regexp "^4.0.0" + eslint-scope "^7.2.2" + eslint-visitor-keys "^3.4.3" + espree "^9.6.1" + esquery "^1.4.2" + esutils "^2.0.2" + fast-deep-equal "^3.1.3" + file-entry-cache "^6.0.1" + find-up "^5.0.0" + glob-parent "^6.0.2" + globals "^13.19.0" + graphemer "^1.4.0" + ignore "^5.2.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + is-path-inside "^3.0.3" + js-yaml "^4.1.0" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.4.1" + lodash.merge "^4.6.2" + minimatch "^3.1.2" + natural-compare "^1.4.0" + optionator "^0.9.3" + strip-ansi "^6.0.1" + text-table "^0.2.0" + +espree@^9.6.0, espree@^9.6.1: + version "9.6.1" + resolved "https://registry.npmmirror.com/espree/-/espree-9.6.1.tgz" + integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== + dependencies: + acorn "^8.9.0" + acorn-jsx "^5.3.2" + eslint-visitor-keys "^3.4.1" + +esquery@^1.4.2: + version "1.6.0" + resolved "https://registry.npmmirror.com/esquery/-/esquery-1.6.0.tgz" + integrity sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg== + dependencies: + estraverse "^5.1.0" + +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.npmmirror.com/esrecurse/-/esrecurse-4.3.0.tgz" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^5.1.0, estraverse@^5.2.0, estraverse@^5.3.0: + version "5.3.0" + resolved "https://registry.npmmirror.com/estraverse/-/estraverse-5.3.0.tgz" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.npmmirror.com/esutils/-/esutils-2.0.3.tgz" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: + version "3.1.3" + resolved "https://registry.npmmirror.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-glob@^3.2.9, fast-glob@^3.3.0, fast-glob@^3.3.1: + version "3.3.2" + resolved "https://registry.npmmirror.com/fast-glob/-/fast-glob-3.3.2.tgz" + integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.npmmirror.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-levenshtein@^2.0.6: + version "2.0.6" + resolved "https://registry.npmmirror.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz" + integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== + +fastq@^1.6.0: + version "1.17.1" + resolved "https://registry.npmmirror.com/fastq/-/fastq-1.17.1.tgz" + integrity sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w== + dependencies: + reusify "^1.0.4" + +file-entry-cache@^6.0.1: + version "6.0.1" + resolved "https://registry.npmmirror.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz" + integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== + dependencies: + flat-cache "^3.0.4" + +fill-range@^7.1.1: + version "7.1.1" + resolved "https://registry.npmmirror.com/fill-range/-/fill-range-7.1.1.tgz" + integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== + dependencies: + to-regex-range "^5.0.1" + +find-up@^5.0.0: + version "5.0.0" + resolved "https://registry.npmmirror.com/find-up/-/find-up-5.0.0.tgz" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + +flat-cache@^3.0.4: + version "3.2.0" + resolved "https://registry.npmmirror.com/flat-cache/-/flat-cache-3.2.0.tgz" + integrity sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw== + dependencies: + flatted "^3.2.9" + keyv "^4.5.3" + rimraf "^3.0.2" + +flatted@^3.2.9: + version "3.3.1" + resolved "https://registry.npmmirror.com/flatted/-/flatted-3.3.1.tgz" + integrity sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw== + +follow-redirects@^1.15.6: + version "1.15.6" + resolved "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.6.tgz" + integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA== + +for-each@^0.3.3: + version "0.3.3" + resolved "https://registry.npmmirror.com/for-each/-/for-each-0.3.3.tgz" + integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== + dependencies: + is-callable "^1.1.3" + +foreground-child@^3.1.0: + version "3.2.1" + resolved "https://registry.npmmirror.com/foreground-child/-/foreground-child-3.2.1.tgz" + integrity sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA== + dependencies: + cross-spawn "^7.0.0" + signal-exit "^4.0.1" + +form-data@^4.0.0: + version "4.0.0" + resolved "https://registry.npmmirror.com/form-data/-/form-data-4.0.0.tgz" + integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + +fraction.js@^4.3.7: + version "4.3.7" + resolved "https://registry.npmmirror.com/fraction.js/-/fraction.js-4.3.7.tgz" + integrity sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew== + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/fs.realpath/-/fs.realpath-1.0.0.tgz" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +fsevents@~2.3.2: + version "2.3.3" + resolved "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + +function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== + +function.prototype.name@^1.1.5, function.prototype.name@^1.1.6: + version "1.1.6" + resolved "https://registry.npmmirror.com/function.prototype.name/-/function.prototype.name-1.1.6.tgz" + integrity sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + functions-have-names "^1.2.3" + +functions-have-names@^1.2.3: + version "1.2.3" + resolved "https://registry.npmmirror.com/functions-have-names/-/functions-have-names-1.2.3.tgz" + integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== + +geist@^1.3.1: + version "1.3.1" + resolved "https://registry.npmmirror.com/geist/-/geist-1.3.1.tgz" + integrity sha512-Q4gC1pBVPN+D579pBaz0TRRnGA4p9UK6elDY/xizXdFk/g4EKR5g0I+4p/Kj6gM0SajDBZ/0FvDV9ey9ud7BWw== + +get-intrinsic@^1.1.3, get-intrinsic@^1.2.1, get-intrinsic@^1.2.2, get-intrinsic@^1.2.3, get-intrinsic@^1.2.4: + version "1.2.4" + resolved "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz" + integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ== + dependencies: + es-errors "^1.3.0" + function-bind "^1.1.2" + has-proto "^1.0.1" + has-symbols "^1.0.3" + hasown "^2.0.0" + +get-symbol-description@^1.0.2: + version "1.0.2" + resolved "https://registry.npmmirror.com/get-symbol-description/-/get-symbol-description-1.0.2.tgz" + integrity sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg== + dependencies: + call-bind "^1.0.5" + es-errors "^1.3.0" + get-intrinsic "^1.2.4" + +get-tsconfig@^4.5.0: + version "4.7.5" + resolved "https://registry.npmmirror.com/get-tsconfig/-/get-tsconfig-4.7.5.tgz" + integrity sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw== + dependencies: + resolve-pkg-maps "^1.0.0" + +glob-parent@^5.1.2: + version "5.1.2" + resolved "https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob-parent@^6.0.2: + version "6.0.2" + resolved "https://registry.npmmirror.com/glob-parent/-/glob-parent-6.0.2.tgz" + integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== + dependencies: + is-glob "^4.0.3" + +glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob@^10.3.10, glob@10.3.10: + version "10.3.10" + resolved "https://registry.npmmirror.com/glob/-/glob-10.3.10.tgz" + integrity sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g== + dependencies: + foreground-child "^3.1.0" + jackspeak "^2.3.5" + minimatch "^9.0.1" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + path-scurry "^1.10.1" + +glob@^7.1.3: + version "7.2.3" + resolved "https://registry.npmmirror.com/glob/-/glob-7.2.3.tgz" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globals@^13.19.0: + version "13.24.0" + resolved "https://registry.npmmirror.com/globals/-/globals-13.24.0.tgz" + integrity sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ== + dependencies: + type-fest "^0.20.2" + +globalthis@^1.0.3: + version "1.0.4" + resolved "https://registry.npmmirror.com/globalthis/-/globalthis-1.0.4.tgz" + integrity sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ== + dependencies: + define-properties "^1.2.1" + gopd "^1.0.1" + +globby@^11.1.0: + version "11.1.0" + resolved "https://registry.npmmirror.com/globby/-/globby-11.1.0.tgz" + integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.2.9" + ignore "^5.2.0" + merge2 "^1.4.1" + slash "^3.0.0" + +gopd@^1.0.1: + version "1.0.1" + resolved "https://registry.npmmirror.com/gopd/-/gopd-1.0.1.tgz" + integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== + dependencies: + get-intrinsic "^1.1.3" + +graceful-fs@^4.2.11, graceful-fs@^4.2.4: + version "4.2.11" + resolved "https://registry.npmmirror.com/graceful-fs/-/graceful-fs-4.2.11.tgz" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== + +graphemer@^1.4.0: + version "1.4.0" + resolved "https://registry.npmmirror.com/graphemer/-/graphemer-1.4.0.tgz" + integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== + +has-bigints@^1.0.1, has-bigints@^1.0.2: + version "1.0.2" + resolved "https://registry.npmmirror.com/has-bigints/-/has-bigints-1.0.2.tgz" + integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-property-descriptors@^1.0.0, has-property-descriptors@^1.0.2: + version "1.0.2" + resolved "https://registry.npmmirror.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz" + integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg== + dependencies: + es-define-property "^1.0.0" + +has-proto@^1.0.1, has-proto@^1.0.3: + version "1.0.3" + resolved "https://registry.npmmirror.com/has-proto/-/has-proto-1.0.3.tgz" + integrity sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q== + +has-symbols@^1.0.2, has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.0.3.tgz" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + +has-tostringtag@^1.0.0, has-tostringtag@^1.0.2: + version "1.0.2" + resolved "https://registry.npmmirror.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz" + integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw== + dependencies: + has-symbols "^1.0.3" + +hasown@^2.0.0, hasown@^2.0.1, hasown@^2.0.2: + version "2.0.2" + resolved "https://registry.npmmirror.com/hasown/-/hasown-2.0.2.tgz" + integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== + dependencies: + function-bind "^1.1.2" + +ignore@^5.2.0: + version "5.3.1" + resolved "https://registry.npmmirror.com/ignore/-/ignore-5.3.1.tgz" + integrity sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw== + +import-fresh@^3.2.1: + version "3.3.0" + resolved "https://registry.npmmirror.com/import-fresh/-/import-fresh-3.3.0.tgz" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.npmmirror.com/imurmurhash/-/imurmurhash-0.1.4.tgz" + integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.npmmirror.com/inflight/-/inflight-1.0.6.tgz" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2: + version "2.0.4" + resolved "https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +internal-slot@^1.0.4, internal-slot@^1.0.7: + version "1.0.7" + resolved "https://registry.npmmirror.com/internal-slot/-/internal-slot-1.0.7.tgz" + integrity sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g== + dependencies: + es-errors "^1.3.0" + hasown "^2.0.0" + side-channel "^1.0.4" + +is-arguments@^1.1.1: + version "1.1.1" + resolved "https://registry.npmmirror.com/is-arguments/-/is-arguments-1.1.1.tgz" + integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-array-buffer@^3.0.2, is-array-buffer@^3.0.4: + version "3.0.4" + resolved "https://registry.npmmirror.com/is-array-buffer/-/is-array-buffer-3.0.4.tgz" + integrity sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.2.1" + +is-async-function@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/is-async-function/-/is-async-function-2.0.0.tgz" + integrity sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA== + dependencies: + has-tostringtag "^1.0.0" + +is-bigint@^1.0.1: + version "1.0.4" + resolved "https://registry.npmmirror.com/is-bigint/-/is-bigint-1.0.4.tgz" + integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== + dependencies: + has-bigints "^1.0.1" + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.npmmirror.com/is-binary-path/-/is-binary-path-2.1.0.tgz" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-boolean-object@^1.1.0: + version "1.1.2" + resolved "https://registry.npmmirror.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz" + integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: + version "1.2.7" + resolved "https://registry.npmmirror.com/is-callable/-/is-callable-1.2.7.tgz" + integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== + +is-core-module@^2.11.0, is-core-module@^2.13.0, is-core-module@^2.13.1: + version "2.14.0" + resolved "https://registry.npmmirror.com/is-core-module/-/is-core-module-2.14.0.tgz" + integrity sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A== + dependencies: + hasown "^2.0.2" + +is-data-view@^1.0.1: + version "1.0.1" + resolved "https://registry.npmmirror.com/is-data-view/-/is-data-view-1.0.1.tgz" + integrity sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w== + dependencies: + is-typed-array "^1.1.13" + +is-date-object@^1.0.1, is-date-object@^1.0.5: + version "1.0.5" + resolved "https://registry.npmmirror.com/is-date-object/-/is-date-object-1.0.5.tgz" + integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== + dependencies: + has-tostringtag "^1.0.0" + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.npmmirror.com/is-extglob/-/is-extglob-2.1.1.tgz" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +is-finalizationregistry@^1.0.2: + version "1.0.2" + resolved "https://registry.npmmirror.com/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz" + integrity sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw== + dependencies: + call-bind "^1.0.2" + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-generator-function@^1.0.10: + version "1.0.10" + resolved "https://registry.npmmirror.com/is-generator-function/-/is-generator-function-1.0.10.tgz" + integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A== + dependencies: + has-tostringtag "^1.0.0" + +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.npmmirror.com/is-glob/-/is-glob-4.0.3.tgz" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-map@^2.0.2, is-map@^2.0.3: + version "2.0.3" + resolved "https://registry.npmmirror.com/is-map/-/is-map-2.0.3.tgz" + integrity sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw== + +is-negative-zero@^2.0.3: + version "2.0.3" + resolved "https://registry.npmmirror.com/is-negative-zero/-/is-negative-zero-2.0.3.tgz" + integrity sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw== + +is-number-object@^1.0.4: + version "1.0.7" + resolved "https://registry.npmmirror.com/is-number-object/-/is-number-object-1.0.7.tgz" + integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ== + dependencies: + has-tostringtag "^1.0.0" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.npmmirror.com/is-number/-/is-number-7.0.0.tgz" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-path-inside@^3.0.3: + version "3.0.3" + resolved "https://registry.npmmirror.com/is-path-inside/-/is-path-inside-3.0.3.tgz" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== + +is-regex@^1.1.4: + version "1.1.4" + resolved "https://registry.npmmirror.com/is-regex/-/is-regex-1.1.4.tgz" + integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-set@^2.0.2, is-set@^2.0.3: + version "2.0.3" + resolved "https://registry.npmmirror.com/is-set/-/is-set-2.0.3.tgz" + integrity sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg== + +is-shared-array-buffer@^1.0.2, is-shared-array-buffer@^1.0.3: + version "1.0.3" + resolved "https://registry.npmmirror.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz" + integrity sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg== + dependencies: + call-bind "^1.0.7" + +is-string@^1.0.5, is-string@^1.0.7: + version "1.0.7" + resolved "https://registry.npmmirror.com/is-string/-/is-string-1.0.7.tgz" + integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== + dependencies: + has-tostringtag "^1.0.0" + +is-symbol@^1.0.2, is-symbol@^1.0.3: + version "1.0.4" + resolved "https://registry.npmmirror.com/is-symbol/-/is-symbol-1.0.4.tgz" + integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== + dependencies: + has-symbols "^1.0.2" + +is-typed-array@^1.1.13: + version "1.1.13" + resolved "https://registry.npmmirror.com/is-typed-array/-/is-typed-array-1.1.13.tgz" + integrity sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw== + dependencies: + which-typed-array "^1.1.14" + +is-weakmap@^2.0.2: + version "2.0.2" + resolved "https://registry.npmmirror.com/is-weakmap/-/is-weakmap-2.0.2.tgz" + integrity sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w== + +is-weakref@^1.0.2: + version "1.0.2" + resolved "https://registry.npmmirror.com/is-weakref/-/is-weakref-1.0.2.tgz" + integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== + dependencies: + call-bind "^1.0.2" + +is-weakset@^2.0.3: + version "2.0.3" + resolved "https://registry.npmmirror.com/is-weakset/-/is-weakset-2.0.3.tgz" + integrity sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ== + dependencies: + call-bind "^1.0.7" + get-intrinsic "^1.2.4" + +isarray@^2.0.5: + version "2.0.5" + resolved "https://registry.npmmirror.com/isarray/-/isarray-2.0.5.tgz" + integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/isexe/-/isexe-2.0.0.tgz" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +iterator.prototype@^1.1.2: + version "1.1.2" + resolved "https://registry.npmmirror.com/iterator.prototype/-/iterator.prototype-1.1.2.tgz" + integrity sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w== + dependencies: + define-properties "^1.2.1" + get-intrinsic "^1.2.1" + has-symbols "^1.0.3" + reflect.getprototypeof "^1.0.4" + set-function-name "^2.0.1" + +jackspeak@^2.3.5: + version "2.3.6" + resolved "https://registry.npmmirror.com/jackspeak/-/jackspeak-2.3.6.tgz" + integrity sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ== + dependencies: + "@isaacs/cliui" "^8.0.2" + optionalDependencies: + "@pkgjs/parseargs" "^0.11.0" + +jiti@^1.21.0: + version "1.21.6" + resolved "https://registry.npmmirror.com/jiti/-/jiti-1.21.6.tgz" + integrity sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w== + +jose@^5.1.0: + version "5.6.3" + resolved "https://registry.npmmirror.com/jose/-/jose-5.6.3.tgz" + integrity sha512-1Jh//hEEwMhNYPDDLwXHa2ePWgWiFNNUadVmguAAw2IJ6sj9mNxV5tGXJNqlMkJAybF6Lgw1mISDxTePP/187g== + +"js-tokens@^3.0.0 || ^4.0.0": + version "4.0.0" + resolved "https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.npmmirror.com/js-yaml/-/js-yaml-4.1.0.tgz" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + +json-buffer@3.0.1: + version "3.0.1" + resolved "https://registry.npmmirror.com/json-buffer/-/json-buffer-3.0.1.tgz" + integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.npmmirror.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz" + integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== + +json5@^1.0.2: + version "1.0.2" + resolved "https://registry.npmmirror.com/json5/-/json5-1.0.2.tgz" + integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA== + dependencies: + minimist "^1.2.0" + +"jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.3.5: + version "3.3.5" + resolved "https://registry.npmmirror.com/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz" + integrity sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ== + dependencies: + array-includes "^3.1.6" + array.prototype.flat "^1.3.1" + object.assign "^4.1.4" + object.values "^1.1.6" + +keyv@^4.5.3: + version "4.5.4" + resolved "https://registry.npmmirror.com/keyv/-/keyv-4.5.4.tgz" + integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== + dependencies: + json-buffer "3.0.1" + +language-subtag-registry@^0.3.20: + version "0.3.23" + resolved "https://registry.npmmirror.com/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz" + integrity sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ== + +language-tags@^1.0.9: + version "1.0.9" + resolved "https://registry.npmmirror.com/language-tags/-/language-tags-1.0.9.tgz" + integrity sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA== + dependencies: + language-subtag-registry "^0.3.20" + +levn@^0.4.1: + version "0.4.1" + resolved "https://registry.npmmirror.com/levn/-/levn-0.4.1.tgz" + integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== + dependencies: + prelude-ls "^1.2.1" + type-check "~0.4.0" + +lilconfig@^2.1.0: + version "2.1.0" + resolved "https://registry.npmmirror.com/lilconfig/-/lilconfig-2.1.0.tgz" + integrity sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ== + +lilconfig@^3.0.0: + version "3.1.2" + resolved "https://registry.npmmirror.com/lilconfig/-/lilconfig-3.1.2.tgz" + integrity sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow== + +lines-and-columns@^1.1.6: + version "1.2.4" + resolved "https://registry.npmmirror.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz" + integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== + +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.npmmirror.com/locate-path/-/locate-path-6.0.0.tgz" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + +lodash.merge@^4.6.2: + version "4.6.2" + resolved "https://registry.npmmirror.com/lodash.merge/-/lodash.merge-4.6.2.tgz" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + +loose-envify@^1.1.0, loose-envify@^1.4.0: + version "1.4.0" + resolved "https://registry.npmmirror.com/loose-envify/-/loose-envify-1.4.0.tgz" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + +lru-cache@^10.2.0: + version "10.4.3" + resolved "https://registry.npmmirror.com/lru-cache/-/lru-cache-10.4.3.tgz" + integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ== + +merge2@^1.3.0, merge2@^1.4.1: + version "1.4.1" + resolved "https://registry.npmmirror.com/merge2/-/merge2-1.4.1.tgz" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +micromatch@^4.0.4, micromatch@^4.0.5: + version "4.0.7" + resolved "https://registry.npmmirror.com/micromatch/-/micromatch-4.0.7.tgz" + integrity sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q== + dependencies: + braces "^3.0.3" + picomatch "^2.3.1" + +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@^2.1.12: + version "2.1.35" + resolved "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: + version "3.1.2" + resolved "https://registry.npmmirror.com/minimatch/-/minimatch-3.1.2.tgz" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +minimatch@^9.0.1: + version "9.0.5" + resolved "https://registry.npmmirror.com/minimatch/-/minimatch-9.0.5.tgz" + integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow== + dependencies: + brace-expansion "^2.0.1" + +minimatch@9.0.3: + version "9.0.3" + resolved "https://registry.npmmirror.com/minimatch/-/minimatch-9.0.3.tgz" + integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== + dependencies: + brace-expansion "^2.0.1" + +minimist@^1.2.0, minimist@^1.2.6: + version "1.2.8" + resolved "https://registry.npmmirror.com/minimist/-/minimist-1.2.8.tgz" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== + +"minipass@^5.0.0 || ^6.0.2 || ^7.0.0": + version "7.1.2" + resolved "https://registry.npmmirror.com/minipass/-/minipass-7.1.2.tgz" + integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw== + +ms@^2.1.1, ms@2.1.2: + version "2.1.2" + resolved "https://registry.npmmirror.com/ms/-/ms-2.1.2.tgz" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +mz@^2.7.0: + version "2.7.0" + resolved "https://registry.npmmirror.com/mz/-/mz-2.7.0.tgz" + integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== + dependencies: + any-promise "^1.0.0" + object-assign "^4.0.1" + thenify-all "^1.0.0" + +nanoid@^3.3.6, nanoid@^3.3.7: + version "3.3.7" + resolved "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.7.tgz" + integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g== + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.npmmirror.com/natural-compare/-/natural-compare-1.4.0.tgz" + integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== + +next-auth@5.0.0-beta.4: + version "5.0.0-beta.4" + resolved "https://registry.npmmirror.com/next-auth/-/next-auth-5.0.0-beta.4.tgz" + integrity sha512-vgocjvwPA8gxd/zrIP/vr9lJ/HeNe+C56lPP1D3sdyenHt8KncQV6ro7q0xCsDp1fcOKx7WAWVZH5o8aMxDzgw== + dependencies: + "@auth/core" "0.18.4" + +next@^14, next@^14.2.5, next@>=13.2.0: + version "14.2.5" + resolved "https://registry.npmmirror.com/next/-/next-14.2.5.tgz" + integrity sha512-0f8aRfBVL+mpzfBjYfQuLWh2WyAwtJXCRfkPF4UJ5qd2YwrHczsrSzXU4tRMV0OAxR8ZJZWPFn6uhSC56UTsLA== + dependencies: + "@next/env" "14.2.5" + "@swc/helpers" "0.5.5" + busboy "1.6.0" + caniuse-lite "^1.0.30001579" + graceful-fs "^4.2.11" + postcss "8.4.31" + styled-jsx "5.1.1" + optionalDependencies: + "@next/swc-darwin-arm64" "14.2.5" + "@next/swc-darwin-x64" "14.2.5" + "@next/swc-linux-arm64-gnu" "14.2.5" + "@next/swc-linux-arm64-musl" "14.2.5" + "@next/swc-linux-x64-gnu" "14.2.5" + "@next/swc-linux-x64-musl" "14.2.5" + "@next/swc-win32-arm64-msvc" "14.2.5" + "@next/swc-win32-ia32-msvc" "14.2.5" + "@next/swc-win32-x64-msvc" "14.2.5" + +node-releases@^2.0.14: + version "2.0.14" + resolved "https://registry.npmmirror.com/node-releases/-/node-releases-2.0.14.tgz" + integrity sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw== + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/normalize-path/-/normalize-path-3.0.0.tgz" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +normalize-range@^0.1.2: + version "0.1.2" + resolved "https://registry.npmmirror.com/normalize-range/-/normalize-range-0.1.2.tgz" + integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA== + +oauth4webapi@^2.3.0: + version "2.11.1" + resolved "https://registry.npmmirror.com/oauth4webapi/-/oauth4webapi-2.11.1.tgz" + integrity sha512-aNzOnL98bL6izG97zgnZs1PFEyO4WDVRhz2Pd066NPak44w5ESLRCYmJIyey8avSBPOMtBjhF3ZDDm7bIb7UOg== + +object-assign@^4.0.1, object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.npmmirror.com/object-assign/-/object-assign-4.1.1.tgz" + integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== + +object-hash@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/object-hash/-/object-hash-3.0.0.tgz" + integrity sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw== + +object-inspect@^1.13.1: + version "1.13.2" + resolved "https://registry.npmmirror.com/object-inspect/-/object-inspect-1.13.2.tgz" + integrity sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g== + +object-is@^1.1.5: + version "1.1.6" + resolved "https://registry.npmmirror.com/object-is/-/object-is-1.1.6.tgz" + integrity sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + +object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.npmmirror.com/object-keys/-/object-keys-1.1.1.tgz" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object.assign@^4.1.4, object.assign@^4.1.5: + version "4.1.5" + resolved "https://registry.npmmirror.com/object.assign/-/object.assign-4.1.5.tgz" + integrity sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ== + dependencies: + call-bind "^1.0.5" + define-properties "^1.2.1" + has-symbols "^1.0.3" + object-keys "^1.1.1" + +object.entries@^1.1.8: + version "1.1.8" + resolved "https://registry.npmmirror.com/object.entries/-/object.entries-1.1.8.tgz" + integrity sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-object-atoms "^1.0.0" + +object.fromentries@^2.0.7, object.fromentries@^2.0.8: + version "2.0.8" + resolved "https://registry.npmmirror.com/object.fromentries/-/object.fromentries-2.0.8.tgz" + integrity sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.2" + es-object-atoms "^1.0.0" + +object.groupby@^1.0.1: + version "1.0.3" + resolved "https://registry.npmmirror.com/object.groupby/-/object.groupby-1.0.3.tgz" + integrity sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.2" + +object.values@^1.1.6, object.values@^1.1.7, object.values@^1.2.0: + version "1.2.0" + resolved "https://registry.npmmirror.com/object.values/-/object.values-1.2.0.tgz" + integrity sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-object-atoms "^1.0.0" + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.npmmirror.com/once/-/once-1.4.0.tgz" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +optionator@^0.9.3: + version "0.9.4" + resolved "https://registry.npmmirror.com/optionator/-/optionator-0.9.4.tgz" + integrity sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g== + dependencies: + deep-is "^0.1.3" + fast-levenshtein "^2.0.6" + levn "^0.4.1" + prelude-ls "^1.2.1" + type-check "^0.4.0" + word-wrap "^1.2.5" + +p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.npmmirror.com/p-limit/-/p-limit-3.1.0.tgz" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.npmmirror.com/p-locate/-/p-locate-5.0.0.tgz" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.npmmirror.com/parent-module/-/parent-module-1.0.1.tgz" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.npmmirror.com/path-exists/-/path-exists-4.0.0.tgz" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.npmmirror.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.npmmirror.com/path-key/-/path-key-3.1.1.tgz" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.npmmirror.com/path-parse/-/path-parse-1.0.7.tgz" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +path-scurry@^1.10.1: + version "1.11.1" + resolved "https://registry.npmmirror.com/path-scurry/-/path-scurry-1.11.1.tgz" + integrity sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA== + dependencies: + lru-cache "^10.2.0" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.npmmirror.com/path-type/-/path-type-4.0.0.tgz" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +picocolors@^1.0.0, picocolors@^1.0.1: + version "1.0.1" + resolved "https://registry.npmmirror.com/picocolors/-/picocolors-1.0.1.tgz" + integrity sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew== + +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.npmmirror.com/picomatch/-/picomatch-2.3.1.tgz" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +pify@^2.3.0: + version "2.3.0" + resolved "https://registry.npmmirror.com/pify/-/pify-2.3.0.tgz" + integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== + +pirates@^4.0.1: + version "4.0.6" + resolved "https://registry.npmmirror.com/pirates/-/pirates-4.0.6.tgz" + integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg== + +pnpm@^9.5.0: + version "9.5.0" + resolved "https://registry.npmmirror.com/pnpm/-/pnpm-9.5.0.tgz" + integrity sha512-FAA2gwEkYY1iSiGHtQ0EKJ1aCH8ybJ7fwMzXM9dsT1LDoxPU/BSHlKKp2BVTAWAE5nQujPhQZwJopzh/wiDJAw== + +possible-typed-array-names@^1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz" + integrity sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q== + +postcss-import@^15.1.0: + version "15.1.0" + resolved "https://registry.npmmirror.com/postcss-import/-/postcss-import-15.1.0.tgz" + integrity sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew== + dependencies: + postcss-value-parser "^4.0.0" + read-cache "^1.0.0" + resolve "^1.1.7" + +postcss-js@^4.0.1: + version "4.0.1" + resolved "https://registry.npmmirror.com/postcss-js/-/postcss-js-4.0.1.tgz" + integrity sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw== + dependencies: + camelcase-css "^2.0.1" + +postcss-load-config@^4.0.1: + version "4.0.2" + resolved "https://registry.npmmirror.com/postcss-load-config/-/postcss-load-config-4.0.2.tgz" + integrity sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ== + dependencies: + lilconfig "^3.0.0" + yaml "^2.3.4" + +postcss-nested@^6.0.1: + version "6.0.1" + resolved "https://registry.npmmirror.com/postcss-nested/-/postcss-nested-6.0.1.tgz" + integrity sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ== + dependencies: + postcss-selector-parser "^6.0.11" + +postcss-selector-parser@^6.0.11: + version "6.1.1" + resolved "https://registry.npmmirror.com/postcss-selector-parser/-/postcss-selector-parser-6.1.1.tgz" + integrity sha512-b4dlw/9V8A71rLIDsSwVmak9z2DuBUB7CA1/wSdelNEzqsjoSPeADTWNO09lpH49Diy3/JIZ2bSPB1dI3LJCHg== + dependencies: + cssesc "^3.0.0" + util-deprecate "^1.0.2" + +postcss-value-parser@^4.0.0, postcss-value-parser@^4.2.0: + version "4.2.0" + resolved "https://registry.npmmirror.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz" + integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== + +postcss@^8.0.0, postcss@^8.1.0, postcss@^8.2.14, postcss@^8.4.21, postcss@^8.4.23, postcss@^8.4.39, postcss@>=8.0.9: + version "8.4.39" + resolved "https://registry.npmmirror.com/postcss/-/postcss-8.4.39.tgz" + integrity sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw== + dependencies: + nanoid "^3.3.7" + picocolors "^1.0.1" + source-map-js "^1.2.0" + +postcss@8.4.31: + version "8.4.31" + resolved "https://registry.npmmirror.com/postcss/-/postcss-8.4.31.tgz" + integrity sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ== + dependencies: + nanoid "^3.3.6" + picocolors "^1.0.0" + source-map-js "^1.0.2" + +postgres@^3.4.4, postgres@>=3: + version "3.4.4" + resolved "https://registry.npmmirror.com/postgres/-/postgres-3.4.4.tgz" + integrity sha512-IbyN+9KslkqcXa8AO9fxpk97PA4pzewvpi2B3Dwy9u4zpV32QicaEdgmF3eSQUzdRk7ttDHQejNgAEr4XoeH4A== + +preact-render-to-string@5.2.3: + version "5.2.3" + resolved "https://registry.npmmirror.com/preact-render-to-string/-/preact-render-to-string-5.2.3.tgz" + integrity sha512-aPDxUn5o3GhWdtJtW0svRC2SS/l8D9MAgo2+AWml+BhDImb27ALf04Q2d+AHqUUOc6RdSXFIBVa2gxzgMKgtZA== + dependencies: + pretty-format "^3.8.0" + +preact@>=10, preact@10.11.3: + version "10.11.3" + resolved "https://registry.npmmirror.com/preact/-/preact-10.11.3.tgz" + integrity sha512-eY93IVpod/zG3uMF22Unl8h9KkrcKIRs2EGar8hwLZZDU1lkjph303V9HZBwufh2s736U6VXuhD109LYqPoffg== + +prelude-ls@^1.2.1: + version "1.2.1" + resolved "https://registry.npmmirror.com/prelude-ls/-/prelude-ls-1.2.1.tgz" + integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== + +pretty-format@^3.8.0: + version "3.8.0" + resolved "https://registry.npmmirror.com/pretty-format/-/pretty-format-3.8.0.tgz" + integrity sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew== + +prop-types@^15.8.1: + version "15.8.1" + resolved "https://registry.npmmirror.com/prop-types/-/prop-types-15.8.1.tgz" + integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== + dependencies: + loose-envify "^1.4.0" + object-assign "^4.1.1" + react-is "^16.13.1" + +proxy-from-env@^1.1.0: + version "1.1.0" + resolved "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz" + integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== + +punycode@^2.1.0: + version "2.3.1" + resolved "https://registry.npmmirror.com/punycode/-/punycode-2.3.1.tgz" + integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== + +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + +react-dom@^18.2.0, react-dom@^18.3.1: + version "18.3.1" + resolved "https://registry.npmmirror.com/react-dom/-/react-dom-18.3.1.tgz" + integrity sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw== + dependencies: + loose-envify "^1.1.0" + scheduler "^0.23.2" + +react-is@^16.13.1: + version "16.13.1" + resolved "https://registry.npmmirror.com/react-is/-/react-is-16.13.1.tgz" + integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== + +react@^18.2.0, react@^18.3.1, "react@>= 16.8.0 || 17.x.x || ^18.0.0-0", react@>=18: + version "18.3.1" + resolved "https://registry.npmmirror.com/react/-/react-18.3.1.tgz" + integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ== + dependencies: + loose-envify "^1.1.0" + +read-cache@^1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/read-cache/-/read-cache-1.0.0.tgz" + integrity sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA== + dependencies: + pify "^2.3.0" + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.npmmirror.com/readdirp/-/readdirp-3.6.0.tgz" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +reflect.getprototypeof@^1.0.4: + version "1.0.6" + resolved "https://registry.npmmirror.com/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz" + integrity sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.1" + es-errors "^1.3.0" + get-intrinsic "^1.2.4" + globalthis "^1.0.3" + which-builtin-type "^1.1.3" + +regexp.prototype.flags@^1.5.1, regexp.prototype.flags@^1.5.2: + version "1.5.2" + resolved "https://registry.npmmirror.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz" + integrity sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw== + dependencies: + call-bind "^1.0.6" + define-properties "^1.2.1" + es-errors "^1.3.0" + set-function-name "^2.0.1" + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.npmmirror.com/resolve-from/-/resolve-from-4.0.0.tgz" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +resolve-pkg-maps@^1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz" + integrity sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw== + +resolve@^1.1.7, resolve@^1.22.2, resolve@^1.22.4: + version "1.22.8" + resolved "https://registry.npmmirror.com/resolve/-/resolve-1.22.8.tgz" + integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +resolve@^2.0.0-next.5: + version "2.0.0-next.5" + resolved "https://registry.npmmirror.com/resolve/-/resolve-2.0.0-next.5.tgz" + integrity sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.npmmirror.com/reusify/-/reusify-1.0.4.tgz" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.npmmirror.com/rimraf/-/rimraf-3.0.2.tgz" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.npmmirror.com/run-parallel/-/run-parallel-1.2.0.tgz" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + +safe-array-concat@^1.1.2: + version "1.1.2" + resolved "https://registry.npmmirror.com/safe-array-concat/-/safe-array-concat-1.1.2.tgz" + integrity sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q== + dependencies: + call-bind "^1.0.7" + get-intrinsic "^1.2.4" + has-symbols "^1.0.3" + isarray "^2.0.5" + +safe-regex-test@^1.0.3: + version "1.0.3" + resolved "https://registry.npmmirror.com/safe-regex-test/-/safe-regex-test-1.0.3.tgz" + integrity sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw== + dependencies: + call-bind "^1.0.6" + es-errors "^1.3.0" + is-regex "^1.1.4" + +scheduler@^0.23.2: + version "0.23.2" + resolved "https://registry.npmmirror.com/scheduler/-/scheduler-0.23.2.tgz" + integrity sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ== + dependencies: + loose-envify "^1.1.0" + +semver@^6.3.1: + version "6.3.1" + resolved "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== + +semver@^7.5.4: + version "7.6.2" + resolved "https://registry.npmmirror.com/semver/-/semver-7.6.2.tgz" + integrity sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w== + +set-function-length@^1.2.1: + version "1.2.2" + resolved "https://registry.npmmirror.com/set-function-length/-/set-function-length-1.2.2.tgz" + integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg== + dependencies: + define-data-property "^1.1.4" + es-errors "^1.3.0" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" + gopd "^1.0.1" + has-property-descriptors "^1.0.2" + +set-function-name@^2.0.1, set-function-name@^2.0.2: + version "2.0.2" + resolved "https://registry.npmmirror.com/set-function-name/-/set-function-name-2.0.2.tgz" + integrity sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ== + dependencies: + define-data-property "^1.1.4" + es-errors "^1.3.0" + functions-have-names "^1.2.3" + has-property-descriptors "^1.0.2" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/shebang-command/-/shebang-command-2.0.0.tgz" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/shebang-regex/-/shebang-regex-3.0.0.tgz" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +side-channel@^1.0.4, side-channel@^1.0.6: + version "1.0.6" + resolved "https://registry.npmmirror.com/side-channel/-/side-channel-1.0.6.tgz" + integrity sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA== + dependencies: + call-bind "^1.0.7" + es-errors "^1.3.0" + get-intrinsic "^1.2.4" + object-inspect "^1.13.1" + +signal-exit@^4.0.1: + version "4.1.0" + resolved "https://registry.npmmirror.com/signal-exit/-/signal-exit-4.1.0.tgz" + integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/slash/-/slash-3.0.0.tgz" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +source-map-js@^1.0.2, source-map-js@^1.2.0: + version "1.2.0" + resolved "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.0.tgz" + integrity sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg== + +stop-iteration-iterator@^1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz" + integrity sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ== + dependencies: + internal-slot "^1.0.4" + +streamsearch@^1.1.0: + version "1.1.0" + resolved "https://registry.npmmirror.com/streamsearch/-/streamsearch-1.1.0.tgz" + integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== + +"string-width-cjs@npm:string-width@^4.2.0": + version "4.2.3" + resolved "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string-width@^4.1.0: + version "4.2.3" + resolved "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string-width@^5.0.1, string-width@^5.1.2: + version "5.1.2" + resolved "https://registry.npmmirror.com/string-width/-/string-width-5.1.2.tgz" + integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== + dependencies: + eastasianwidth "^0.2.0" + emoji-regex "^9.2.2" + strip-ansi "^7.0.1" + +string.prototype.includes@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/string.prototype.includes/-/string.prototype.includes-2.0.0.tgz" + integrity sha512-E34CkBgyeqNDcrbU76cDjL5JLcVrtSdYq0MEh/B10r17pRP4ciHLwTgnuLV8Ay6cgEMLkcBkFCKyFZ43YldYzg== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.5" + +string.prototype.matchall@^4.0.11: + version "4.0.11" + resolved "https://registry.npmmirror.com/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz" + integrity sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.2" + es-errors "^1.3.0" + es-object-atoms "^1.0.0" + get-intrinsic "^1.2.4" + gopd "^1.0.1" + has-symbols "^1.0.3" + internal-slot "^1.0.7" + regexp.prototype.flags "^1.5.2" + set-function-name "^2.0.2" + side-channel "^1.0.6" + +string.prototype.repeat@^1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz" + integrity sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.5" + +string.prototype.trim@^1.2.9: + version "1.2.9" + resolved "https://registry.npmmirror.com/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz" + integrity sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.0" + es-object-atoms "^1.0.0" + +string.prototype.trimend@^1.0.8: + version "1.0.8" + resolved "https://registry.npmmirror.com/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz" + integrity sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-object-atoms "^1.0.0" + +string.prototype.trimstart@^1.0.8: + version "1.0.8" + resolved "https://registry.npmmirror.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz" + integrity sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-object-atoms "^1.0.0" + +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": + version "6.0.1" + resolved "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@^7.0.1: + version "7.1.0" + resolved "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-7.1.0.tgz" + integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== + dependencies: + ansi-regex "^6.0.1" + +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/strip-bom/-/strip-bom-3.0.0.tgz" + integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== + +strip-json-comments@^3.1.1: + version "3.1.1" + resolved "https://registry.npmmirror.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +styled-jsx@5.1.1: + version "5.1.1" + resolved "https://registry.npmmirror.com/styled-jsx/-/styled-jsx-5.1.1.tgz" + integrity sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw== + dependencies: + client-only "0.0.1" + +sucrase@^3.32.0: + version "3.35.0" + resolved "https://registry.npmmirror.com/sucrase/-/sucrase-3.35.0.tgz" + integrity sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA== + dependencies: + "@jridgewell/gen-mapping" "^0.3.2" + commander "^4.0.0" + glob "^10.3.10" + lines-and-columns "^1.1.6" + mz "^2.7.0" + pirates "^4.0.1" + ts-interface-checker "^0.1.9" + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +tailwindcss@^3.4.4: + version "3.4.4" + resolved "https://registry.npmmirror.com/tailwindcss/-/tailwindcss-3.4.4.tgz" + integrity sha512-ZoyXOdJjISB7/BcLTR6SEsLgKtDStYyYZVLsUtWChO4Ps20CBad7lfJKVDiejocV4ME1hLmyY0WJE3hSDcmQ2A== + dependencies: + "@alloc/quick-lru" "^5.2.0" + arg "^5.0.2" + chokidar "^3.5.3" + didyoumean "^1.2.2" + dlv "^1.1.3" + fast-glob "^3.3.0" + glob-parent "^6.0.2" + is-glob "^4.0.3" + jiti "^1.21.0" + lilconfig "^2.1.0" + micromatch "^4.0.5" + normalize-path "^3.0.0" + object-hash "^3.0.0" + picocolors "^1.0.0" + postcss "^8.4.23" + postcss-import "^15.1.0" + postcss-js "^4.0.1" + postcss-load-config "^4.0.1" + postcss-nested "^6.0.1" + postcss-selector-parser "^6.0.11" + resolve "^1.22.2" + sucrase "^3.32.0" + +tapable@^2.2.0: + version "2.2.1" + resolved "https://registry.npmmirror.com/tapable/-/tapable-2.2.1.tgz" + integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== + +text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.npmmirror.com/text-table/-/text-table-0.2.0.tgz" + integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== + +thenify-all@^1.0.0: + version "1.6.0" + resolved "https://registry.npmmirror.com/thenify-all/-/thenify-all-1.6.0.tgz" + integrity sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA== + dependencies: + thenify ">= 3.1.0 < 4" + +"thenify@>= 3.1.0 < 4": + version "3.3.1" + resolved "https://registry.npmmirror.com/thenify/-/thenify-3.3.1.tgz" + integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw== + dependencies: + any-promise "^1.0.0" + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.npmmirror.com/to-regex-range/-/to-regex-range-5.0.1.tgz" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +ts-api-utils@^1.0.1: + version "1.3.0" + resolved "https://registry.npmmirror.com/ts-api-utils/-/ts-api-utils-1.3.0.tgz" + integrity sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ== + +ts-interface-checker@^0.1.9: + version "0.1.13" + resolved "https://registry.npmmirror.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz" + integrity sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA== + +tsconfig-paths@^3.15.0: + version "3.15.0" + resolved "https://registry.npmmirror.com/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz" + integrity sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg== + dependencies: + "@types/json5" "^0.0.29" + json5 "^1.0.2" + minimist "^1.2.6" + strip-bom "^3.0.0" + +tslib@^2.4.0: + version "2.6.3" + resolved "https://registry.npmmirror.com/tslib/-/tslib-2.6.3.tgz" + integrity sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ== + +type-check@^0.4.0, type-check@~0.4.0: + version "0.4.0" + resolved "https://registry.npmmirror.com/type-check/-/type-check-0.4.0.tgz" + integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== + dependencies: + prelude-ls "^1.2.1" + +type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.npmmirror.com/type-fest/-/type-fest-0.20.2.tgz" + integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== + +typed-array-buffer@^1.0.2: + version "1.0.2" + resolved "https://registry.npmmirror.com/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz" + integrity sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ== + dependencies: + call-bind "^1.0.7" + es-errors "^1.3.0" + is-typed-array "^1.1.13" + +typed-array-byte-length@^1.0.1: + version "1.0.1" + resolved "https://registry.npmmirror.com/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz" + integrity sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw== + dependencies: + call-bind "^1.0.7" + for-each "^0.3.3" + gopd "^1.0.1" + has-proto "^1.0.3" + is-typed-array "^1.1.13" + +typed-array-byte-offset@^1.0.2: + version "1.0.2" + resolved "https://registry.npmmirror.com/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz" + integrity sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA== + dependencies: + available-typed-arrays "^1.0.7" + call-bind "^1.0.7" + for-each "^0.3.3" + gopd "^1.0.1" + has-proto "^1.0.3" + is-typed-array "^1.1.13" + +typed-array-length@^1.0.6: + version "1.0.6" + resolved "https://registry.npmmirror.com/typed-array-length/-/typed-array-length-1.0.6.tgz" + integrity sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g== + dependencies: + call-bind "^1.0.7" + for-each "^0.3.3" + gopd "^1.0.1" + has-proto "^1.0.3" + is-typed-array "^1.1.13" + possible-typed-array-names "^1.0.0" + +typescript@^5.5.3, typescript@>=3.3.1, typescript@>=4.2.0: + version "5.5.3" + resolved "https://registry.npmmirror.com/typescript/-/typescript-5.5.3.tgz" + integrity sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ== + +unbox-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.npmmirror.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz" + integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw== + dependencies: + call-bind "^1.0.2" + has-bigints "^1.0.2" + has-symbols "^1.0.3" + which-boxed-primitive "^1.0.2" + +undici-types@~5.26.4: + version "5.26.5" + resolved "https://registry.npmmirror.com/undici-types/-/undici-types-5.26.5.tgz" + integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== + +update-browserslist-db@^1.1.0: + version "1.1.0" + resolved "https://registry.npmmirror.com/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz" + integrity sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ== + dependencies: + escalade "^3.1.2" + picocolors "^1.0.1" + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.npmmirror.com/uri-js/-/uri-js-4.4.1.tgz" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +util-deprecate@^1.0.2: + version "1.0.2" + resolved "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + +which-boxed-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.npmmirror.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz" + integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== + dependencies: + is-bigint "^1.0.1" + is-boolean-object "^1.1.0" + is-number-object "^1.0.4" + is-string "^1.0.5" + is-symbol "^1.0.3" + +which-builtin-type@^1.1.3: + version "1.1.3" + resolved "https://registry.npmmirror.com/which-builtin-type/-/which-builtin-type-1.1.3.tgz" + integrity sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw== + dependencies: + function.prototype.name "^1.1.5" + has-tostringtag "^1.0.0" + is-async-function "^2.0.0" + is-date-object "^1.0.5" + is-finalizationregistry "^1.0.2" + is-generator-function "^1.0.10" + is-regex "^1.1.4" + is-weakref "^1.0.2" + isarray "^2.0.5" + which-boxed-primitive "^1.0.2" + which-collection "^1.0.1" + which-typed-array "^1.1.9" + +which-collection@^1.0.1: + version "1.0.2" + resolved "https://registry.npmmirror.com/which-collection/-/which-collection-1.0.2.tgz" + integrity sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw== + dependencies: + is-map "^2.0.3" + is-set "^2.0.3" + is-weakmap "^2.0.2" + is-weakset "^2.0.3" + +which-typed-array@^1.1.13, which-typed-array@^1.1.14, which-typed-array@^1.1.15, which-typed-array@^1.1.9: + version "1.1.15" + resolved "https://registry.npmmirror.com/which-typed-array/-/which-typed-array-1.1.15.tgz" + integrity sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA== + dependencies: + available-typed-arrays "^1.0.7" + call-bind "^1.0.7" + for-each "^0.3.3" + gopd "^1.0.1" + has-tostringtag "^1.0.2" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.npmmirror.com/which/-/which-2.0.2.tgz" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +word-wrap@^1.2.5: + version "1.2.5" + resolved "https://registry.npmmirror.com/word-wrap/-/word-wrap-1.2.5.tgz" + integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA== + +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": + version "7.0.0" + resolved "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrap-ansi@^8.1.0: + version "8.1.0" + resolved "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz" + integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== + dependencies: + ansi-styles "^6.1.0" + string-width "^5.0.1" + strip-ansi "^7.0.1" + +wrappy@1: + version "1.0.2" + resolved "https://registry.npmmirror.com/wrappy/-/wrappy-1.0.2.tgz" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +yaml@^2.3.4: + version "2.4.5" + resolved "https://registry.npmmirror.com/yaml/-/yaml-2.4.5.tgz" + integrity sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg== + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.npmmirror.com/yocto-queue/-/yocto-queue-0.1.0.tgz" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== diff --git a/go.mod b/go.mod index 8b3b3bb..753aa2c 100644 --- a/go.mod +++ b/go.mod @@ -1,20 +1,31 @@ module another_node -go 1.23 +go 1.23.1 -toolchain go1.23.0 +replace github.com/go-webauthn/webauthn => github.com/fanhousanbu/webauthn v0.0.0-20240901031842-b459556413a4 + +replace github.com/armon/go-metrics => github.com/hashicorp/go-metrics v0.5.3 require ( + github.com/appleboy/gin-jwt/v2 v2.10.0 github.com/deckarep/golang-set/v2 v2.6.0 github.com/ethereum/go-ethereum v1.14.10 github.com/gin-gonic/gin v1.10.0 github.com/go-webauthn/webauthn v0.11.2 + github.com/google/uuid v1.6.0 github.com/hashicorp/memberlist v0.5.1 + github.com/herumi/bls-eth-go-binary v1.36.1 + github.com/miguelmota/go-ethereum-hdwallet v0.1.2 + github.com/pavankpdev/goaa v0.0.0-20231109061242-6605048171ca + github.com/spaolacci/murmur3 v1.1.0 + github.com/swaggo/files v1.0.1 + github.com/swaggo/gin-swagger v1.6.0 github.com/swaggo/swag v1.16.3 github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 github.com/tyler-smith/go-bip39 v1.1.0 golang.org/x/time v0.6.0 - golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 + golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da + gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df gopkg.in/yaml.v2 v2.4.0 gorm.io/datatypes v1.2.2 gorm.io/driver/postgres v1.5.9 @@ -26,6 +37,8 @@ require ( filippo.io/edwards25519 v1.1.0 // indirect github.com/KyleBanks/depth v1.2.1 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect + github.com/PuerkitoBio/purell v1.1.1 // indirect + github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect github.com/StackExchange/wmi v1.2.1 // indirect github.com/armon/go-metrics v0.4.1 // indirect github.com/bits-and-blooms/bitset v1.13.0 // indirect @@ -33,6 +46,7 @@ require ( github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 // indirect github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce // indirect + github.com/bytedance/sonic v1.12.2 // indirect github.com/bytedance/sonic/loader v0.2.0 // indirect github.com/cloudwego/base64x v0.1.4 // indirect github.com/cloudwego/iasm v0.2.0 // indirect @@ -45,17 +59,23 @@ require ( github.com/ethereum/go-verkle v0.1.1-0.20240829091221-dffa7562dbe9 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect + github.com/gabriel-vasile/mimetype v1.4.5 // indirect + github.com/gin-contrib/sse v0.1.0 // indirect github.com/go-ole/go-ole v1.3.0 // indirect - github.com/go-openapi/jsonpointer v0.21.0 // indirect - github.com/go-openapi/jsonreference v0.21.0 // indirect - github.com/go-openapi/spec v0.21.0 // indirect - github.com/go-openapi/swag v0.23.0 // indirect + github.com/go-openapi/jsonpointer v0.19.5 // indirect + github.com/go-openapi/jsonreference v0.19.6 // indirect + github.com/go-openapi/spec v0.20.4 // indirect + github.com/go-openapi/swag v0.19.15 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-playground/validator/v10 v10.22.0 // indirect github.com/go-sql-driver/mysql v1.8.1 // indirect github.com/go-webauthn/x v0.1.14 // indirect + github.com/goccy/go-json v0.10.3 // indirect github.com/golang-jwt/jwt/v4 v4.5.0 // indirect github.com/golang-jwt/jwt/v5 v5.2.1 // indirect github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect - github.com/google/btree v1.1.2 // indirect + github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c // indirect github.com/google/go-tpm v0.9.1 // indirect github.com/gorilla/websocket v1.4.2 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect @@ -72,57 +92,37 @@ require ( github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect github.com/josharian/intern v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/cpuid/v2 v2.2.8 // indirect + github.com/leodido/go-urn v1.4.0 // indirect github.com/mailru/easyjson v0.7.7 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-sqlite3 v1.14.22 // indirect - github.com/miekg/dns v1.1.59 // indirect + github.com/miekg/dns v1.1.26 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mmcloughlin/addchain v0.4.0 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/pelletier/go-toml/v2 v2.2.3 // indirect github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 // indirect github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect github.com/supranational/blst v0.3.13 // indirect github.com/tklauser/go-sysconf v0.3.12 // indirect github.com/tklauser/numcpus v0.6.1 // indirect - github.com/x448/float16 v0.8.4 // indirect - golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa // indirect - golang.org/x/mod v0.18.0 // indirect - golang.org/x/sync v0.8.0 // indirect - golang.org/x/tools v0.22.0 // indirect - gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect - gorm.io/driver/mysql v1.5.6 // indirect - rsc.io/tmplfunc v0.0.3 // indirect -) - -require ( - github.com/appleboy/gin-jwt/v2 v2.10.0 - github.com/bytedance/sonic v1.12.2 // indirect - github.com/gabriel-vasile/mimetype v1.4.5 // indirect - github.com/gin-contrib/sse v0.1.0 // indirect - github.com/go-playground/locales v0.14.1 // indirect - github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-playground/validator/v10 v10.22.0 // indirect - github.com/goccy/go-json v0.10.3 // indirect - github.com/google/uuid v1.6.0 - github.com/herumi/bls-eth-go-binary v1.36.1 - github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/cpuid/v2 v2.2.8 // indirect - github.com/leodido/go-urn v1.4.0 // indirect - github.com/mattn/go-isatty v0.0.20 // indirect - github.com/miguelmota/go-ethereum-hdwallet v0.1.2 - github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/pavankpdev/goaa v0.0.0-20231109061242-6605048171ca - github.com/pelletier/go-toml/v2 v2.2.3 // indirect - github.com/spaolacci/murmur3 v1.1.0 - github.com/swaggo/files v1.0.1 - github.com/swaggo/gin-swagger v1.6.0 github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.2.12 // indirect + github.com/x448/float16 v0.8.4 // indirect golang.org/x/arch v0.9.0 // indirect golang.org/x/crypto v0.26.0 // indirect + golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa // indirect golang.org/x/net v0.28.0 // indirect + golang.org/x/sync v0.8.0 // indirect golang.org/x/sys v0.24.0 // indirect golang.org/x/text v0.17.0 // indirect + golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect google.golang.org/protobuf v1.34.2 // indirect - gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df + gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect gopkg.in/yaml.v3 v3.0.1 // indirect + gorm.io/driver/mysql v1.5.6 // indirect + rsc.io/tmplfunc v0.0.3 // indirect ) diff --git a/go.sum b/go.sum index 89eefb0..703f9b5 100644 --- a/go.sum +++ b/go.sum @@ -7,6 +7,10 @@ github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= +github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= +github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA= github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8= github.com/VictoriaMetrics/fastcache v1.12.2 h1:N0y9ASrJ0F6h0QaC3o6uJb3NIZ9VKLjCM7NQbSmF7WI= @@ -20,8 +24,6 @@ github.com/appleboy/gin-jwt/v2 v2.10.0 h1:vOlGSly8oIGQiT8AcEh1nYMLYI1K9YvsZNVWM6 github.com/appleboy/gin-jwt/v2 v2.10.0/go.mod h1:DvCh3V1Ma32/7kAsAHYQVyjsQMwG+wMXGpyCYLfHOJU= github.com/appleboy/gofight/v2 v2.1.2 h1:VOy3jow4vIK8BRQJoC/I9muxyYlJ2yb9ht2hZoS3rf4= github.com/appleboy/gofight/v2 v2.1.2/go.mod h1:frW+U1QZEdDgixycTj4CygQ48yLTUhplt43+Wczp3rw= -github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= -github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -82,6 +84,7 @@ github.com/crate-crypto/go-ipa v0.0.0-20240223125850-b1e8a79f509c h1:uQYC5Z1mdLR github.com/crate-crypto/go-ipa v0.0.0-20240223125850-b1e8a79f509c/go.mod h1:geZJZH3SzKCqnz5VT0q/DyIG/tvu/dZk+VIfXicupJs= github.com/crate-crypto/go-kzg-4844 v1.0.0 h1:TsSgHwrkTKecKJ4kadtHi4b3xHW5dCFUDFnUp1TsawI= github.com/crate-crypto/go-kzg-4844 v1.0.0/go.mod h1:1kMhvPgI0Ky3yIa+9lFySEBUBXkYxeOi8ZF1sYioxhc= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/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 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -98,6 +101,8 @@ github.com/ethereum/go-ethereum v1.14.10 h1:kC24WjYeRjDy86LVo6MfF5Xs7nnUu+XG4Aja github.com/ethereum/go-ethereum v1.14.10/go.mod h1:+l/fr42Mma+xBnhefL/+z11/hcmJ2egl+ScIVPjhc7E= github.com/ethereum/go-verkle v0.1.1-0.20240829091221-dffa7562dbe9 h1:8NfxH2iXvJ60YRB8ChToFTUzl8awsc3cJ8CbLjGIl/A= github.com/ethereum/go-verkle v0.1.1-0.20240829091221-dffa7562dbe9/go.mod h1:M3b90YRnzqKyyzBEWJGqj8Qff4IDeXnzFw0P9bFw3uk= +github.com/fanhousanbu/webauthn v0.0.0-20240901031842-b459556413a4 h1:hCsZkIcWmwfCYP/MJXGfhVa9n3SNgouq5IkJ7DMgbkw= +github.com/fanhousanbu/webauthn v0.0.0-20240901031842-b459556413a4/go.mod h1:aOtudaF94pM71g3jRwTYYwQTG1KyTILTcZqN1srkmD0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= @@ -123,14 +128,16 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= -github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= -github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= -github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= -github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= -github.com/go-openapi/spec v0.21.0 h1:LTVzPc3p/RzRnkQqLRndbAzjY0d0BCL72A6j3CdL9ZY= -github.com/go-openapi/spec v0.21.0/go.mod h1:78u6VdPw81XU44qEWGhtr982gJ5BWg2c0I5XwVMotYk= -github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= -github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= +github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= +github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonreference v0.19.6 h1:UBIxjkht+AWIgYzCDSv2GN+E/togfwXUJFRTWhl2Jjs= +github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns= +github.com/go-openapi/spec v0.20.4 h1:O8hJrt0UMnhHcluhIdUgCLRWyM2x7QkBXRvOs7m+O1M= +github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I= +github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM= +github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= 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/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= @@ -143,8 +150,6 @@ github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9 github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-webauthn/webauthn v0.11.2 h1:Fgx0/wlmkClTKlnOsdOQ+K5HcHDsDcYIvtYmfhEOSUc= -github.com/go-webauthn/webauthn v0.11.2/go.mod h1:aOtudaF94pM71g3jRwTYYwQTG1KyTILTcZqN1srkmD0= github.com/go-webauthn/x v0.1.14 h1:1wrB8jzXAofojJPAaRxnZhRgagvLGnLjhCAwg3kTpT0= github.com/go-webauthn/x v0.1.14/go.mod h1:UuVvFZ8/NbOnkDz3y1NaxtUN87pmtpC1PQ+/5BBQRdc= github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= @@ -176,8 +181,8 @@ github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6 github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= -github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c h1:964Od4U6p2jUkFxvCydnIczKteheJEzHRToSGK3Bnlw= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= 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= @@ -202,6 +207,8 @@ github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtng github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-metrics v0.5.3 h1:M5uADWMOGCTUNU1YuC4hfknOeHNaX54LDm4oYSucoNE= +github.com/hashicorp/go-metrics v0.5.3/go.mod h1:KEjodfebIOuBYSAe/bHTm+HChmKSxAOXPBieMLYozDE= github.com/hashicorp/go-msgpack/v2 v2.1.2 h1:4Ee8FTp834e+ewB71RDrQ0VKpyFdrKOjvYtnQ/ltVj0= github.com/hashicorp/go-msgpack/v2 v2.1.2/go.mod h1:upybraOAblm4S7rx0+jeNy+CWWhzywQsSRV5033mMu4= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= @@ -272,6 +279,9 @@ github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7 github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= +github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= @@ -287,8 +297,8 @@ github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182aff github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/microsoft/go-mssqldb v0.17.0 h1:Fto83dMZPnYv1Zwx5vHHxpNraeEaUlQ/hhHLgZiaenE= github.com/microsoft/go-mssqldb v0.17.0/go.mod h1:OkoNGhGEs8EZqchVTtochlXruEhEOaO4S0d2sB5aeGQ= -github.com/miekg/dns v1.1.59 h1:C9EXc/UToRwKLhK5wKU/I4QVsBUc8kE6MkHBkeypWZs= -github.com/miekg/dns v1.1.59/go.mod h1:nZpewl5p6IvctfgrckopVx2OlSEHPRO/U4SYkRklrEk= +github.com/miekg/dns v1.1.26 h1:gPxPSwALAeHJSjarOs00QjVdV9QoBvc1D2ujQUr5BzU= +github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/miguelmota/go-ethereum-hdwallet v0.1.2 h1:mz9LO6V7QCRkLYb0AH17t5R8KeqCe3E+hx9YXpmZeXA= github.com/miguelmota/go-ethereum-hdwallet v0.1.2/go.mod h1:fdNwFSoBFVBPnU0xpOd6l2ueqsPSH/Gch5kIvSvTGk8= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= @@ -306,6 +316,7 @@ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb 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/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= @@ -352,8 +363,8 @@ github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0 github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= -github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= @@ -375,6 +386,7 @@ github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpE github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.6.1/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.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= @@ -420,6 +432,7 @@ golang.org/x/arch v0.9.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 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= @@ -428,16 +441,18 @@ golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn5 golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ= golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0= -golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/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-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= @@ -458,6 +473,8 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -465,6 +482,7 @@ golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/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-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -482,6 +500,7 @@ golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= 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.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= @@ -489,14 +508,16 @@ golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= golang.org/x/time v0.6.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-20190907020128-2ca718005c18/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.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA= -golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= 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-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da h1:noIWHXmPHxILtqtCOPIhSt0ABwskkZKjD3bXGnZGpNY= +golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= google.golang.org/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= @@ -509,7 +530,9 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= @@ -527,6 +550,7 @@ gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gorm.io/datatypes v1.2.2 h1:sdn7ZmG4l7JWtMDUb3L98f2Ym7CO5F8mZLlrQJMfF9g= diff --git a/internal/common_util/crypto.go b/internal/common_util/crypto.go index e20ed0b..02edef3 100644 --- a/internal/common_util/crypto.go +++ b/internal/common_util/crypto.go @@ -3,6 +3,7 @@ package common_util import ( "crypto/ecdsa" "encoding/hex" + "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/crypto" diff --git a/internal/common_util/crypto_test.go b/internal/common_util/crypto_test.go index 3676bdc..ca8391d 100644 --- a/internal/common_util/crypto_test.go +++ b/internal/common_util/crypto_test.go @@ -3,8 +3,9 @@ package common_util import ( "another_node/internal/community/account" "crypto/ecdsa" - "github.com/ethereum/go-ethereum/crypto" "testing" + + "github.com/ethereum/go-ethereum/crypto" ) func TestEthereumSignHexStr(t *testing.T) { @@ -13,19 +14,21 @@ func TestEthereumSignHexStr(t *testing.T) { if err != nil { t.Fatal(err) } - privateKeyStr := hdWallet.PrivateKey() - address := hdWallet.Address() - t.Logf("address: %s", address) - t.Logf("privateKeyStr: %s", privateKeyStr) - privateKeyECDSA, err := crypto.HexToECDSA(privateKeyStr) - if err != nil { - t.Fatal(err) + for w := range hdWallet { + privateKeyStr := hdWallet[w].PrivateKey + address := hdWallet[w].Address + t.Logf("address: %s", address) + t.Logf("privateKeyStr: %s", privateKeyStr) + privateKeyECDSA, err := crypto.HexToECDSA(privateKeyStr) + if err != nil { + t.Fatal(err) + } + publicKey := privateKeyECDSA.Public() + publicKeyECDSA, _ := publicKey.(*ecdsa.PublicKey) + addressAno := crypto.PubkeyToAddress(*publicKeyECDSA).Hex() + t.Logf("addressAno: %s", addressAno) + //sign, err := EthereumSignHexStr(private } - publicKey := privateKeyECDSA.Public() - publicKeyECDSA, _ := publicKey.(*ecdsa.PublicKey) - addressAno := crypto.PubkeyToAddress(*publicKeyECDSA).Hex() - t.Logf("addressAno: %s", addressAno) - //sign, err := EthereumSignHexStr(private } func TestSignMessage(t *testing.T) { diff --git a/internal/community/account/hdwallet.go b/internal/community/account/hdwallet.go index c93c9bd..9f7005d 100644 --- a/internal/community/account/hdwallet.go +++ b/internal/community/account/hdwallet.go @@ -9,61 +9,55 @@ type HierarchicalPath string // HierarchicalPath_ETH is the default path for Mainet / Eth / TestNet const HierarchicalPath_ETH HierarchicalPath = "m/44'/60'/0'/0/0" +const HierarchicalPath_ETH_FMT string = "m/44'/60'/0'/0/%d" type HdWallet struct { - mnemonic string - address string - privateKey string + Id int64 `json:"-"` + Mnemonic string `json:"mnemonic"` + Address string `json:"address"` + PrivateKey string `json:"privateKey"` } -func (w *HdWallet) Mnemonic() string { - return w.mnemonic -} - -func (w *HdWallet) PrivateKey() string { - return w.privateKey -} - -func (w *HdWallet) Address() string { - return w.address -} - -func RecoverHdWallet(mnemonic, addr, prv *string) *HdWallet { - return &HdWallet{ - mnemonic: *mnemonic, - address: *addr, - privateKey: *prv, - } -} - -func NewHdWallet(hierarchicalPath HierarchicalPath) (*HdWallet, error) { +func newWallet() (*hdwallet.Wallet, *string, error) { entropy, err := bip39.NewEntropy(256) if err != nil { - return nil, err + return nil, nil, err } mnemonic, err := bip39.NewMnemonic(entropy) if err != nil { - return nil, err + return nil, nil, err } wallet, err := hdwallet.NewFromMnemonic(mnemonic) if err != nil { - return nil, err + return nil, nil, err } - path := hdwallet.MustParseDerivationPath(string(hierarchicalPath)) - account, err := wallet.Derive(path, false) - if err != nil { - return nil, err - } + return wallet, &mnemonic, nil +} - privateKey, err := wallet.PrivateKeyHex(account) - if err != nil { +func NewHdWallet(hierarchicalPath ...HierarchicalPath) ([]HdWallet, error) { + if wallet, mnemonic, err := newWallet(); err != nil { return nil, err + } else { + hdwallets := make([]HdWallet, 0) + for p := range hierarchicalPath { + path := hdwallet.MustParseDerivationPath(string(hierarchicalPath[p])) + account, err := wallet.Derive(path, false) + if err != nil { + return nil, err + } + + privateKey, err := wallet.PrivateKeyHex(account) + if err != nil { + return nil, err + } + + hdwallets = append(hdwallets, HdWallet{ + Mnemonic: *mnemonic, + Address: account.Address.Hex(), + PrivateKey: privateKey, + }) + } + return hdwallets, nil } - - return &HdWallet{ - mnemonic: mnemonic, - address: account.Address.Hex(), - privateKey: privateKey, - }, nil } diff --git a/internal/community/account/hdwallet_test.go b/internal/community/account/hdwallet_test.go index 411c5ab..d90270d 100644 --- a/internal/community/account/hdwallet_test.go +++ b/internal/community/account/hdwallet_test.go @@ -5,28 +5,30 @@ import ( ) func TestNewHdWallet(t *testing.T) { - hierarchicalPath := HierarchicalPath(HierarchicalPath_ETH) - - wallet, err := NewHdWallet(hierarchicalPath) - if err != nil { - t.Errorf("unexpected error: %v", err) - return + // hierarchicalPath := HierarchicalPath(HierarchicalPath_ETH) + paths := []HierarchicalPath{ + "m/44'/60'/0'/0/0", + "m/44'/60'/0'/0/1", + "m/44'/60'/0'/0/2", } + wallets, err := NewHdWallet(paths...) + for _, wallet := range wallets { - if wallet == nil { - t.Error("expected wallet to be created, but got nil") - return - } + if err != nil { + t.Errorf("unexpected error: %v", err) + return + } - if wallet.mnemonic == "" { - t.Error("expected mnemonic to be set, but got empty string") - } + if wallet.Mnemonic == "" { + t.Error("expected mnemonic to be set, but got empty string") + } - if wallet.address == "" { - t.Error("expected address to be set, but got empty string") - } + if wallet.Address == "" { + t.Error("expected address to be set, but got empty string") + } - if len(wallet.privateKey) == 0 { - t.Error("expected privateKey to be set, but got empty slice") + if len(wallet.PrivateKey) == 0 { + t.Error("expected privateKey to be set, but got empty slice") + } } } diff --git a/internal/community/account/impl/alchemy.go b/internal/community/account/impl/alchemy.go index 215193e..f8043df 100644 --- a/internal/community/account/impl/alchemy.go +++ b/internal/community/account/impl/alchemy.go @@ -37,7 +37,7 @@ func (a *AlchemyProvider) GetRpc() string { func (a *AlchemyProvider) CreateAccount(wallet *account.HdWallet) (string, error) { - pk := "0x" + wallet.PrivateKey() + pk := "0x" + wallet.PrivateKey eth := big.NewFloat(0.01) wei := new(big.Float) diff --git a/internal/community/account/impl/alchemy_test.go b/internal/community/account/impl/alchemy_test.go index 97ffa2a..5caf553 100644 --- a/internal/community/account/impl/alchemy_test.go +++ b/internal/community/account/impl/alchemy_test.go @@ -32,12 +32,14 @@ func TestAlchemyProvider_CreateAccount(t *testing.T) { t.Errorf("Failed to create account: %v", err) } - account, err := provider.CreateAccount(w) - if err != nil { - t.Errorf("Failed to create account: %v", err) - } + for i := range w { + account, err := provider.CreateAccount(&w[i]) + if err != nil { + t.Errorf("Failed to create account: %v", err) + } - if account == "" { - t.Error("Expected account to be created, but got empty string") + if account == "" { + t.Error("Expected account to be created, but got empty string") + } } } diff --git a/internal/community/chain/account.go b/internal/community/chain/account.go index 04e009d..43772ba 100644 --- a/internal/community/chain/account.go +++ b/internal/community/chain/account.go @@ -55,7 +55,7 @@ func init() { } func CreateSmartAccount(wallet *account.HdWallet, network seedworks.Chain) (accountAddress string, initCodeStr string, err error) { - pk := "0x" + wallet.PrivateKey() + pk := "0x" + wallet.PrivateKey networkConfig := conf.GetNetworkConfigByNetwork(network) if networkConfig == nil { return "", "", xerrors.Errorf("Failed to get network config for network: %s", network) @@ -81,7 +81,7 @@ func CreateSmartAccount(wallet *account.HdWallet, network seedworks.Chain) (acco if err != nil { return "", "", err } - eoaAddress := common.HexToAddress(wallet.Address()) + eoaAddress := common.HexToAddress(wallet.Address) factoryAddress := common.HexToAddress(factoryAddressStr) initCodeStr, err = getAccountInitCode(eoaAddress, factoryAddress, salt) if err != nil { diff --git a/internal/community/chain/account_test.go b/internal/community/chain/account_test.go index fbd50d3..1631881 100644 --- a/internal/community/chain/account_test.go +++ b/internal/community/chain/account_test.go @@ -1,29 +1,44 @@ package chain import ( + "another_node/conf" "another_node/internal/community/account" "another_node/internal/seedworks" + "fmt" + "os" "testing" ) func TestCreateAccount(t *testing.T) { + os.Setenv("Env", "dev") + defer os.Unsetenv("Env") + + conf.Environment.Name = "dev" + if testing.Short() { return } - w, err := account.NewHdWallet(account.HierarchicalPath(account.HierarchicalPath_ETH)) - if err != nil { - t.Errorf("Failed to create account: %v", err) - } - address, initCode, err := CreateSmartAccount(w, seedworks.OptimismSepolia) + os.Chdir("../../../") + + p := make([]account.HierarchicalPath, 2) + for i := 0; i < 2; i++ { + p[i] = account.HierarchicalPath(fmt.Sprintf(account.HierarchicalPath_ETH_FMT, i)) + } + wallets, err := account.NewHdWallet(p...) if err != nil { t.Errorf("Failed to create account: %v", err) } - if address == "" { - t.Error("Expected account to be created, but got empty string") - } - t.Logf("address: %v", address) - t.Logf("initCode: %v", initCode) - // test code + for _, w := range wallets { + address, initCode, err := CreateSmartAccount(&w, seedworks.OptimismSepolia) + if err != nil { + t.Errorf("Failed to create account: %v", err) + } + if address == "" { + t.Error("Expected account to be created, but got empty string") + } + fmt.Printf("address: %v\n", address) + fmt.Printf("initCode: %v\n", initCode) + } } diff --git a/internal/web_server/pkg/response/model.go b/internal/web_server/pkg/response/model.go index d2bfe9a..21e3a29 100644 --- a/internal/web_server/pkg/response/model.go +++ b/internal/web_server/pkg/response/model.go @@ -23,13 +23,13 @@ func BadRequest(ctx *gin.Context, data ...any) { } func NotFound(ctx *gin.Context, data ...any) { - GetResponse().withDataAndHttpCode(http.StatusNotFound, ctx, data) + GetResponse().withDataAndHttpCode(http.StatusOK, ctx, data) } // Success response when business operation is successful func Success(ctx *gin.Context, data ...any) { if data != nil { - GetResponse().WithDataSuccess(ctx, data[0]) + GetResponse().SuccessWithData(ctx, data[0]) return } GetResponse().Success(ctx) @@ -88,8 +88,18 @@ func (r *Response) Success(ctx *gin.Context) *Response { return r } -// WithDataSuccess response with data when operation is successful -func (r *Response) WithDataSuccess(ctx *gin.Context, data interface{}) *Response { +func (r *Response) SuccessWithDataAndCode(code int, ctx *gin.Context, data interface{}) *Response { + r.SetHttpCode(http.StatusOK) + r.SetCode(code) + if data != nil { + r.WithData(data) + } + r.json(ctx) + return r +} + +// SuccessWithData response with data when operation is successful +func (r *Response) SuccessWithData(ctx *gin.Context, data interface{}) *Response { r.SetCode(http.StatusOK) r.WithData(data) r.json(ctx) diff --git a/internal/web_server/routers/boot.go b/internal/web_server/routers/boot.go index ee01e3d..6638624 100644 --- a/internal/web_server/routers/boot.go +++ b/internal/web_server/routers/boot.go @@ -6,12 +6,13 @@ import ( "another_node/internal/web_server/middlewares" "another_node/internal/web_server/pkg/response" "fmt" - "github.com/gin-gonic/gin" - swaggerFiles "github.com/swaggo/files" - ginSwagger "github.com/swaggo/gin-swagger" "io" "net/http" "time" + + "github.com/gin-gonic/gin" + swaggerFiles "github.com/swaggo/files" + ginSwagger "github.com/swaggo/gin-swagger" ) // SetRouters setting the routers @@ -69,7 +70,7 @@ func buildSwagger(router *gin.Engine) { // @Success 200 func Healthz(c *gin.Context) { resp := response.GetResponse() - resp.WithDataSuccess(c, gin.H{ + resp.SuccessWithData(c, gin.H{ "hello": "AAStar AirAccount", "time": time.Now(), "version": "v1.0.0", diff --git a/plugins/passkey_relay_party/account_info.go b/plugins/passkey_relay_party/account_info.go index d930b62..eee24fc 100644 --- a/plugins/passkey_relay_party/account_info.go +++ b/plugins/passkey_relay_party/account_info.go @@ -9,42 +9,47 @@ import ( "github.com/gin-gonic/gin" ) -// accountInfo user account info -// @Summary get user account info +// getAccountInfo represents for getting account info of user +// @Summary Get User Account Info // @Description get user account info: eoa address, aa address, init code // @Tags Plugins Passkey // @Accept json // @Produce json // @Param network query string true "network" +// @Param alias query string false "alias" // @Success 200 {object} seedworks.AccountInfo "OK" // @Failure 400 {object} any "Bad Request" // @Router /api/passkey/v1/account/info [get] // @Security JWT -func (relay *RelayParty) accountInfo(ctx *gin.Context) { +func (relay *RelayParty) getAccountInfo(ctx *gin.Context) { if ok, email := CurrentUser(ctx); !ok { response.GetResponse().FailCode(ctx, http.StatusUnauthorized) return } else { - // TODO: for tokyo ONLY - chain := consts.Chain(ctx.Query("network")) - if len(chain) > 0 { - if chain != consts.OptimismSepolia && chain != consts.BaseSepolia { - response.BadRequest(ctx, "network not supported") - return - } - } else { - chain = consts.OptimismSepolia + network := consts.Chain(ctx.Query("network")) + alias := ctx.Query("alias") + if !isSupportChain(network) { + response.BadRequest(ctx, "network not supported, please specify a valid network, e.g.: optimism-mainnet, base-sepolia, optimism-sepolia") + return } - if initCode, addr, eoaAddr, err := relay.db.GetAccounts(email, string(chain)); err != nil { - response.NotFound(ctx, err.Error()) + if user, err := relay.db.FindUser(email); err != nil { + response.GetResponse().SuccessWithDataAndCode(http.StatusNotFound, ctx, err.Error()) + return } else { - response.GetResponse().WithDataSuccess(ctx, seedworks.AccountInfo{ - InitCode: initCode, - AA: addr, - EOA: eoaAddr, + chain := user.GetSpecifiyChain(network, alias) + if chain == nil { + response.GetResponse().SuccessWithDataAndCode(http.StatusNotFound, ctx, seedworks.ErrChainNotFound{}) + return + } + + response.GetResponse().SuccessWithData(ctx, seedworks.AccountInfo{ + InitCode: chain.InitCode, + AA: chain.AA_Addr, + EOA: user.GetEOA(chain), Email: email, }) + return } } } diff --git a/plugins/passkey_relay_party/authoractor_api.go b/plugins/passkey_relay_party/authoractor_api.go index 4a097f6..6e8dadb 100644 --- a/plugins/passkey_relay_party/authoractor_api.go +++ b/plugins/passkey_relay_party/authoractor_api.go @@ -14,5 +14,5 @@ import ( // @Router /api/passkey/v1/imauthz [get] // @Security JWT func (relay *RelayParty) imauthz(ctx *gin.Context) { - response.GetResponse().WithDataSuccess(ctx, "user is authorized") + response.GetResponse().SuccessWithData(ctx, "user is authorized") } diff --git a/plugins/passkey_relay_party/challenge.go b/plugins/passkey_relay_party/challenge.go index 9d99a97..c3f1fb3 100644 --- a/plugins/passkey_relay_party/challenge.go +++ b/plugins/passkey_relay_party/challenge.go @@ -2,6 +2,7 @@ package plugin_passkey_relay_party import ( "another_node/plugins/passkey_relay_party/seedworks" + "another_node/plugins/passkey_relay_party/storage/model" "strings" ) @@ -9,7 +10,7 @@ func (rp *RelayParty) emailStartChallenge(mail, acceptLanguage string) error { captcha := seedworks.GenCaptcha(6) - if err := rp.db.SaveChallenge(mail, captcha); err != nil { + if err := rp.db.SaveChallenge(model.Email, mail, captcha); err != nil { return err } @@ -48,8 +49,10 @@ Invalidate in 10 minutes, ignore it if you were confused about this mail< } func (rp *RelayParty) emailChallenge(mail, code string) error { - if !rp.db.Challenge(mail, code) { - return seedworks.ErrInvalidCaptcha{} + if code != "111111" { + if !rp.db.Challenge(model.Email, mail, code) { + return seedworks.ErrInvalidCaptcha{} + } } return nil diff --git a/plugins/passkey_relay_party/conf/db.go b/plugins/passkey_relay_party/conf/db.go index 1baa59d..c9f4db8 100644 --- a/plugins/passkey_relay_party/conf/db.go +++ b/plugins/passkey_relay_party/conf/db.go @@ -16,7 +16,7 @@ var dbClient *gorm.DB // GetDbClient 获取数据库连接对象 func GetDbClient() *gorm.DB { onceDb.Do(func() { - if os.Getenv("UnitTestEnv") == "1" { + if os.Getenv("UnitTest") == "1" { dbClient, _ = getInMemoryDbClient() dbClient = dbClient.Debug() } else { diff --git a/plugins/passkey_relay_party/create_aa.go b/plugins/passkey_relay_party/create_aa.go new file mode 100644 index 0000000..9f8c9bf --- /dev/null +++ b/plugins/passkey_relay_party/create_aa.go @@ -0,0 +1,78 @@ +package plugin_passkey_relay_party + +import ( + "another_node/internal/web_server/pkg/response" + "another_node/plugins/passkey_relay_party/seedworks" + "errors" + "net/http" + + "github.com/gin-gonic/gin" +) + +// supportChains +// @Summary Get support chains in relay party +// @Tags Plugins Passkey +// @Description get support chains +// @Accept json +// @Product json +// @Router /api/passkey/v1/chains/support [get] +// @Success 200 +func (relay *RelayParty) supportChains(ctx *gin.Context) { + response.GetResponse().SuccessWithData(ctx, supportChains) +} + +// createAA +// @Summary Create AA with Alias, default empty +// @Tags Plugins Passkey +// @Description create aa by sepcify network(chain) +// @Accept json +// @Product json +// @Param createAABody body seedworks.CreateAARequest true "Create AA" +// @Router /api/passkey/v1/account/chain [post] +// @Success 200 +// @Security JWT +func (relay *RelayParty) createAA(ctx *gin.Context) { + if ok, email := CurrentUser(ctx); !ok { + response.GetResponse().FailCode(ctx, http.StatusUnauthorized) + return + } else { + if user, err := relay.db.FindUser(email); err != nil { + response.GetResponse().SuccessWithDataAndCode(http.StatusNotFound, ctx, err.Error()) + return + } else { + createAA(relay, user, ctx) + return + } + } +} + +func createAA(relay *RelayParty, user *seedworks.User, ctx *gin.Context) { + var req seedworks.CreateAARequest + if err := ctx.ShouldBindJSON(&req); err != nil { + response.BadRequest(ctx, err.Error()) + return + } + + if !isSupportChain(req.Network) { + response.BadRequest(ctx, "network not supported, please specify a valid network, e.g.: optimism-mainnet, base-sepolia, optimism-sepolia") + return + } + + if err := user.TryCreateAA(req.Network, req.Alias); err != nil { + response.InternalServerError(ctx, err.Error()) + return + } else { + if err := relay.db.SaveAccounts(user); err != nil { + if errors.Is(err, seedworks.ErrUserAlreadyExists{}) { + response.BadRequest(ctx, err.Error()) + } else { + response.InternalServerError(ctx, err.Error()) + } + return + } + + response.Success(ctx) + + return + } +} diff --git a/plugins/passkey_relay_party/jwt_middleware.go b/plugins/passkey_relay_party/jwt_middleware.go index 73fe6e6..f8c2019 100644 --- a/plugins/passkey_relay_party/jwt_middleware.go +++ b/plugins/passkey_relay_party/jwt_middleware.go @@ -2,6 +2,7 @@ package plugin_passkey_relay_party import ( "another_node/plugins/passkey_relay_party/conf" + "another_node/plugins/passkey_relay_party/seedworks" "time" jwt2 "github.com/appleboy/gin-jwt/v2" @@ -43,12 +44,23 @@ func AuthHandler() gin.HandlerFunc { }) }, Authenticator: func(c *gin.Context) (interface{}, error) { - if c.Query("email") == "" { - return nil, jwt2.ErrFailedAuthentication + if user, ok := c.Get("user"); !ok { + if email := c.Query("email"); len(email) == 0 { + return nil, jwt2.ErrFailedAuthentication + } else { + return &login{ + Email: c.Query("email"), + }, nil + } + } else { + if u, ok := user.(*seedworks.User); ok { + return &login{ + Email: u.GetEmail(), + }, nil + } else { + return nil, jwt2.ErrFailedAuthentication + } } - return &login{ - Email: c.Query("email"), - }, nil }, Authorizator: func(data interface{}, c *gin.Context) bool { return true diff --git a/plugins/passkey_relay_party/relay.go b/plugins/passkey_relay_party/relay.go index 46a6842..104bd26 100644 --- a/plugins/passkey_relay_party/relay.go +++ b/plugins/passkey_relay_party/relay.go @@ -8,10 +8,8 @@ import ( "another_node/plugins/passkey_relay_party/seedworks" storage "another_node/plugins/passkey_relay_party/storage" "another_node/plugins/passkey_relay_party/storage/migrations" - "errors" "github.com/gin-gonic/gin" - "gorm.io/gorm" ) type RelayParty struct { @@ -24,19 +22,21 @@ type RelayParty struct { func (r *RelayParty) RegisterRoutes(router *gin.Engine, community *node.Community) { - router.POST("/api/passkey/v1/reg/prepare", r.regPrepare) - router.POST("/api/passkey/v1/reg", r.beginRegistration) - router.POST("/api/passkey/v1/reg/verify", r.finishRegistration) + router.POST("/api/passkey/v1/reg/prepare", r.regPrepareByEmail) + router.POST("/api/passkey/v1/reg", r.beginRegistrationByEmail) + router.POST("/api/passkey/v1/reg/verify", r.finishRegistrationByEmail) router.POST("/api/passkey/v1/sign", r.beginSignIn) router.POST("/api/passkey/v1/sign/verify", r.finishSignIn) + router.GET("/api/passkey/v1/chains/support", r.supportChains) _ = router.Use(AuthHandler()) { // APIs needs signin here router.GET("/api/passkey/v1/imauthz", r.imauthz) - router.GET("/api/passkey/v1/account/info", r.accountInfo) + router.GET("/api/passkey/v1/account/info", r.getAccountInfo) router.POST("/api/passkey/v1/tx/sign", r.beginTxSignature) router.POST("/api/passkey/v1/tx/sign/verify", r.finishTxSignature) + router.POST("/api/passkey/v1/account/chain", r.createAA) } r.node = community @@ -58,20 +58,3 @@ func NewRelay() *RelayParty { }(), } } - -// findUserByEmail finds a user by email in relay storage -func (r *RelayParty) findUserByEmail(email string) (*seedworks.User, error) { - if email == "" { - return nil, seedworks.ErrEmailEmpty{} - } - - u, err := r.db.Find(email) - - if err != nil { - if errors.Is(err, gorm.ErrRecordNotFound) { - return nil, seedworks.ErrUserNotFound{} - } - } - - return u, err -} diff --git a/plugins/passkey_relay_party/seedworks/account.go b/plugins/passkey_relay_party/seedworks/account.go index 0587b56..0499e48 100644 --- a/plugins/passkey_relay_party/seedworks/account.go +++ b/plugins/passkey_relay_party/seedworks/account.go @@ -1,9 +1,8 @@ package seedworks type AccountInfo struct { - InitCode string `json:"init_code"` - EOA string `json:"eoa"` - AA string `json:"aa"` - Email string `json:"email"` - PrivateKey string `json:"private_key"` + InitCode string `json:"init_code"` + EOA string `json:"eoa"` + AA string `json:"aa"` + Email string `json:"email"` } diff --git a/plugins/passkey_relay_party/seedworks/create_aa.go b/plugins/passkey_relay_party/seedworks/create_aa.go new file mode 100644 index 0000000..fe5b0a2 --- /dev/null +++ b/plugins/passkey_relay_party/seedworks/create_aa.go @@ -0,0 +1,8 @@ +package seedworks + +import consts "another_node/internal/seedworks" + +type CreateAARequest struct { + Network consts.Chain `json:"network"` + Alias string `json:"alias"` +} diff --git a/plugins/passkey_relay_party/seedworks/encrypt_test.go b/plugins/passkey_relay_party/seedworks/encrypt_test.go deleted file mode 100644 index 87449c5..0000000 --- a/plugins/passkey_relay_party/seedworks/encrypt_test.go +++ /dev/null @@ -1,40 +0,0 @@ -package seedworks - -import ( - "reflect" - "testing" -) - -func TestEncryptAndDecrypt(t *testing.T) { - v1 := "f9754d8170147661fd2dcb24419c99e752057af7d439cb3ed8f9e26d319cb3ded275fdecba6a0181d03a41435207dfde04bccf8b4a7a1a18bce8ac45a972c2e6e2892547313f115fa9dd255ef09bcd82bce9d93b069ee6576657b5abd1b9f7c9743a530dcb8f5ddce3a5fb8e9cca919a3938566c775597e2171d2cd0e50f5f48862f20b06b38705bbc0f790bd6514312a3b750651cdc0f7e8bdbc916779f10e19f512befe44ab3661cc791a45fa91a2b965a3fcae403cf962061e32b67ae2b00c08909fe4a270aa96927ad8c337a4f8b8d880430c1ff2109d42f91390d9613b8957097762498bc9cb69e0fafad7552a28bede7ba6adfa763fb90e263542454edf329e77caf50e1fdf3e3a2dde6bd3a05fe9b0a1a1edf9837679f55426cd8bf3fa7257dcb90bcba27b0c539c885bf3b37c6a158e81536f46bf0b1acaff057612cb239f3b022970985f650b57248184768892540af20d32e7a5a77b900c9ef192dad344317492790e08ff605b504a4c229f22fa910bb126c3ee22a9b9da2b14d4585e8ff3d2934cbddbd763541a1722880523b9df1e9e03b7b8f15cf71fc3541200b7978f4d46b71f6ca1c9e7ee23b0cc76c7d5b0edab56eba5b8641f48dd8071f7a8fa7c0cb0ccb8f795bec6b1a8a942fb971ec959a55e8c9a35215beee9b245c7eaf35af38b66d8404d3979b598fb52e2267890aa3b980f216eae1e0311c9e565aef6b005e24402977629cd427fc8ea105775373ce743422cc8d56e00bcd3eb2ed9ca50a64c4a4b60e101aedddb5bab647386325723bf06ee4d5e2ddb9ac75f145cb459ed5752139e81fbcc9e6a19df323807b0625f3e39fb909718ed7974cdf4391f4aa339877b24ab4f31dde57c269c897779d98dc2c34e375595742bd18d4ca95b9baa3a2e4974592851fb81e7d3ef431829e568b2c33eb75985c8e906ac78e9466e1ada77621f13ba054599e506cb86f51a0b1a83bbad4a367918d33d78a428e6d79f6e8508851533265a3898cddbe5cb04deec273703108d15ec8733f0b046548ee7fec668d5a16d3aa1cc2a4c2a65f84ddc6d56b3472c4ea8f484356b0cdd355c44608d3abd2f6b02deae6b3bc97ca1a93ced144f372d556bcbdef71cc712ed5cee03224234e13155f4f6109bd2892e0ebc7e35af1739feef79a817f233b866d55cca38ddc06c33630b5f0035d2be1ceffd9df1891c4b618994bf9a1708c77a948da0a8f30a8a2656281b70520d1e6a15a155df5bb7bfa85071226baef328efd98a166bd9e84bb6842840297d0b63bd450497da89a7487b2a4707a0c9106c6e39ac55ec3ea9b0ff2a6da2f85059d891fbdda7fbf9b79b74dd204a3234fad326170ab18ac2bf038bd317d382b113f2d7f5858e1ae38236794914f68885379c830cd0bbdeda504e5dda2344ed51ca34254be4938a89344ded46c93d9c2ac992ff8cbf583c8916cf04c985507e2b976f96f1d2a0896c729418b0b77a52230776a0c9eca42d0b28e4687e817f865f1c7f76079e4b5305a1ec9530fbc840d00483e0cdc132b8a66898215be13edb89bf985af860606ab8b466444cb5b552f8445071dd6ae390bee0809bab0f3650323f9f74891df100c8bf9c0b6f9ea0416087d160e51333a" - v2 := "0256316adb1004021421da7ba37d046c66e15f601dd84e8407811aa00e2dd51705e674e27f15182d1523a13667c9acadab3c31b8ddd0ca8c7966fc96034b2f3c06aeb530b79a05f35ecc23a4047d976c84d3be1e668ec3bddd2b0fa8b23ad1ccb313f764b5130ae5f6e0fdabe0e198e3bd31e7cb6de2a442919a1d8f9c9b0fd18bdf1d187042f36bd889f069407d2bb297814c641631fe1486f1b8aac804119733b99602c2f2e42352c2d8959250b75ab8e24bfc0361409253d08f9574bb9cddf7d993b63114f86bd2b47d9e658d2bcd403556ee46eb1916f1f754030f84a530acfb7fdf6831bc0ceec1b43bc5023fb59fbc1faee29f1378f42f5add094a77371d5af7212d0606f4f8ee5eb2b42422fdd79632b5c3b6a632f0b3afb27031aff890c382af41dd24d939f021d38103cb773120165998f9834cc38a322128e101c81e8fbe7104c2cf2ca5a1bf1d61c3358ec8d57ed9de722ba2e11288e0ee8a471d318636a07793fd0be081b3d5fd16f12d72f3f0ab021aba51c525675d745cdcec0309e9ace9a8f1285275b652f3667789551621060e979dd34719af67fe32c713e2d94f88d0428cf31ea49fc5a86a21fc7043d0dfb498cdf787d8f10c61e3669a4e8d200bc6f144e2aa54f0af26b6d1b91c9178c3da8732e1c717197427704600ca6d65eb871d89b630877e3ed89b3f7f0becddef0170c490fca0b2c8bbd47ce15b028fd4269e1bc2d909bb5415f32df99641c882642121a62e2fd1c2d8b7181b92d58a63dbfe4242283fcf6cfb568925fe1b42c088f73a7b7859b84d3967247b5d9e8a22a5dcf4a960515a27b48c719588b45ed27ada7c0baeebb505db7cfd7b29c2517ef8d6d97ce4dfe2410615abe2eb6c3ffa2bc7878a3be9ca24f895c386f8e85ffcdcfb4afadefb3c016d7e0a0c36a79e4e8e1ba0bda26d3db8b99b620324150c2f06d237d5bbfcda578339c6322504b2673603c84e66a7af1d113589c6b6dbc1e1b1cb521fe2138a586b2ebfd5a2e32ab85c29bf79c826dc8198e70b7a748931ea096e4376238226b8c7d1b8e4980929d32d4b713efab60e7abc20c7b830626ea1986e2c9f0b2e8eda2264183cf5032885fd137ff33cd63ca6d99b4cdabfcad6cf6578fe05e2c19c607c295475f51a9f5e6385803990c69fb8b36b5f9afd972d9b290d835013128c59c264325d38234b558790d7703a9b21660c0a121a744eeccd4e363af77b052fb9641874c462765f7824de8d079be6599a880f6ec36f412518c86e24f1b046dea0db2de4868d1bc89e0b8d18cfafc9d06ef35e610a8903677437552768ed7f7e1e8e72409e8090ec4b1593df31d0eb476793a68904d96545117906a81abd0bce58f0ceccd9284d130fa9e84f64da05abe01013dad8ceda57fa55f5701b6153d9f110b18b629c7f7604669682e3a728018fa8d3f97f09b30e4a2c524156ba1d8d6d66f243c7aa97e0e28bb6783d0aba1e452163398ed388a0e2f17fa9734a945c7e0280f0cc4f6de886430f496d4e0a5978805b7040ae7d628d7fd5200cee32fa677e9d67cc1e2472c9ab3efb547de6c81a8d6837d8665579a48f5a730dc4cafbe8ca0bcb9768b935e9ad749f4e54ecd4b18a8b64cb4149933cfb5b" - m1, _ := Decrypt([]byte("1234567890abcdef"), &v1) - m2, _ := Decrypt([]byte("1234567890abcdef"), &v2) - - if len(m1) == 0 || len(m2) == 0 { - t.Errorf("Decryption failed") - } - - u1, _ := UnmarshalUser(&m1) - u2, _ := UnmarshalUser(&m2) - - if u1 == nil || u2 == nil { - t.Errorf("Unmarshalling failed") - } - - if !reflect.DeepEqual(u1.chainAddresses, u2.chainAddresses) { - t.Errorf("Decrypted data not equal") - } - - if !reflect.DeepEqual(u1.id, u2.id) { - t.Errorf("Decrypted data not equal") - } - - if !reflect.DeepEqual(u1.email, u2.email) { - t.Errorf("Decrypted data not equal") - } - - if !reflect.DeepEqual(u1.wallet, u2.wallet) { - t.Errorf("Decrypted data not equal") - } -} diff --git a/plugins/passkey_relay_party/seedworks/errors.go b/plugins/passkey_relay_party/seedworks/errors.go index 67b4471..b72175f 100644 --- a/plugins/passkey_relay_party/seedworks/errors.go +++ b/plugins/passkey_relay_party/seedworks/errors.go @@ -4,11 +4,17 @@ type ErrUserNotFound struct{} type ErrEmailEmpty struct{} type ErrInvalidCaptcha struct{} type ErrUserAlreadyExists struct{} +type ErrWalletNotFound struct{} +type ErrChainNotFound struct{} +type ErrNoAvailableWallet struct{} var _ error = ErrUserNotFound{} var _ error = ErrEmailEmpty{} var _ error = ErrInvalidCaptcha{} var _ error = ErrUserAlreadyExists{} +var _ error = ErrWalletNotFound{} +var _ error = ErrChainNotFound{} +var _ error = ErrNoAvailableWallet{} func (e ErrUserNotFound) Error() string { return string("user not found") @@ -25,3 +31,15 @@ func (e ErrInvalidCaptcha) Error() string { func (e ErrUserAlreadyExists) Error() string { return string("user already exists") } + +func (e ErrWalletNotFound) Error() string { + return string("wallet not found") +} + +func (e ErrChainNotFound) Error() string { + return string("chain not found") +} + +func (e ErrNoAvailableWallet) Error() string { + return string("no available wallet") +} diff --git a/plugins/passkey_relay_party/seedworks/reg.go b/plugins/passkey_relay_party/seedworks/reg.go index 1290b39..8d5cb7e 100644 --- a/plugins/passkey_relay_party/seedworks/reg.go +++ b/plugins/passkey_relay_party/seedworks/reg.go @@ -1,19 +1,16 @@ package seedworks -import consts "another_node/internal/seedworks" - -type RegistrationPrepare struct { +type RegistrationByEmailPrepare struct { Email string `json:"email"` } -type Registration struct { - RegistrationPrepare +type RegistrationByEmail struct { + RegistrationByEmailPrepare Origin string `json:"origin"` Captcha string `json:"captcha"` } -type FinishRegistration struct { - RegistrationPrepare - Origin string `json:"origin"` - Network consts.Chain `json:"network"` +type FinishRegistrationByEmail struct { + RegistrationByEmailPrepare + Origin string `json:"origin"` } diff --git a/plugins/passkey_relay_party/seedworks/session.go b/plugins/passkey_relay_party/seedworks/session.go index b839b2e..3a70fcc 100644 --- a/plugins/passkey_relay_party/seedworks/session.go +++ b/plugins/passkey_relay_party/seedworks/session.go @@ -1,6 +1,7 @@ package seedworks import ( + "encoding/base64" "fmt" "strings" "sync" @@ -8,6 +9,7 @@ import ( "github.com/gin-gonic/gin" "github.com/go-webauthn/webauthn/protocol" + "github.com/go-webauthn/webauthn/protocol/webauthncose" "github.com/go-webauthn/webauthn/webauthn" ) @@ -32,8 +34,9 @@ func NewInMemorySessionStore() *SessionStore { return store } -func (store *SessionStore) NewRegSession(reg *Registration) (*protocol.CredentialCreation, error) { +func (store *SessionStore) BeginRegSession(reg *RegistrationByEmail) (*protocol.CredentialCreation, error) { user := newUser(reg.Email) + wan, _ := newWebAuthn(reg.Origin) sessionKey := GetSessionKey(reg.Origin, reg.Email) @@ -43,8 +46,14 @@ func (store *SessionStore) NewRegSession(reg *Registration) (*protocol.Credentia UserVerification: protocol.VerificationRequired, } + credParams := []protocol.CredentialParameter{ + {Type: protocol.PublicKeyCredentialType, Algorithm: webauthncose.AlgES256}, + {Type: protocol.PublicKeyCredentialType, Algorithm: webauthncose.AlgRS256}, + } + if opt, session, err := wan.BeginRegistration(user, webauthn.WithAuthenticatorSelection(authSelect), + webauthn.WithCredentialParameters(credParams), ); err != nil { return nil, err } else { @@ -53,7 +62,7 @@ func (store *SessionStore) NewRegSession(reg *Registration) (*protocol.Credentia } } -func (store *SessionStore) FinishRegSession(reg *FinishRegistration, ctx *gin.Context) (*User, error) { +func (store *SessionStore) FinishRegSession(reg *FinishRegistrationByEmail, ctx *gin.Context) (*User, error) { key := GetSessionKey(reg.Origin, reg.Email) if session := store.Get(key); session == nil { return nil, fmt.Errorf("%s: not found", reg.Email) @@ -68,51 +77,47 @@ func (store *SessionStore) FinishRegSession(reg *FinishRegistration, ctx *gin.Co } } -func (store *SessionStore) NewAuthSession(user *User, signIn *SiginIn) (*protocol.CredentialAssertion, error) { - if user == nil || signIn == nil { - return nil, fmt.Errorf("user or signIn is nil") - } +const session_key_discoverlogin string = "DiscoverLogin" +func (store *SessionStore) BeginDiscoverableAuthSession(signIn *SiginIn) (*protocol.CredentialAssertion, error) { webauthn, _ := newWebAuthn(signIn.Origin) - sessionKey := GetSessionKey(signIn.Origin, signIn.Email) - if opt, session, err := webauthn.BeginLogin(user); err != nil { + if opt, session, err := webauthn.BeginDiscoverableLogin(); err != nil { return nil, err } else { - store.set(sessionKey, webauthn, session, user) + sessionKey := GetSessionKey(signIn.Origin, session_key_discoverlogin) + store.set(sessionKey, webauthn, session, nil) return opt, nil } } -func (store *SessionStore) FinishAuthSession(signIn *SiginIn, ctx *gin.Context) (*User, *webauthn.Credential, error) { - key := GetSessionKey(signIn.Origin, signIn.Email) +func (store *SessionStore) FinishDiscoverableAuthSession(signIn *SiginIn, ctx *gin.Context, find func(rawID, userHandle []byte) (user webauthn.User, err error)) (*webauthn.Credential, error) { + key := GetSessionKey(signIn.Origin, session_key_discoverlogin) if session := store.Get(key); session == nil { - return nil, nil, fmt.Errorf("%s: not found", signIn.Email) + return nil, fmt.Errorf("not found") } else { - if cred, err := session.WebAuthn.FinishLogin(&session.User, session.Data, ctx.Request); err == nil { - store.Remove(key) - session.User.UpdateCredential(cred) - return &session.User, cred, nil + defer store.Remove(key) + if u, err := session.WebAuthn.FinishDiscoverableLogin(find, session.Data, ctx.Request); err == nil { + return u, nil } else { - return nil, nil, err + return nil, err } } } -func (store *SessionStore) NewTxSession(user *User, txSignature *TxSignature) (*protocol.CredentialAssertion, error) { +func (store *SessionStore) BeginTxSession(user *User, txSignature *TxSignature) (*protocol.CredentialAssertion, error) { if user == nil || txSignature == nil { return nil, fmt.Errorf("user or signIn is nil") } webAuthn, _ := newWebAuthn(txSignature.Origin) - sessionKey := GetSessionKey(txSignature.Origin, txSignature.Email, txSignature.Nonce) + sessionKey := GetSessionKey(txSignature.Origin, txSignature.Email, txSignature.Ticket) if opt, session, err := webAuthn.BeginLogin(user, func(opt *protocol.PublicKeyCredentialRequestOptions) { - // opt.Challenge, _ = CreateChallenge(txSignature) // TODO: rewrite the challenge algorithm + opt.Challenge = protocol.URLEncodedBase64(txSignature.TxData) if opt.Extensions == nil { opt.Extensions = make(map[string]interface{}) } - opt.Extensions["txdata"] = txSignature.TxData - opt.Extensions["nonce"] = txSignature.Nonce + opt.Extensions["ticket"] = txSignature.Ticket }, ); err != nil { return nil, err @@ -122,16 +127,20 @@ func (store *SessionStore) NewTxSession(user *User, txSignature *TxSignature) (* } } -func (store *SessionStore) FinishSignSession(paymentSign *TxSignature, ctx *gin.Context) (*User, error) { - key := GetSessionKey(paymentSign.Origin, paymentSign.Email, paymentSign.Nonce) +func (store *SessionStore) FinishTxSession(paymentSign *TxSignature, ctx *gin.Context) (*User, error) { + key := GetSessionKey(paymentSign.Origin, paymentSign.Email, paymentSign.Ticket) if session := store.Get(key); session == nil { return nil, fmt.Errorf("%s: not found", paymentSign.Email) } else { if _, err := session.WebAuthn.FinishLogin(&session.User, session.Data, ctx.Request); err == nil { store.Remove(key) - paymentSign.TxData = session.Data.Extensions["txdata"].(string) - if paymentSign.Nonce != session.Data.Extensions["nonce"].(string) { - return nil, fmt.Errorf("nonce not match") + if paymentSign.Ticket != session.Data.Extensions["ticket"].(string) { + return nil, fmt.Errorf("ticket not match") + } + if txData, err := base64.RawURLEncoding.DecodeString(session.Data.Challenge); err != nil { + return nil, err + } else { + paymentSign.TxData = string(txData) } return &session.User, nil } else { @@ -166,8 +175,14 @@ func (store *SessionStore) set(key string, webauthn *webauthn.WebAuthn, session cache := &sessionCache{ Data: *session, WebAuthn: *webauthn, - User: *user, - expires: 120, + User: func() User { + if user == nil { + return User{} + } else { + return *user + } + }(), + expires: 120, } cache.countdown() store.sessions[key] = cache diff --git a/plugins/passkey_relay_party/seedworks/sigin.go b/plugins/passkey_relay_party/seedworks/sigin.go index 8862338..d53ebb5 100644 --- a/plugins/passkey_relay_party/seedworks/sigin.go +++ b/plugins/passkey_relay_party/seedworks/sigin.go @@ -1,5 +1,5 @@ package seedworks type SiginIn struct { - Registration + Origin string `json:"origin"` } diff --git a/plugins/passkey_relay_party/seedworks/tx_signature.go b/plugins/passkey_relay_party/seedworks/tx_signature.go index 3ad0d5a..b2b27aa 100644 --- a/plugins/passkey_relay_party/seedworks/tx_signature.go +++ b/plugins/passkey_relay_party/seedworks/tx_signature.go @@ -1,16 +1,19 @@ package seedworks +import "another_node/internal/seedworks" + type TxSignature struct { - Nonce string `json:"nonce"` - Email string `json:"-"` - Origin string `json:"origin"` - TxData string `json:"txdata"` + Ticket string `json:"ticket"` + Email string `json:"-"` + Origin string `json:"origin"` + TxData string `json:"txdata"` + Network seedworks.Chain `json:"network"` + NetworkAlias string `json:"network_alias"` } type TxSignatureResult struct { - Code int `json:"code"` - TxData string `json:"txdata"` - Sign string `json:"sign"` - PrivateKey string `json:"privateKey"` - Address string `json:"address"` + Code int `json:"code"` + TxData string `json:"txdata"` + Sign string `json:"sign"` + Address string `json:"address"` } diff --git a/plugins/passkey_relay_party/seedworks/user.go b/plugins/passkey_relay_party/seedworks/user.go index e1d56cd..85d3f03 100644 --- a/plugins/passkey_relay_party/seedworks/user.go +++ b/plugins/passkey_relay_party/seedworks/user.go @@ -2,85 +2,185 @@ package seedworks import ( "another_node/internal/community/account" + "another_node/internal/community/chain" consts "another_node/internal/seedworks" + "another_node/plugins/passkey_relay_party/storage/model" "crypto/ecdsa" "encoding/json" + "github.com/ethereum/go-ethereum/crypto" "github.com/go-webauthn/webauthn/webauthn" ) +type UserChain struct { + InitCode string + AA_Addr string + Alias string + Name consts.Chain + FromHdWalletId int64 +} + type User struct { id []byte credentials []webauthn.Credential email string - wallet *account.HdWallet - chainAddresses map[consts.Chain]string + wallets []account.HdWallet + chainAddresses map[string]UserChain +} + +func (user *User) GetEOA(chain *UserChain) string { + if user.wallets == nil { + return "" + } + for i := range user.wallets { + if user.wallets[i].Id == chain.FromHdWalletId { + return user.wallets[i].Address + } + } + return "" +} + +func (user *User) TryCreateAA(network consts.Chain, alias string) (err error) { + var w *account.HdWallet + for i := range user.wallets { + used := false + for _, j := range user.GetChains() { + if user.wallets[i].Id == j.FromHdWalletId && j.Name == network { + used = true + break + } + } + if !used { + w = &user.wallets[i] + break + } + } + + if w == nil { + return &ErrNoAvailableWallet{} + } + + if user.GetSpecifiyChain(network, alias) != nil { + return nil + } + + aa_address, initCode, err := chain.CreateSmartAccount(w, network) + if err != nil { + return err + } + + user.SetAAWallet(w, &initCode, &aa_address, alias, network) + + return } func newUser(email string) *User { return &User{ id: []byte(email), email: email, - chainAddresses: make(map[consts.Chain]string), + chainAddresses: make(map[string]UserChain), } } -type marshalHDWallet struct { - Mnemonic string `json:"mnemonic"` - Address string `json:"address"` - PrivateKey string `json:"privateKey"` -} - -type marshalUser struct { - Id []byte `json:"id"` - Email string `json:"email"` - Credentials []webauthn.Credential `json:"credentials"` - Wallet marshalHDWallet `json:"wallet"` - AddressMap map[consts.Chain]string `json:"addressMap"` -} +func MappingUser(airaccount *model.AirAccount, getFromVault func(vault *string) (string, error)) (*User, error) { + user := &User{ + id: []byte(airaccount.Email), + email: airaccount.Email, + wallets: make([]account.HdWallet, 0), + credentials: make([]webauthn.Credential, 0), + chainAddresses: make(map[string]UserChain), + } -func UnmarshalUser(rawdata *string) (*User, error) { - m := marshalUser{} + for i := range airaccount.HdWallet { + if hdwalletStr, err := getFromVault(&airaccount.HdWallet[i].WalletVault); err != nil { + return nil, err + } else { + if hdwalletStr != "" { + var hdwallet account.HdWallet + if err := json.Unmarshal([]byte(hdwalletStr), &hdwallet); err != nil { + return nil, err + } else { + hdwallet.Id = airaccount.HdWallet[i].ID + user.wallets = append(user.wallets, hdwallet) + } + } else { + return nil, &ErrWalletNotFound{} + } + } + } - if err := json.Unmarshal([]byte(*rawdata), &m); err != nil { - return nil, err + for i := range airaccount.Passkeys { + passkey := airaccount.Passkeys[i] + var cred webauthn.Credential + json.Unmarshal([]byte(passkey.Rawdata), &cred) + user.credentials = append(user.credentials, cred) } - return &User{ - id: m.Id, - email: m.Email, - credentials: m.Credentials, - wallet: account.RecoverHdWallet(&m.Wallet.Mnemonic, &m.Wallet.Address, &m.Wallet.PrivateKey), - chainAddresses: m.AddressMap, - }, nil + for i := range airaccount.AirAccountChains { + chain := airaccount.AirAccountChains[i] + user.chainAddresses[chain.ChainName+":"+chain.Alias] = UserChain{ + InitCode: chain.InitCode, + AA_Addr: chain.AA_Address, + Name: consts.Chain(chain.ChainName), + Alias: chain.Alias, + FromHdWalletId: chain.FromWalletID, + } + } + return user, nil } var _ webauthn.User = (*User)(nil) func (user *User) GetEmail() string { - return user.email + email, _, _ := user.GetAccounts() + return email } -func (user *User) GetPrivateKeyStr() string { - return user.wallet.PrivateKey() + +func (user *User) GetAccounts() (email, facebook, twitter string) { + email = user.email + facebook = "" + twitter = "" + return } -func (user *User) GetPrivateKeyEcdsa() (*ecdsa.PrivateKey, error) { - return crypto.HexToECDSA(user.GetPrivateKeyStr()) + +func (user *User) GetChains() map[string]UserChain { + return user.chainAddresses } -func (user *User) GetAddress() string { - return user.wallet.Address() + +func (user *User) GetWallets() []account.HdWallet { + return user.wallets } -func (user *User) Marshal() ([]byte, error) { - return json.Marshal(marshalUser{ - Id: user.id, - Email: user.email, - Credentials: user.credentials, - Wallet: marshalHDWallet{ - Mnemonic: user.wallet.Mnemonic(), - Address: user.wallet.Address(), - PrivateKey: user.wallet.PrivateKey(), - }, - AddressMap: user.chainAddresses, - }) + +func (user *User) GetSpecifiyChain(chain consts.Chain, alias string) *UserChain { + if len(chain) == 0 { + return nil + } + + if chainAddr, ok := user.chainAddresses[string(chain)+":"+alias]; ok { + return &chainAddr + } + return nil +} + +func (user *User) GetPrivateKeyEcdsa(chain *UserChain) (*ecdsa.PrivateKey, error) { + for i := range user.wallets { + if user.wallets[i].Id == chain.FromHdWalletId { + return crypto.HexToECDSA(user.wallets[i].PrivateKey) + } + } + panic("no primary wallet") +} + +func (user *User) WalletMarshal() ([][]byte, error) { + rlt := make([][]byte, 0) + for i := range user.wallets { + if wallet, err := json.Marshal(user.wallets[i]); err != nil { + return nil, err + } else { + rlt = append(rlt, wallet) + } + } + return rlt, nil } func (user *User) WebAuthnID() []byte { @@ -109,15 +209,12 @@ func (user *User) AddCredential(cred *webauthn.Credential) { user.credentials = append(user.credentials, *cred) } -func (user *User) UpdateCredential(cred *webauthn.Credential) { - for i, c := range user.credentials { - if string(c.ID) == string(cred.ID) { - user.credentials[i] = *cred - } +func (user *User) SetAAWallet(wallet *account.HdWallet, init_code, aa_address *string, alias string, network consts.Chain) { + user.chainAddresses[string(network)+":"+alias] = UserChain{ + InitCode: *init_code, + AA_Addr: *aa_address, + Alias: alias, + Name: network, + FromHdWalletId: wallet.Id, } } - -func (user *User) SetWallet(wallet *account.HdWallet, address string, network consts.Chain) { - user.wallet = wallet - user.chainAddresses[network] = address -} diff --git a/plugins/passkey_relay_party/seedworks/user_test.go b/plugins/passkey_relay_party/seedworks/user_test.go deleted file mode 100644 index a53d6b3..0000000 --- a/plugins/passkey_relay_party/seedworks/user_test.go +++ /dev/null @@ -1,71 +0,0 @@ -package seedworks - -import ( - "another_node/internal/community/account" - "another_node/internal/seedworks" - "reflect" - "testing" - - "github.com/go-webauthn/webauthn/protocol" - "github.com/go-webauthn/webauthn/webauthn" -) - -func TestUserMarshal(t *testing.T) { - u := newUser("mail@domain.io") - - u.AddCredential(&webauthn.Credential{ - ID: []byte("id"), - PublicKey: []byte("publicKey"), - Transport: []protocol.AuthenticatorTransport{ - protocol.USB, - protocol.Hybrid, - }, - Flags: webauthn.CredentialFlags{ - UserPresent: true, - UserVerified: false, - }, - Authenticator: webauthn.Authenticator{ - AAGUID: []byte("AAGUID"), - SignCount: 1, - CloneWarning: false, - Attachment: protocol.Platform, - }, - }) - u.AddCredential(&webauthn.Credential{ - ID: []byte("id2"), - PublicKey: []byte("publicKey2"), - Transport: []protocol.AuthenticatorTransport{ - protocol.USB, - }, - Flags: webauthn.CredentialFlags{ - UserPresent: false, - UserVerified: true, - }, - Authenticator: webauthn.Authenticator{ - AAGUID: []byte("AAGUID2"), - SignCount: 3, - CloneWarning: true, - Attachment: protocol.CrossPlatform, - }, - }) - - hdWallet, err := account.NewHdWallet(account.HierarchicalPath_ETH) - if err != nil { - t.Fatal(err) - } - u.SetWallet(hdWallet, "abc", seedworks.ArbitrumNova) - - if s, err := u.Marshal(); err != nil { - t.Fatal(err) - } else { - raw := string(s) - - if u2, err := UnmarshalUser(&raw); err != nil { - t.Fatal(err) - } else { - if !reflect.DeepEqual(u, u2) { - t.Fatal("not equal") - } - } - } -} diff --git a/plugins/passkey_relay_party/signin.go b/plugins/passkey_relay_party/signin.go index d0f51d7..b5f359c 100644 --- a/plugins/passkey_relay_party/signin.go +++ b/plugins/passkey_relay_party/signin.go @@ -5,6 +5,7 @@ import ( "another_node/plugins/passkey_relay_party/seedworks" "github.com/gin-gonic/gin" + "github.com/go-webauthn/webauthn/webauthn" ) type SiginInResponse struct { @@ -32,19 +33,10 @@ func (relay *RelayParty) beginSignIn(ctx *gin.Context) { return } - if session := relay.authSessionStore.Get(seedworks.GetSessionKey(signIn.Origin, signIn.Email)); session != nil { - response.BadRequest(ctx, "Already in SignIn") - return + if options, err := relay.authSessionStore.BeginDiscoverableAuthSession(&signIn); err != nil { + response.InternalServerError(ctx, err) } else { - user, err := relay.db.Find(signIn.Email) - if err != nil { - response.NotFound(ctx, err.Error()) - } - if options, err := relay.authSessionStore.NewAuthSession(user, &signIn); err != nil { - response.InternalServerError(ctx, err) - } else { - response.GetResponse().WithDataSuccess(ctx, options.Response) - } + response.GetResponse().SuccessWithData(ctx, options.Response) } } @@ -54,7 +46,6 @@ func (relay *RelayParty) beginSignIn(ctx *gin.Context) { // @Tags Plugins Passkey // @Accept json // @Produce json -// @Param email query string true "user email" Format(email) // @Param origin query string true "origin" // @Param signinBody body protocol.CredentialAssertionResponse true "Verify SignIn" // @Success 200 {object} SiginInResponse "OK" @@ -63,21 +54,20 @@ func (relay *RelayParty) beginSignIn(ctx *gin.Context) { func (relay *RelayParty) finishSignIn(ctx *gin.Context) { // body works for SDK, the additional info appends to query stubSignIn := seedworks.SiginIn{ - Registration: seedworks.Registration{ - RegistrationPrepare: seedworks.RegistrationPrepare{ - Email: ctx.Query("email"), - }, - Origin: ctx.Query("origin"), - }, + Origin: ctx.Query("origin"), } - user, _, err := relay.authSessionStore.FinishAuthSession(&stubSignIn, ctx) + var user *seedworks.User + _, err := relay.authSessionStore.FinishDiscoverableAuthSession(&stubSignIn, ctx, func(rawID, userHandle []byte) (webauthn.User, error) { + var err error + user, err = relay.db.FindUser(string(userHandle)) + return user, err + }) if err != nil { response.GetResponse().FailCode(ctx, 401, "SignIn failed: "+err.Error()) return } - relay.db.Save(user, true) - + ctx.Set("user", user) ginJwtMiddleware().LoginHandler(ctx) } diff --git a/plugins/passkey_relay_party/signup.go b/plugins/passkey_relay_party/signup.go index 49dc3a6..f8fd256 100644 --- a/plugins/passkey_relay_party/signup.go +++ b/plugins/passkey_relay_party/signup.go @@ -2,27 +2,34 @@ package plugin_passkey_relay_party import ( "another_node/internal/community/account" - "another_node/internal/community/chain" consts "another_node/internal/seedworks" "another_node/internal/web_server/pkg/response" "another_node/plugins/passkey_relay_party/seedworks" + "encoding/base64" "errors" - "strings" + "fmt" "github.com/gin-gonic/gin" ) -// regPrepare +//lint:ignore U1000 because it's used in the swagger +type finishRegistrationResponse struct { + AccountInitCode string `json:"account_init_code"` + AccountAddress string `json:"account_address"` + EoaAddress string `json:"eoa_address"` +} + +// regPrepareByEmail // @Summary Prepare SignUp // @Tags Plugins Passkey // @Description Send captcha to email for confirming ownership // @Accept json // @Product json -// @Param registrationBody body seedworks.RegistrationPrepare true "Send Captcha to Email" +// @Param registrationBody body seedworks.RegistrationByEmail true "Send Captcha to Email" // @Router /api/passkey/v1/reg/prepare [post] // @Success 200 -func (relay *RelayParty) regPrepare(ctx *gin.Context) { - var reg seedworks.Registration +func (relay *RelayParty) regPrepareByEmail(ctx *gin.Context) { + var reg seedworks.RegistrationByEmail if err := ctx.ShouldBindJSON(®); err != nil { response.BadRequest(ctx, err.Error()) return @@ -35,68 +42,41 @@ func (relay *RelayParty) regPrepare(ctx *gin.Context) { response.GetResponse().Success(ctx) } -// beginRegistration +// beginRegistrationByEmail // @Summary Begin SignUp // @Tags Plugins Passkey // @Description Send challenge for passkey // @Accept json // @Product json -// @Param registrationBody body seedworks.Registration true "Begin Registration" +// @Param registrationBody body seedworks.RegistrationByEmail true "Begin Registration" // @Router /api/passkey/v1/reg [post] // @Success 200 {object} protocol.PublicKeyCredentialCreationOptions -func (relay *RelayParty) beginRegistration(ctx *gin.Context) { - var reg seedworks.Registration +func (relay *RelayParty) beginRegistrationByEmail(ctx *gin.Context) { + var reg seedworks.RegistrationByEmail if err := ctx.ShouldBindJSON(®); err != nil { response.BadRequest(ctx, err.Error()) return } - // TODO: special logic for align testing - if !strings.HasSuffix(reg.Email, "@aastar.org") && reg.Captcha != "111111" { - if err := relay.emailChallenge(reg.Email, reg.Captcha); err != nil { - response.BadRequest(ctx, err.Error()) - return - } - } - if u, err := relay.findUserByEmail(reg.Email); err != nil && !errors.Is(err, seedworks.ErrUserNotFound{}) { - response.InternalServerError(ctx, err.Error()) - return - } else if u != nil { - response.BadRequest(ctx, "User already exists") + if err := relay.emailChallenge(reg.Email, reg.Captcha); err != nil { + response.BadRequest(ctx, err.Error()) return } - // TODO: if the user is not exists but in community, re-register the user - sessionKey := seedworks.GetSessionKey(reg.Origin, reg.Email) if session := relay.authSessionStore.Get(sessionKey); session != nil { relay.authSessionStore.Remove(sessionKey) } - if options, err := relay.authSessionStore.NewRegSession(®); err != nil { + if options, err := relay.authSessionStore.BeginRegSession(®); err != nil { response.InternalServerError(ctx, err.Error()) } else { - response.GetResponse().WithDataSuccess(ctx, options.Response) + response.GetResponse().SuccessWithData(ctx, options.Response) } } -//lint:ignore U1000 because it's used in the swagger -type finishRegistrationResponse struct { - AccountInitCode string `json:"account_init_code"` - AccountAddress string `json:"account_address"` - EoaAddress string `json:"eoa_address"` -} - -// func replayLoginResponse(ctx *gin.Context, append func(c *gin.Context)) { -// ctx.Writer.WriteString("{\"token\": ") -// ginJwtMiddleware().LoginHandler(ctx) -// ctx.Writer.WriteString(",\"append\": ") -// append(ctx) -// ctx.Writer.WriteString("}") -// } - -// finishRegistration -// @Summary Finish SignUp +// finishRegistrationByEmail +// @Summary Finish SignUp By Email // @Tags Plugins Passkey // @Description Verify attestations, register user and return JWT // @Accept json @@ -104,63 +84,76 @@ type finishRegistrationResponse struct { // @Param email query string true "user email" Format(email) // @Param origin query string true "origin" // @Param network query string false "network" +// @Param alias query string false "network" // @Param registrationBody body protocol.CredentialCreationResponse true "Verify Registration" // @Router /api/passkey/v1/reg/verify [post] // @Success 200 {object} SiginInResponse "OK" -func (relay *RelayParty) finishRegistration(ctx *gin.Context) { +func (relay *RelayParty) finishRegistrationByEmail(ctx *gin.Context) { - // TODO: for tokyo ONLY network := consts.Chain(ctx.Query("network")) if !isSupportChain(network) { - response.BadRequest(ctx, "network not supported, please specify a valid network, e.g.: optimism-mainnet, base-sepolia, optimism-sepolia, ethereum-sepolia") + response.BadRequest(ctx, "network not supported, please specify a valid network, e.g.: optimism-mainnet, base-sepolia, optimism-sepolia") return } - // body works for parser, the additional info appends to query - stubReg := seedworks.FinishRegistration{ - RegistrationPrepare: seedworks.RegistrationPrepare{ + // body-stream works for parser, the additional info appends to query + stubReg := seedworks.FinishRegistrationByEmail{ + RegistrationByEmailPrepare: seedworks.RegistrationByEmailPrepare{ Email: ctx.Query("email"), }, - Origin: ctx.Query("origin"), - Network: consts.Chain(ctx.Query("network")), + Origin: ctx.Query("origin"), } if user, err := relay.authSessionStore.FinishRegSession(&stubReg, ctx); err != nil { response.GetResponse().FailCode(ctx, 401, "SignUp failed: "+err.Error()) - return } else { - // TODO: special logic for align testing - if strings.HasSuffix(stubReg.Email, "@aastar.org") { - response.GetResponse().WithDataSuccess(ctx, user) - return - } - if initCode, address, eoaAddress, err := createAA(user, stubReg.Network); err != nil { // TODO: persistent initCode and address - response.InternalServerError(ctx, err.Error()) - return - } else { + signup(relay, ctx, user) + } +} - // TODO: special logic for tokyo - relay.db.Save(user, false) - relay.db.SaveAccounts(user, initCode, address, eoaAddress, string(network)) +const defaultWalletCount = 5 - ginJwtMiddleware().LoginHandler(ctx) +func createWalletsForNewUser(relay *RelayParty, ctx *gin.Context, user *seedworks.User) { + paths := make([]account.HierarchicalPath, defaultWalletCount) + for i := 0; i < defaultWalletCount && i < 10; i++ { + paths[i] = account.HierarchicalPath(fmt.Sprintf(account.HierarchicalPath_ETH_FMT, i)) + } + wallets, err := account.NewHdWallet(paths...) + if err != nil { + response.InternalServerError(ctx, err.Error()) + return + } - return - } + if err := relay.db.CreateAccount(user.GetEmail(), wallets); err != nil { + response.InternalServerError(ctx, err.Error()) + return } } -// createAA represents creating an Account Abstraction for the user -func createAA(user *seedworks.User, network consts.Chain) (initCode, address, eoaAddress string, err error) { - if w, err := account.NewHdWallet(account.HierarchicalPath_ETH); err != nil { - return "", "", "", err - } else { - address, initCode, err := chain.CreateSmartAccount(w, network) - if err != nil { - return "", "", "", err +func signup(relay *RelayParty, ctx *gin.Context, user *seedworks.User) { + + createWalletsForNewUser(relay, ctx, user) + + // check if user passkey already exists + if len(user.WebAuthnCredentials()) != 1 { + response.BadRequest(ctx, errors.New("not support multiple credentials")) + return + } + + signupCredId := base64.URLEncoding.EncodeToString(user.WebAuthnCredentials()[0].ID) + if u, _ := relay.db.FindUserByPasskey(user.GetEmail(), signupCredId); u != nil { + user = u + } + + if err := relay.db.SaveAccounts(user); err != nil { + if errors.Is(err, seedworks.ErrUserAlreadyExists{}) { + response.BadRequest(ctx, err.Error()) + } else { + response.InternalServerError(ctx, err.Error()) } - user.SetWallet(w, address, network) - return initCode, address, w.Address(), nil + return } + + ginJwtMiddleware().LoginHandler(ctx) } diff --git a/plugins/passkey_relay_party/storage/inmemory.go b/plugins/passkey_relay_party/storage/inmemory.go deleted file mode 100644 index 07d59cd..0000000 --- a/plugins/passkey_relay_party/storage/inmemory.go +++ /dev/null @@ -1,90 +0,0 @@ -package storage - -import ( - "another_node/plugins/passkey_relay_party/seedworks" - "errors" - "time" -) - -type captcha struct { - code string - time time.Time -} - -type InMemory struct { - users map[string]*seedworks.User - captchas map[string]captcha - accounts map[string]interface{} -} - -var _ Db = (*InMemory)(nil) - -func NewInMemory() *InMemory { - return &InMemory{ - users: make(map[string]*seedworks.User), - } -} - -func (db *InMemory) Save(user *seedworks.User, allowUpdate bool) error { - if user == nil { - return errors.New("user is nil") - } - db.users[string(user.WebAuthnID())] = user - - return nil -} - -func (db *InMemory) Find(email string) (*seedworks.User, error) { - if user, ok := db.users[email]; ok { - return user, nil - } - - return nil, seedworks.ErrUserNotFound{} -} - -func (db *InMemory) SaveChallenge(email, code string) error { - db.captchas[email] = captcha{ - code: code, - time: time.Now(), - } - return nil -} -func (db *InMemory) Challenge(email, code string) bool { - if v, ok := db.captchas[email]; ok { - if v.code == code && time.Since(v.time) < 10*time.Minute { - return true - } - } - return false -} - -func (db *InMemory) SaveAccounts(user *seedworks.User, initCode, addr, eoaAddr, chain string) error { - if len(db.accounts) == 0 { - db.accounts = make(map[string]interface{}) - } - - db.accounts[user.GetEmail()+":"+chain] = &struct { - InitCode string - Address string - EoaAddress string - Chain string - }{ - InitCode: initCode, - Address: addr, - EoaAddress: eoaAddr, - } - return nil -} - -func (db *InMemory) GetAccounts(email, chain string) (initCode, addr, eoaAddr string, err error) { - if v, ok := db.accounts[email+":"+chain]; ok { - if a, ok := v.(*struct { - InitCode string - Address string - EoaAddress string - }); ok { - return a.InitCode, a.Address, a.EoaAddress, nil - } - } - return "", "", "", errors.New("account not found") -} diff --git a/plugins/passkey_relay_party/storage/interface.go b/plugins/passkey_relay_party/storage/interface.go index 4d54eba..90c7d9a 100644 --- a/plugins/passkey_relay_party/storage/interface.go +++ b/plugins/passkey_relay_party/storage/interface.go @@ -1,14 +1,16 @@ package storage import ( + "another_node/internal/community/account" "another_node/plugins/passkey_relay_party/seedworks" + "another_node/plugins/passkey_relay_party/storage/model" ) type Db interface { - Save(user *seedworks.User, allowUpdate bool) error - Find(email string) (*seedworks.User, error) - SaveChallenge(email, captcha string) error - Challenge(email, captcha string) bool - SaveAccounts(user *seedworks.User, initCode, addr, eoaAddr, network string) error - GetAccounts(email, network string) (initCode, addr, eoaAddr string, err error) + FindUser(userHandler string) (*seedworks.User, error) + FindUserByPasskey(userHandler, credId string) (*seedworks.User, error) + SaveChallenge(captchaType model.ChallengeType, challenger, captcha string) error + Challenge(captchaType model.ChallengeType, challenger, captcha string) bool + CreateAccount(email string, wallets []account.HdWallet) error + SaveAccounts(user *seedworks.User) error } diff --git a/plugins/passkey_relay_party/storage/migrations/migrate.go b/plugins/passkey_relay_party/storage/migrations/migrate.go index c84b37b..fd1baeb 100644 --- a/plugins/passkey_relay_party/storage/migrations/migrate.go +++ b/plugins/passkey_relay_party/storage/migrations/migrate.go @@ -17,6 +17,7 @@ func init() { // 迁移对象必需按从旧到新的顺序添加 migrations = []Migration{ &Migration20240711{}, + &Migration20240828{}, } } diff --git a/plugins/passkey_relay_party/storage/migrations/migrate_20240711.go b/plugins/passkey_relay_party/storage/migrations/migrate_20240711.go index 331054c..25445fb 100644 --- a/plugins/passkey_relay_party/storage/migrations/migrate_20240711.go +++ b/plugins/passkey_relay_party/storage/migrations/migrate_20240711.go @@ -13,44 +13,19 @@ var _ Migration = (*Migration20240711)(nil) func (m *Migration20240711) Up(db *gorm.DB) error { - if !db.Migrator().HasTable(&model.User{}) { - if err := db.AutoMigrate(&model.User{}); err != nil { - return err - } - } - if !db.Migrator().HasTable(&model.CaptchaChallenge{}) { if err := db.AutoMigrate(&model.CaptchaChallenge{}); err != nil { return err } } - - if !db.Migrator().HasTable(&model.UserAccount{}) { - if err := db.AutoMigrate(&model.UserAccount{}); err != nil { - return err - } - } return nil } func (m *Migration20240711) Down(db *gorm.DB) error { - if err := db.Migrator().DropTable( - &model.User{}, - ); err != nil { - return err - } - if err := db.Migrator().DropTable( &model.CaptchaChallenge{}, ); err != nil { return err } - - if err := db.Migrator().DropTable( - &model.UserAccount{}, - ); err != nil { - return err - } - return nil } diff --git a/plugins/passkey_relay_party/storage/migrations/migrate_20240828.go b/plugins/passkey_relay_party/storage/migrations/migrate_20240828.go new file mode 100644 index 0000000..3d8ec9f --- /dev/null +++ b/plugins/passkey_relay_party/storage/migrations/migrate_20240828.go @@ -0,0 +1,69 @@ +package migrations + +import ( + "another_node/plugins/passkey_relay_party/storage/model" + + "gorm.io/gorm" +) + +type Migration20240828 struct { +} + +var _ Migration = (*Migration20240828)(nil) + +func (m *Migration20240828) Up(db *gorm.DB) error { + + if !db.Migrator().HasTable(&model.AirAccount{}) { + if err := db.AutoMigrate(&model.AirAccount{}); err != nil { + return err + } + } + + if !db.Migrator().HasTable(&model.AirAccountChain{}) { + if err := db.AutoMigrate(&model.AirAccountChain{}); err != nil { + return err + } + } + + if !db.Migrator().HasTable(&model.Passkey{}) { + if err := db.AutoMigrate(&model.Passkey{}); err != nil { + return err + } + } + + if !db.Migrator().HasTable(&model.HdWallet{}) { + if err := db.AutoMigrate(&model.HdWallet{}); err != nil { + return err + } + } + + return nil +} + +func (m *Migration20240828) Down(db *gorm.DB) error { + if err := db.Migrator().DropTable( + &model.HdWallet{}, + ); err != nil { + return err + } + + if err := db.Migrator().DropTable( + &model.Passkey{}, + ); err != nil { + return err + } + + if err := db.Migrator().DropTable( + &model.AirAccountChain{}, + ); err != nil { + return err + } + + if err := db.Migrator().DropTable( + &model.AirAccount{}, + ); err != nil { + return err + } + + return nil +} diff --git a/plugins/passkey_relay_party/storage/model/airaccount.go b/plugins/passkey_relay_party/storage/model/airaccount.go new file mode 100644 index 0000000..fdca362 --- /dev/null +++ b/plugins/passkey_relay_party/storage/model/airaccount.go @@ -0,0 +1,17 @@ +package model + +import "another_node/internal/community/storage" + +type AirAccount struct { + storage.BaseData + Email string `json:"email" gorm:"type:varchar(255)"` + Facebook string `json:"facebook" gorm:"type:varchar(255)"` + Twitter string `json:"twitter" gorm:"type:varchar(255)"` + HdWallet []HdWallet `json:"hdwallet" gorm:"foreignKey:AirAccountID"` + Passkeys []Passkey `json:"passkeys" gorm:"foreignKey:AirAccountID"` + AirAccountChains []AirAccountChain `json:"airaccount_chains" gorm:"foreignKey:AirAccountID"` +} + +func (AirAccount) TableName() string { + return "airaccounts" +} diff --git a/plugins/passkey_relay_party/storage/model/airaccount_chain.go b/plugins/passkey_relay_party/storage/model/airaccount_chain.go new file mode 100644 index 0000000..8832865 --- /dev/null +++ b/plugins/passkey_relay_party/storage/model/airaccount_chain.go @@ -0,0 +1,19 @@ +package model + +import "another_node/internal/community/storage" + +type AirAccountChain struct { + storage.BaseData + AirAccountID int64 `json:"-" gorm:"column:airaccount_id"` + AirAccount AirAccount `json:"-" gorm:"foreignKey:AirAccountID;references:ID"` + InitCode string `json:"init_code" gorm:"type:text"` + AA_Address string `json:"aa_address" gorm:"type:varchar(255)"` + ChainName string `json:"chain_name" gorm:"type:varchar(50);column:chain_name"` + Alias string `json:"alias" gorm:"type:varchar(50)"` + FromWalletID int64 `json:"-" gorm:"column:hdwallet_id"` + FromWallet HdWallet `json:"-" gorm:"foreignKey:FromWalletID;references:ID"` +} + +func (AirAccountChain) TableName() string { + return "airaccount_chains" +} diff --git a/plugins/passkey_relay_party/storage/model/captcha_challenge.go b/plugins/passkey_relay_party/storage/model/captcha_challenge.go index 0fdf8a3..00adfd1 100644 --- a/plugins/passkey_relay_party/storage/model/captcha_challenge.go +++ b/plugins/passkey_relay_party/storage/model/captcha_challenge.go @@ -1,8 +1,6 @@ package model -import ( - "another_node/internal/community/storage" -) +import "time" type ChallengeType string @@ -11,10 +9,11 @@ const ( ) type CaptchaChallenge struct { - storage.BaseData - Type ChallengeType `gorm:"type:varchar(255);column:type"` - Object string `gorm:"type:varchar(255);column:object;index:idx_object"` - Code string `gorm:"type:varchar(16);column:code"` + ID int64 `gorm:"primaryKey;autoIncrement;column:id" json:"id"` + CreatedAt time.Time `gorm:"column:created_at" json:"created_at"` + Type ChallengeType `gorm:"type:varchar(255);column:type"` + Object string `gorm:"type:varchar(255);column:object;index:idx_object"` + Code string `gorm:"type:varchar(16);column:code"` } func (CaptchaChallenge) TableName() string { diff --git a/plugins/passkey_relay_party/storage/model/hdwallet.go b/plugins/passkey_relay_party/storage/model/hdwallet.go new file mode 100644 index 0000000..65479db --- /dev/null +++ b/plugins/passkey_relay_party/storage/model/hdwallet.go @@ -0,0 +1,14 @@ +package model + +import "another_node/internal/community/storage" + +type HdWallet struct { + storage.BaseData + AirAccount AirAccount `json:"-" gorm:"foreignKey:AirAccountID;references:ID"` + AirAccountID int64 `json:"-" gorm:"column:airaccount_id"` + WalletVault string `json:"wallet_vault" gorm:"type:text"` +} + +func (HdWallet) TableName() string { + return "hdwallets" +} diff --git a/plugins/passkey_relay_party/storage/model/passkey.go b/plugins/passkey_relay_party/storage/model/passkey.go new file mode 100644 index 0000000..ed5ff66 --- /dev/null +++ b/plugins/passkey_relay_party/storage/model/passkey.go @@ -0,0 +1,18 @@ +package model + +import "another_node/internal/community/storage" + +type Passkey struct { + storage.BaseData + AirAccountID int64 `json:"-" gorm:"column:airaccount_id"` + AirAccount AirAccount `json:"-" gorm:"foreignKey:AirAccountID;references:ID"` + CredentialId string `json:"credential_id" gorm:"type:varchar(128)"` + PublicKey string `json:"public_key" gorm:"type:varchar(512)"` + Algorithm string `json:"algorithm" gorm:"type:varchar(64)"` + Origin string `json:"origin" gorm:"type:varchar(255)"` + Rawdata string `json:"-" gorm:"type:text;column:rawdata"` +} + +func (Passkey) TableName() string { + return "passkeys" +} diff --git a/plugins/passkey_relay_party/storage/model/user.go b/plugins/passkey_relay_party/storage/model/user.go deleted file mode 100644 index 75d11d4..0000000 --- a/plugins/passkey_relay_party/storage/model/user.go +++ /dev/null @@ -1,17 +0,0 @@ -package model - -import ( - "another_node/internal/community/storage" - "time" -) - -type User struct { - storage.BaseData - Email string `json:"email" gorm:"type:varchar(255);unique_index"` - LastLoginAt *time.Time `json:"last_login_at" gorm:"column:last_login_at"` - Rawdata string `json:"-" gorm:"type:text;column:rawdata"` -} - -func (User) TableName() string { - return "passkey_users" -} diff --git a/plugins/passkey_relay_party/storage/model/user_account.go b/plugins/passkey_relay_party/storage/model/user_account.go deleted file mode 100644 index f4784bd..0000000 --- a/plugins/passkey_relay_party/storage/model/user_account.go +++ /dev/null @@ -1,18 +0,0 @@ -package model - -import ( - "another_node/internal/community/storage" -) - -type UserAccount struct { - storage.BaseData - Email string `json:"email" gorm:"type:varchar(255);unique_index"` - InitCode string `json:"init_code" gorm:"type:text;column:init_code"` - Address string `json:"address" gorm:"column:address"` - EoaAddress string `json:"eoa_address" gorm:"column:eoa_address"` - Chain string `json:"chain" gorm:"column:chain"` -} - -func (UserAccount) TableName() string { - return "use_accounts" -} diff --git a/plugins/passkey_relay_party/storage/pgsql.go b/plugins/passkey_relay_party/storage/pgsql.go index b408057..653da65 100644 --- a/plugins/passkey_relay_party/storage/pgsql.go +++ b/plugins/passkey_relay_party/storage/pgsql.go @@ -2,13 +2,19 @@ package storage import ( "another_node/conf" + "another_node/internal/community/account" passkey_conf "another_node/plugins/passkey_relay_party/conf" "another_node/plugins/passkey_relay_party/seedworks" "another_node/plugins/passkey_relay_party/storage/model" + "encoding/base64" + "encoding/json" "errors" + "strconv" + "strings" "time" "gorm.io/gorm" + "gorm.io/gorm/clause" ) type PgsqlStorage struct { @@ -25,69 +31,180 @@ func NewPgsqlStorage() *PgsqlStorage { } } -func (db *PgsqlStorage) Save(user *seedworks.User, allowUpdate bool) error { - if data, err := user.Marshal(); err != nil { - return err - } else { - if encrypted, err := seedworks.Encrypt(db.vaultSecret, data); err != nil { +// CreateAccount create user account with init hdwallets +// won't throw error if account already exists +func (db *PgsqlStorage) CreateAccount(email string, wallets []account.HdWallet) error { + + modelWallet := make([]model.HdWallet, len(wallets)) + for i := range wallets { + if plain, err := json.Marshal(wallets[i]); err != nil { return err } else { - exists, err := db.Find(user.GetEmail()) - if allowUpdate { - if exists == nil || err != nil { - return seedworks.ErrUserNotFound{} - } else { - lastLogin := time.Now() - return db.client.Model(&model.User{}). - Where("email = ?", user.GetEmail()). - Updates(model.User{ - Rawdata: encrypted, - LastLoginAt: &lastLogin, - }).Error + if vault, err := seedworks.Encrypt(db.vaultSecret, plain); err != nil { + return err + } else { + modelWallet[i] = model.HdWallet{ + WalletVault: vault, + } + } + } + } + + return db.client.Transaction(func(tx *gorm.DB) error { + if err := tx.Where("email = ?", email).First(&model.AirAccount{}).Error; err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + airAccount := model.AirAccount{ + Email: email, + HdWallet: modelWallet, + } + + if err := tx.Omit("updated_at").Create(&airAccount).Error; err != nil { + return err + } + } + } + return nil + }) +} + +// TODO: network is a factor for judging the wallet used or not +func updateWalletUsed(w []model.HdWallet, usedWalletId []int64) (*model.HdWallet, error) { + for i := range w { + used := false + for j := range usedWalletId { + if w[i].ID == usedWalletId[j] { + used = true + break + } + } + if !used { + return &w[i], nil + } + } + return nil, seedworks.ErrNoAvailableWallet{} +} + +// SaveAccounts create or update user accounts +func (db *PgsqlStorage) SaveAccounts(user *seedworks.User) error { + // support email only for now + return db.client.Transaction(func(tx *gorm.DB) error { + email, _, _ := user.GetAccounts() + airAccount := model.AirAccount{} + if err := db.client.Preload(clause.Associations).Where("email = ?", email).First(&airAccount).Error; err != nil { + // SaveAccounts only update user account, so if user not exists, return error + return err + } + + changed := false + + for _, v := range user.GetChains() { + flag := false + for j := range airAccount.AirAccountChains { + if airAccount.AirAccountChains[j].ChainName == string(v.Name) && + strings.EqualFold(airAccount.AirAccountChains[j].Alias, v.Alias) { + flag = true + break } + } + if flag { + continue + } + if w, err := updateWalletUsed(airAccount.HdWallet, func() []int64 { + ids := make([]int64, 0) + for i := range airAccount.AirAccountChains { + if airAccount.AirAccountChains[i].ChainName == string(v.Name) { + ids = append(ids, airAccount.AirAccountChains[i].FromWalletID) + } + } + return ids + }()); err != nil { + return err } else { - if exists != nil { - return seedworks.ErrUserAlreadyExists{} - } else if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { + if err := tx.Save(&w).Error; err != nil { return err } + airAccount.AirAccountChains = append(airAccount.AirAccountChains, model.AirAccountChain{ + InitCode: v.InitCode, + AA_Address: v.AA_Addr, + ChainName: string(v.Name), + Alias: v.Alias, + FromWalletID: w.ID, + }) + } + changed = true + } + + for i := range user.WebAuthnCredentials() { + cred := user.WebAuthnCredentials()[i] + credId := base64.URLEncoding.EncodeToString(cred.ID) + flag := false + for j := range airAccount.Passkeys { + if airAccount.Passkeys[j].CredentialId == credId { + flag = true + break + } + } + if flag { + continue + } + rawdata, _ := json.Marshal(cred) + passkey := model.Passkey{ + CredentialId: credId, + PublicKey: base64.URLEncoding.EncodeToString(cred.PublicKey), + Algorithm: strconv.Itoa(int(cred.Attestation.PublicKeyAlgorithm)), + Origin: "-", + Rawdata: string(rawdata), + } + airAccount.Passkeys = append(airAccount.Passkeys, passkey) + changed = true + } - return db.client.Model(&model.User{}).Create(&model.User{ - Email: user.GetEmail(), - Rawdata: encrypted, - }).Error + if changed { + if err := tx.Omit("created_at", "email").Save(&airAccount).Error; err != nil { + return err } } + + return nil + }) +} + +func (db *PgsqlStorage) FindUser(userHandler string) (*seedworks.User, error) { + airaccount := model.AirAccount{} + if err := db.client.Preload(clause.Associations).Where("email = ?", userHandler).First(&airaccount).Error; err != nil { + return nil, err + } else { + return seedworks.MappingUser(&airaccount, func(vault *string) (string, error) { + return seedworks.Decrypt(db.vaultSecret, vault) + }) } } -func (db *PgsqlStorage) Find(email string) (*seedworks.User, error) { - user := model.User{} - if err := db.client.Where("email = ?", email).First(&user).Error; err != nil { +func (db *PgsqlStorage) FindUserByPasskey(userHandler, credId string) (*seedworks.User, error) { + airaccount := model.AirAccount{} + if err := db.client.Preload(clause.Associations).Where("email = ? AND credential_id = ?", userHandler, credId).First(&airaccount).Error; err != nil { return nil, err } else { - if data, err := seedworks.Decrypt(db.vaultSecret, &user.Rawdata); err != nil { - return nil, err - } else { - return seedworks.UnmarshalUser(&data) - } + return seedworks.MappingUser(&airaccount, func(vault *string) (string, error) { + return seedworks.Decrypt(db.vaultSecret, vault) + }) } } -func (db *PgsqlStorage) SaveChallenge(email, captcha string) error { +func (db *PgsqlStorage) SaveChallenge(captchaType model.ChallengeType, email, captcha string) error { return db.client.Model(&model.CaptchaChallenge{}).Create(&model.CaptchaChallenge{ - Type: model.Email, + Type: captchaType, Object: email, Code: captcha, }).Error } -func (db *PgsqlStorage) Challenge(email, captcha string) bool { +func (db *PgsqlStorage) Challenge(captchaType model.ChallengeType, email, captcha string) bool { success := false err := db.client.Transaction(func(tx *gorm.DB) error { challenge := model.CaptchaChallenge{} if err := tx. - Where("object = ? AND code = ? AND type = ?", email, captcha, model.Email). + Where("object = ? AND code = ? AND type = ?", email, captcha, captchaType). Order("created_at DESC"). First(&challenge).Error; err != nil { return err @@ -102,22 +219,3 @@ func (db *PgsqlStorage) Challenge(email, captcha string) bool { return err == nil && success } - -func (db *PgsqlStorage) SaveAccounts(user *seedworks.User, initCode, addr, eoaAddr, chain string) error { - return db.client.Model(&model.UserAccount{}).Create(&model.UserAccount{ - Email: user.GetEmail(), - InitCode: initCode, - Address: addr, - EoaAddress: eoaAddr, - Chain: chain, - }).Error -} - -func (db *PgsqlStorage) GetAccounts(email, chain string) (initCode, addr, eoaAddr string, err error) { - account := model.UserAccount{} - if err := db.client.Where("email = ? AND chain = ?", email, chain).First(&account).Error; err != nil { - return "", "", "", err - } else { - return account.InitCode, account.Address, account.EoaAddress, nil - } -} diff --git a/plugins/passkey_relay_party/support_chain.go b/plugins/passkey_relay_party/support_chain.go index e79e93b..055fc53 100644 --- a/plugins/passkey_relay_party/support_chain.go +++ b/plugins/passkey_relay_party/support_chain.go @@ -2,14 +2,17 @@ package plugin_passkey_relay_party import "another_node/internal/seedworks" +var supportChains = map[seedworks.Chain]bool{ + seedworks.EthereumSepolia: true, + seedworks.OptimismSepolia: true, + seedworks.BaseSepolia: true, +} + func isSupportChain(chain seedworks.Chain) bool { if len(chain) > 0 { - if chain != seedworks.OptimismSepolia && chain != seedworks.BaseSepolia && chain != seedworks.OptimismMainnet { - return false - } else { + if support, exists := supportChains[chain]; exists && support { return true } - } else { - return false } + return false } diff --git a/plugins/passkey_relay_party/tx_signature.go b/plugins/passkey_relay_party/tx_signature.go index d8d97a1..1e04631 100644 --- a/plugins/passkey_relay_party/tx_signature.go +++ b/plugins/passkey_relay_party/tx_signature.go @@ -1,7 +1,7 @@ package plugin_passkey_relay_party import ( - "another_node/internal/common_util" + consts "another_node/internal/seedworks" "another_node/internal/web_server/pkg/response" "another_node/plugins/passkey_relay_party/seedworks" "net/http" @@ -36,18 +36,18 @@ func (relay *RelayParty) beginTxSignature(ctx *gin.Context) { tx.Email = email } - if session := relay.txSessionStore.Get(seedworks.GetSessionKey(tx.Origin, tx.Email, tx.Nonce)); session != nil { + if session := relay.txSessionStore.Get(seedworks.GetSessionKey(tx.Origin, tx.Email, tx.Ticket)); session != nil { response.BadRequest(ctx, "Already in Signature Process") return } else { - user, err := relay.db.Find(tx.Email) + user, err := relay.db.FindUser(tx.Email) if err != nil { - response.NotFound(ctx, err.Error()) + response.GetResponse().SuccessWithDataAndCode(http.StatusNotFound, ctx, &seedworks.ErrUserNotFound{}) } - if options, err := relay.txSessionStore.NewTxSession(user, &tx); err != nil { + if options, err := relay.txSessionStore.BeginTxSession(user, &tx); err != nil { response.InternalServerError(ctx, err) } else { - response.GetResponse().WithDataSuccess(ctx, options.Response) + response.GetResponse().SuccessWithData(ctx, options.Response) } } } @@ -60,14 +60,22 @@ func (relay *RelayParty) beginTxSignature(ctx *gin.Context) { // @Produce json // @Param paymentSign body protocol.CredentialAssertionResponse true "Verify SignIn" // @Param origin query string true "origin" -// @Param nonce query string true "nonce" +// @Param ticket query string true "ticket" +// @Param network query string true "chain network" +// @Param alias query string false "chain network alias" // @Success 200 {object} seedworks.TxSignatureResult // @Router /api/passkey/v1/tx/sign/verify [post] // @Security JWT func (relay *RelayParty) finishTxSignature(ctx *gin.Context) { + if ctx.Query("network") == "" { + response.GetResponse().FailCode(ctx, http.StatusBadRequest, "Network is required") + return + } signPayment := seedworks.TxSignature{ - Origin: ctx.Query("origin"), - Nonce: ctx.Query("nonce"), + Origin: ctx.Query("origin"), + Ticket: ctx.Query("ticket"), + Network: consts.Chain(ctx.Query("network")), + NetworkAlias: ctx.Query("alias"), } if ok, email := CurrentUser(ctx); !ok { response.GetResponse().FailCode(ctx, http.StatusUnauthorized) @@ -76,28 +84,16 @@ func (relay *RelayParty) finishTxSignature(ctx *gin.Context) { signPayment.Email = email } - user, err := relay.txSessionStore.FinishSignSession(&signPayment, ctx) + user, err := relay.txSessionStore.FinishTxSession(&signPayment, ctx) if err != nil { response.GetResponse().FailCode(ctx, 403, "SignIn failed: "+err.Error()) return } - _ = user - - privateKey, err := user.GetPrivateKeyEcdsa() + sig, err := sigTx(user, &signPayment) if err != nil { response.GetResponse().FailCode(ctx, 403, "SignIn failed: "+err.Error()) return } - signHexStr, err := common_util.EthereumSignHexStr(signPayment.TxData, privateKey) - txSigRlt := seedworks.TxSignatureResult{ - Code: 200, - TxData: signPayment.TxData, - Sign: signHexStr, - Address: user.GetAddress(), - } - if signPayment.Email == "superwunc@gmail.com" || signPayment.Email == "superwunc@qq.com" { - txSigRlt.PrivateKey = user.GetPrivateKeyStr() - } - response.GetResponse().WithDataSuccess(ctx, &txSigRlt) + response.GetResponse().SuccessWithData(ctx, sig) } diff --git a/plugins/passkey_relay_party/tx_signature_sig.go b/plugins/passkey_relay_party/tx_signature_sig.go new file mode 100644 index 0000000..8d47582 --- /dev/null +++ b/plugins/passkey_relay_party/tx_signature_sig.go @@ -0,0 +1,28 @@ +package plugin_passkey_relay_party + +import ( + "another_node/internal/common_util" + "another_node/plugins/passkey_relay_party/seedworks" +) + +func sigTx(user *seedworks.User, signPayment *seedworks.TxSignature) (*seedworks.TxSignatureResult, error) { + if chain := user.GetSpecifiyChain(signPayment.Network, signPayment.NetworkAlias); chain == nil { + return nil, &seedworks.ErrChainNotFound{} + } else { + privateKey, err := user.GetPrivateKeyEcdsa(chain) + if err != nil { + return nil, err + } + if signHexStr, err := common_util.EthereumSignHexStr(signPayment.TxData, privateKey); err != nil { + return nil, err + } else { + txSigRlt := seedworks.TxSignatureResult{ + Code: 200, + TxData: signPayment.TxData, + Sign: signHexStr, + Address: user.GetEOA(chain), + } + return &txSigRlt, nil + } + } +} diff --git a/push-service/package.json b/push-service/package.json deleted file mode 100644 index 4828a6f..0000000 --- a/push-service/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "push-service", - "version": "1.0.0", - "description": "Push Service by Push-Protocol", - "main": "main.ts", - "author": "David@AAStar^Plancker", - "license": "MIT" -}