Skip to content

Commit

Permalink
feat: add method for anonymous sign-in (#858)
Browse files Browse the repository at this point in the history
## What kind of change does this PR introduce?
* supabase/auth#68
* Adds the `signInAnonymously` method to support
supabase/auth#1460
* Passing in user metadata / the captcha token in `signInAnonymously`
looks like:
    `signInAnonymously({ options: { data, captchaToken }})` 
which follows the same format as the other sign up / sign in methods
  • Loading branch information
kangmingtay committed Mar 6, 2024
1 parent 15c7c82 commit e8a1fc9
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 11 deletions.
3 changes: 3 additions & 0 deletions example/react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
"react-scripts": "5.0.1",
"tailwindcss": "^1.8.10"
},
"devDependencies": {
"@babel/plugin-proposal-private-property-in-object": "^7.21.11"
},
"scripts": {
"build:tailwind": "tailwindcss build src/App.css -o src/tailwind.output.css",
"prestart": "npm run build:tailwind",
Expand Down
19 changes: 16 additions & 3 deletions example/react/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,11 @@ function App() {
console.log(event, session)
if (event === 'SIGNED_OUT' || event === 'SIGNED_IN') {
setSession(session)
window.location.reload()
}
})

return () => {
if (subscription) {
console.log('Subscription: ', subscription)
if (subscription.subscription) {
subscription.unsubscribe()
}
}
Expand Down Expand Up @@ -94,6 +92,10 @@ function App() {
let { error } = await auth.signOut()
if (error) console.log('Error: ', error)
}
async function handleSignInAnonymously(data) {
let { error } = await auth.signInAnonymously({ options: { data } })
if (error) alert(error.message)
}
async function forgotPassword() {
var email = prompt('Please enter your email:')
if (email === null || email === '') {
Expand Down Expand Up @@ -393,6 +395,17 @@ function App() {
</button>
</span>
</div>
<div className="mt-6">
<span className="block w-full rounded-md shadow-sm">
<button
onClick={() => handleSignInAnonymously({ color: 'blue' })}
type="button"
className="w-full flex justify-center py-2 px-4 border border-transparent text-sm font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-500 focus:outline-none focus:border-indigo-700 focus:shadow-outline-indigo active:bg-indigo-700 transition duration-150 ease-in-out"
>
Sign In Anonymously
</button>
</span>
</div>
</div>
</div>
</div>
Expand Down
37 changes: 36 additions & 1 deletion src/GoTrueClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ import type {
AuthFlowType,
LockFunc,
UserIdentity,
WeakPassword,
SignInAnonymouslyCredentials,
} from './lib/types'

polyfillGlobalThis() // Make "globalThis" available
Expand Down Expand Up @@ -361,6 +361,41 @@ export default class GoTrueClient {
}
}

async signInAnonymously(credentials?: SignInAnonymouslyCredentials): Promise<AuthResponse> {
try {
await this._removeSession()

const res = await _request(this.fetch, 'POST', `${this.url}/signup`, {
headers: this.headers,
body: {
data: credentials?.options?.data ?? {},
gotrue_meta_security: { captcha_token: credentials?.options?.captchaToken },
},
xform: _sessionResponse,
})
const { data, error } = res

if (error || !data) {
return { data: { user: null, session: null }, error: error }
}
const session: Session | null = data.session
const user: User | null = data.user

if (data.session) {
await this._saveSession(data.session)
await this._notifyAllSubscribers('SIGNED_IN', session)
}

return { data: { user, session }, error: null }
} catch (error) {
if (isAuthError(error)) {
return { data: { user: null, session: null }, error }
}

throw error
}
}

/**
* Creates a new user.
*
Expand Down
27 changes: 20 additions & 7 deletions src/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ export interface UserAttributes {
nonce?: string

/**
* A custom data object to store the user's metadata. This maps to the `auth.users.user_metadata` column.
* A custom data object to store the user's metadata. This maps to the `auth.users.raw_user_meta_data` column.
*
* The `data` should be a JSON object that includes user-specific info, such as their first and last name.
*
Expand All @@ -376,7 +376,7 @@ export interface UserAttributes {

export interface AdminUserAttributes extends Omit<UserAttributes, 'data'> {
/**
* A custom data object to store the user's metadata. This maps to the `auth.users.user_metadata` column.
* A custom data object to store the user's metadata. This maps to the `auth.users.raw_user_meta_data` column.
*
*
* The `user_metadata` should be a JSON object that includes user-specific info, such as their first and last name.
Expand Down Expand Up @@ -452,6 +452,19 @@ export interface UpdatableFactorAttributes {
friendlyName: string
}

export type SignInAnonymouslyCredentials = {
options?: {
/**
* A custom data object to store the user's metadata. This maps to the `auth.users.raw_user_meta_data` column.
*
* The `data` should be a JSON object that includes user-specific info, such as their first and last name.
*/
data?: object
/** Verification token received when the user completes the captcha on the site. */
captchaToken?: string
}
}

export type SignUpWithPasswordCredentials =
| {
/** The user's email address. */
Expand All @@ -462,7 +475,7 @@ export type SignUpWithPasswordCredentials =
/** The redirect url embedded in the email link */
emailRedirectTo?: string
/**
* A custom data object to store the user's metadata. This maps to the `auth.users.user_metadata` column.
* A custom data object to store the user's metadata. This maps to the `auth.users.raw_user_meta_data` column.
*
* The `data` should be a JSON object that includes user-specific info, such as their first and last name.
*/
Expand All @@ -478,7 +491,7 @@ export type SignUpWithPasswordCredentials =
password: string
options?: {
/**
* A custom data object to store the user's metadata. This maps to the `auth.users.user_metadata` column.
* A custom data object to store the user's metadata. This maps to the `auth.users.raw_user_meta_data` column.
*
* The `data` should be a JSON object that includes user-specific info, such as their first and last name.
*/
Expand Down Expand Up @@ -521,7 +534,7 @@ export type SignInWithPasswordlessCredentials =
/** If set to false, this method will not create a new user. Defaults to true. */
shouldCreateUser?: boolean
/**
* A custom data object to store the user's metadata. This maps to the `auth.users.user_metadata` column.
* A custom data object to store the user's metadata. This maps to the `auth.users.raw_user_meta_data` column.
*
* The `data` should be a JSON object that includes user-specific info, such as their first and last name.
*/
Expand All @@ -537,7 +550,7 @@ export type SignInWithPasswordlessCredentials =
/** If set to false, this method will not create a new user. Defaults to true. */
shouldCreateUser?: boolean
/**
* A custom data object to store the user's metadata. This maps to the `auth.users.user_metadata` column.
* A custom data object to store the user's metadata. This maps to the `auth.users.raw_user_meta_data` column.
*
* The `data` should be a JSON object that includes user-specific info, such as their first and last name.
*/
Expand Down Expand Up @@ -708,7 +721,7 @@ export type GenerateEmailChangeLinkParams = {

export interface GenerateLinkOptions {
/**
* A custom data object to store the user's metadata. This maps to the `auth.users.user_metadata` column.
* A custom data object to store the user's metadata. This maps to the `auth.users.raw_user_meta_data` column.
*
* The `data` should be a JSON object that includes user-specific info, such as their first and last name.
*/
Expand Down

0 comments on commit e8a1fc9

Please sign in to comment.