@supabase/gotrue-js 2.69.1 → 2.70.0-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/main/GoTrueClient.d.ts +19 -1
- package/dist/main/GoTrueClient.d.ts.map +1 -1
- package/dist/main/GoTrueClient.js +151 -0
- package/dist/main/GoTrueClient.js.map +1 -1
- package/dist/main/lib/base64url.d.ts +1 -0
- package/dist/main/lib/base64url.d.ts.map +1 -1
- package/dist/main/lib/base64url.js +13 -1
- package/dist/main/lib/base64url.js.map +1 -1
- package/dist/main/lib/types.d.ts +33 -0
- package/dist/main/lib/types.d.ts.map +1 -1
- package/dist/main/lib/version.d.ts +1 -1
- package/dist/main/lib/version.d.ts.map +1 -1
- package/dist/main/lib/version.js +1 -1
- package/dist/main/lib/version.js.map +1 -1
- package/dist/module/GoTrueClient.d.ts +19 -1
- package/dist/module/GoTrueClient.d.ts.map +1 -1
- package/dist/module/GoTrueClient.js +152 -1
- package/dist/module/GoTrueClient.js.map +1 -1
- package/dist/module/lib/base64url.d.ts +1 -0
- package/dist/module/lib/base64url.d.ts.map +1 -1
- package/dist/module/lib/base64url.js +11 -0
- package/dist/module/lib/base64url.js.map +1 -1
- package/dist/module/lib/types.d.ts +33 -0
- package/dist/module/lib/types.d.ts.map +1 -1
- package/dist/module/lib/version.d.ts +1 -1
- package/dist/module/lib/version.d.ts.map +1 -1
- package/dist/module/lib/version.js +1 -1
- package/dist/module/lib/version.js.map +1 -1
- package/package.json +2 -1
- package/src/GoTrueClient.ts +212 -1
- package/src/lib/base64url.ts +16 -0
- package/src/lib/types.ts +50 -0
- package/src/lib/version.ts +1 -1
package/src/GoTrueClient.ts
CHANGED
|
@@ -106,8 +106,11 @@ import type {
|
|
|
106
106
|
JWK,
|
|
107
107
|
JwtPayload,
|
|
108
108
|
JwtHeader,
|
|
109
|
+
SolanaWeb3Credentials,
|
|
110
|
+
SolanaWallet,
|
|
111
|
+
Web3Credentials,
|
|
109
112
|
} from './lib/types'
|
|
110
|
-
import { stringToUint8Array } from './lib/base64url'
|
|
113
|
+
import { stringToUint8Array, bytesToBase64URL } from './lib/base64url'
|
|
111
114
|
|
|
112
115
|
polyfillGlobalThis() // Make "globalThis" available
|
|
113
116
|
|
|
@@ -601,6 +604,214 @@ export default class GoTrueClient {
|
|
|
601
604
|
})
|
|
602
605
|
}
|
|
603
606
|
|
|
607
|
+
/**
|
|
608
|
+
* Signs in a user by verifying a message signed by the user's private key.
|
|
609
|
+
* Only Solana supported at this time, using the Sign in with Solana standard.
|
|
610
|
+
*/
|
|
611
|
+
async signInWithWeb3(credentials: Web3Credentials): Promise<
|
|
612
|
+
| {
|
|
613
|
+
data: { session: Session; user: User }
|
|
614
|
+
error: null
|
|
615
|
+
}
|
|
616
|
+
| { data: { session: null; user: null }; error: AuthError }
|
|
617
|
+
> {
|
|
618
|
+
const { chain } = credentials
|
|
619
|
+
|
|
620
|
+
if (chain === 'solana') {
|
|
621
|
+
return await this.signInWithSolana(credentials)
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
throw new Error(`@supabase/auth-js: Unsupported chain "${chain}"`)
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
private async signInWithSolana(credentials: SolanaWeb3Credentials) {
|
|
628
|
+
let message: string
|
|
629
|
+
let signature: Uint8Array
|
|
630
|
+
|
|
631
|
+
if ('message' in credentials) {
|
|
632
|
+
message = credentials.message
|
|
633
|
+
signature = credentials.signature
|
|
634
|
+
} else {
|
|
635
|
+
const { chain, wallet, statement, options } = credentials
|
|
636
|
+
|
|
637
|
+
let resolvedWallet: SolanaWallet
|
|
638
|
+
|
|
639
|
+
if (!isBrowser()) {
|
|
640
|
+
if (typeof wallet !== 'object' || !options?.url) {
|
|
641
|
+
throw new Error(
|
|
642
|
+
'@supabase/auth-js: Both wallet and url must be specified in non-browser environments.'
|
|
643
|
+
)
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
resolvedWallet = wallet
|
|
647
|
+
} else if (typeof wallet === 'object') {
|
|
648
|
+
resolvedWallet = wallet
|
|
649
|
+
} else {
|
|
650
|
+
const windowAny = window as any
|
|
651
|
+
|
|
652
|
+
if (
|
|
653
|
+
'solana' in windowAny &&
|
|
654
|
+
typeof windowAny.solana === 'object' &&
|
|
655
|
+
(('signIn' in windowAny.solana && typeof windowAny.solana.signIn === 'function') ||
|
|
656
|
+
('signMessage' in windowAny.solana &&
|
|
657
|
+
typeof windowAny.solana.signMessage === 'function'))
|
|
658
|
+
) {
|
|
659
|
+
resolvedWallet = windowAny.solana
|
|
660
|
+
} else {
|
|
661
|
+
throw new Error(
|
|
662
|
+
`@supabase/auth-js: No compatible Solana wallet interface on the window object (window.solana) detected. Make sure the user already has a wallet installed and connected for this app. Prefer passing the wallet interface object directly to signInWithWeb3({ chain: 'solana', wallet: resolvedUserWallet }) instead.`
|
|
663
|
+
)
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
const url = new URL(options?.url ?? window.location.href)
|
|
668
|
+
|
|
669
|
+
if ('signIn' in resolvedWallet && resolvedWallet.signIn) {
|
|
670
|
+
const output = await resolvedWallet.signIn({
|
|
671
|
+
issuedAt: new Date().toISOString(),
|
|
672
|
+
|
|
673
|
+
...options?.signInWithSolana,
|
|
674
|
+
|
|
675
|
+
// non-overridable properties
|
|
676
|
+
version: '1',
|
|
677
|
+
domain: url.host,
|
|
678
|
+
uri: url.href,
|
|
679
|
+
|
|
680
|
+
...(statement ? { statement } : null),
|
|
681
|
+
})
|
|
682
|
+
|
|
683
|
+
let outputToProcess: any
|
|
684
|
+
|
|
685
|
+
if (Array.isArray(output) && output[0] && typeof output[0] === 'object') {
|
|
686
|
+
outputToProcess = output[0]
|
|
687
|
+
} else if (
|
|
688
|
+
output &&
|
|
689
|
+
typeof output === 'object' &&
|
|
690
|
+
'signedMessage' in output &&
|
|
691
|
+
'signature' in output
|
|
692
|
+
) {
|
|
693
|
+
outputToProcess = output
|
|
694
|
+
} else {
|
|
695
|
+
throw new Error('@supabase/auth-js: Wallet method signIn() returned unrecognized value')
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
if (
|
|
699
|
+
'signedMessage' in outputToProcess &&
|
|
700
|
+
'signature' in outputToProcess &&
|
|
701
|
+
(typeof outputToProcess.signedMessage === 'string' ||
|
|
702
|
+
outputToProcess.signedMessage instanceof Uint8Array) &&
|
|
703
|
+
outputToProcess.signature instanceof Uint8Array
|
|
704
|
+
) {
|
|
705
|
+
message =
|
|
706
|
+
typeof outputToProcess.signedMessage === 'string'
|
|
707
|
+
? outputToProcess.signedMessage
|
|
708
|
+
: new TextDecoder().decode(outputToProcess.signedMessage)
|
|
709
|
+
signature = outputToProcess.signature
|
|
710
|
+
} else {
|
|
711
|
+
throw new Error(
|
|
712
|
+
'@supabase/auth-js: Wallet method signIn() API returned object without signedMessage and signature fields'
|
|
713
|
+
)
|
|
714
|
+
}
|
|
715
|
+
} else {
|
|
716
|
+
if (
|
|
717
|
+
!('signMessage' in resolvedWallet) ||
|
|
718
|
+
typeof resolvedWallet.signMessage !== 'function' ||
|
|
719
|
+
!('publicKey' in resolvedWallet) ||
|
|
720
|
+
typeof resolvedWallet !== 'object' ||
|
|
721
|
+
!resolvedWallet.publicKey ||
|
|
722
|
+
!('toBase58' in resolvedWallet.publicKey) ||
|
|
723
|
+
typeof resolvedWallet.publicKey.toBase58 !== 'function'
|
|
724
|
+
) {
|
|
725
|
+
throw new Error(
|
|
726
|
+
'@supabase/auth-js: Wallet does not have a compatible signMessage() and publicKey.toBase58() API'
|
|
727
|
+
)
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
message = [
|
|
731
|
+
`${url.host} wants you to sign in with your Solana account:`,
|
|
732
|
+
resolvedWallet.publicKey.toBase58(),
|
|
733
|
+
...(statement ? ['', statement, ''] : ['']),
|
|
734
|
+
'Version: 1',
|
|
735
|
+
`URI: ${url.href}`,
|
|
736
|
+
`Issued At: ${options?.signInWithSolana?.issuedAt ?? new Date().toISOString()}`,
|
|
737
|
+
...(options?.signInWithSolana?.notBefore
|
|
738
|
+
? [`Not Before: ${options.signInWithSolana.notBefore}`]
|
|
739
|
+
: []),
|
|
740
|
+
...(options?.signInWithSolana?.expirationTime
|
|
741
|
+
? [`Expiration Time: ${options.signInWithSolana.expirationTime}`]
|
|
742
|
+
: []),
|
|
743
|
+
...(options?.signInWithSolana?.chainId
|
|
744
|
+
? [`Chain ID: ${options.signInWithSolana.chainId}`]
|
|
745
|
+
: []),
|
|
746
|
+
...(options?.signInWithSolana?.nonce ? [`Nonce: ${options.signInWithSolana.nonce}`] : []),
|
|
747
|
+
...(options?.signInWithSolana?.requestId
|
|
748
|
+
? [`Request ID: ${options.signInWithSolana.requestId}`]
|
|
749
|
+
: []),
|
|
750
|
+
...(options?.signInWithSolana?.resources?.length
|
|
751
|
+
? [
|
|
752
|
+
'Resources',
|
|
753
|
+
...options.signInWithSolana.resources.map((resource) => `- ${resource}`),
|
|
754
|
+
]
|
|
755
|
+
: []),
|
|
756
|
+
].join('\n')
|
|
757
|
+
|
|
758
|
+
const maybeSignature = await resolvedWallet.signMessage(
|
|
759
|
+
new TextEncoder().encode(message),
|
|
760
|
+
'utf8'
|
|
761
|
+
)
|
|
762
|
+
|
|
763
|
+
if (!maybeSignature || !(maybeSignature instanceof Uint8Array)) {
|
|
764
|
+
throw new Error(
|
|
765
|
+
'@supabase/auth-js: Wallet signMessage() API returned an recognized value'
|
|
766
|
+
)
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
signature = maybeSignature
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
try {
|
|
774
|
+
const { data, error } = await _request(
|
|
775
|
+
this.fetch,
|
|
776
|
+
'POST',
|
|
777
|
+
`${this.url}/token?grant_type=web3`,
|
|
778
|
+
{
|
|
779
|
+
headers: this.headers,
|
|
780
|
+
body: {
|
|
781
|
+
chain: 'solana',
|
|
782
|
+
message,
|
|
783
|
+
signature: bytesToBase64URL(signature),
|
|
784
|
+
|
|
785
|
+
...(credentials.options?.captchaToken
|
|
786
|
+
? { gotrue_meta_security: { captcha_token: credentials.options?.captchaToken } }
|
|
787
|
+
: null),
|
|
788
|
+
},
|
|
789
|
+
xform: _sessionResponse,
|
|
790
|
+
}
|
|
791
|
+
)
|
|
792
|
+
if (error) {
|
|
793
|
+
throw error
|
|
794
|
+
}
|
|
795
|
+
if (!data || !data.session || !data.user) {
|
|
796
|
+
return {
|
|
797
|
+
data: { user: null, session: null },
|
|
798
|
+
error: new AuthInvalidTokenResponseError(),
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
if (data.session) {
|
|
802
|
+
await this._saveSession(data.session)
|
|
803
|
+
await this._notifyAllSubscribers('SIGNED_IN', data.session)
|
|
804
|
+
}
|
|
805
|
+
return { data: { ...data }, error }
|
|
806
|
+
} catch (error) {
|
|
807
|
+
if (isAuthError(error)) {
|
|
808
|
+
return { data: { user: null, session: null }, error }
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
throw error
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
|
|
604
815
|
private async _exchangeCodeForSession(authCode: string): Promise<
|
|
605
816
|
| {
|
|
606
817
|
data: { session: Session; user: User; redirectType: string | null }
|
package/src/lib/base64url.ts
CHANGED
|
@@ -288,3 +288,19 @@ export function stringToUint8Array(str: string): Uint8Array {
|
|
|
288
288
|
stringToUTF8(str, (byte: number) => result.push(byte))
|
|
289
289
|
return new Uint8Array(result)
|
|
290
290
|
}
|
|
291
|
+
|
|
292
|
+
export function bytesToBase64URL(bytes: Uint8Array) {
|
|
293
|
+
const result: string[] = []
|
|
294
|
+
const state = { queue: 0, queuedBits: 0 }
|
|
295
|
+
|
|
296
|
+
const onChar = (char: string) => {
|
|
297
|
+
result.push(char)
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
bytes.forEach((byte) => byteToBase64URL(byte, state, onChar))
|
|
301
|
+
|
|
302
|
+
// always call with `null` after processing all bytes
|
|
303
|
+
byteToBase64URL(null, state, onChar)
|
|
304
|
+
|
|
305
|
+
return result.join('')
|
|
306
|
+
}
|
package/src/lib/types.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { AuthError } from './errors'
|
|
2
2
|
import { Fetch } from './fetch'
|
|
3
|
+
import type { SolanaSignInInput, SolanaSignInOutput } from '@solana/wallet-standard-features'
|
|
3
4
|
|
|
4
5
|
/** One of the providers supported by GoTrue. */
|
|
5
6
|
export type Provider =
|
|
@@ -521,6 +522,7 @@ export type SignUpWithPasswordCredentials =
|
|
|
521
522
|
channel?: 'sms' | 'whatsapp'
|
|
522
523
|
}
|
|
523
524
|
}
|
|
525
|
+
|
|
524
526
|
export type SignInWithPasswordCredentials =
|
|
525
527
|
| {
|
|
526
528
|
/** The user's email address. */
|
|
@@ -612,6 +614,54 @@ export type SignInWithIdTokenCredentials = {
|
|
|
612
614
|
}
|
|
613
615
|
}
|
|
614
616
|
|
|
617
|
+
export type SolanaWallet = {
|
|
618
|
+
signIn?: (...inputs: SolanaSignInInput[]) => Promise<SolanaSignInOutput | SolanaSignInOutput[]>
|
|
619
|
+
publicKey?: {
|
|
620
|
+
toBase58: () => string
|
|
621
|
+
} | null
|
|
622
|
+
|
|
623
|
+
signMessage?: (message: Uint8Array, encoding?: 'utf8' | string) => Promise<Uint8Array> | undefined
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
export type SolanaWeb3Credentials =
|
|
627
|
+
| {
|
|
628
|
+
chain: 'solana'
|
|
629
|
+
|
|
630
|
+
/** Wallet interface to use. If not specified will default to `window.solana`. */
|
|
631
|
+
wallet?: SolanaWallet
|
|
632
|
+
|
|
633
|
+
/** Optional statement to include in the Sign in with Solana message. Must not include new line characters. Most wallets like Phantom **require specifying a statement!** */
|
|
634
|
+
statement?: string
|
|
635
|
+
|
|
636
|
+
options?: {
|
|
637
|
+
/** URL to use with the wallet interface. Some wallets do not allow signing a message for URLs different from the current page. */
|
|
638
|
+
url?: string
|
|
639
|
+
|
|
640
|
+
/** Verification token received when the user completes the captcha on the site. */
|
|
641
|
+
captchaToken?: string
|
|
642
|
+
|
|
643
|
+
signInWithSolana?: Partial<
|
|
644
|
+
Omit<SolanaSignInInput, 'version' | 'chain' | 'domain' | 'uri' | 'statement'>
|
|
645
|
+
>
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
| {
|
|
649
|
+
chain: 'solana'
|
|
650
|
+
|
|
651
|
+
/** Sign in with Solana compatible message. Must include `Issued At`, `URI` and `Version`. */
|
|
652
|
+
message: string
|
|
653
|
+
|
|
654
|
+
/** Ed25519 signature of the message. */
|
|
655
|
+
signature: Uint8Array
|
|
656
|
+
|
|
657
|
+
options?: {
|
|
658
|
+
/** Verification token received when the user completes the captcha on the site. */
|
|
659
|
+
captchaToken?: string
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
export type Web3Credentials = SolanaWeb3Credentials
|
|
664
|
+
|
|
615
665
|
export type VerifyOtpParams = VerifyMobileOtpParams | VerifyEmailOtpParams | VerifyTokenHashParams
|
|
616
666
|
export interface VerifyMobileOtpParams {
|
|
617
667
|
/** The user's phone number. */
|
package/src/lib/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '2.
|
|
1
|
+
export const version = '2.70.0-rc.2'
|