Created
November 9, 2021 05:43
-
-
Save gautamsi/d89cf29a5ea2d4c3eb0e19eb248a8d9c to your computer and use it in GitHub Desktop.
Firebase Auth with Keystone
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { KeystoneContext } from '@keystone-next/keystone/types'; | |
import admin from 'firebase-admin'; | |
const firebase = admin.initializeApp(); | |
export const authMutations = ` | |
authenticateWithFirebase(token: String!): User | |
signupWithFirebase( | |
token: String! | |
name: String! | |
email: String | |
password: String! | |
): User | |
verifyEmailAddress(token: String!): User | |
verifyMobile(phone: String!): UserAlreadyExist | |
`; | |
export const authTypes = ` | |
type UserAlreadyExist { | |
success: Boolean! | |
} | |
`; | |
export async function authenticateWithFirebase( | |
root: any, | |
{ token }: { token: string }, | |
context: KeystoneContext | |
) { | |
const sudo = context.sudo(); | |
const firebaseToken = await firebase.auth()?.verifyIdToken(token); | |
const { uid, phone_number: phone } = firebaseToken; | |
const firebaseUser = await sudo.lists.User.findMany({ | |
where: { | |
firebaseId: { equals: uid }, | |
phone: { equals: phone }, | |
}, | |
}); | |
if (!firebaseUser.length) { | |
throw new Error('USER_NOT_FOUND'); | |
} | |
const item = firebaseUser[0]; | |
const newToken = await context?.startSession?.({ | |
itemId: item?.id, | |
listKey: 'User', | |
}); | |
if (newToken) { | |
return await sudo.db.lists.User.findOne({ where: { id: item.id } }); | |
} | |
return null; | |
} | |
export async function signupWithFirebase( | |
root: any, | |
{ | |
token, | |
name, | |
email, | |
password, | |
}: { token: string; name: string; email: string; password: string }, | |
context: KeystoneContext | |
) { | |
try { | |
const firebaseToken = await firebase.auth().verifyIdToken(token); | |
const sudo = context.sudo(); | |
const { uid, phone_number: phone } = firebaseToken; | |
const firebaseUser = await sudo.lists.User.findMany({ | |
where: { | |
firebaseId: { equals: uid }, | |
phone: { equals: phone }, | |
}, | |
}); | |
if (firebaseUser.length) { | |
throw new Error('USER_ALREADY_EXIST'); | |
} | |
const newUser = await sudo.lists.User.createOne({ | |
data: { | |
name, | |
phone: phone, | |
firebaseId: uid, | |
email, | |
password, | |
}, | |
}); | |
const item = newUser; | |
const currentUser = await context?.startSession?.({ | |
itemId: item?.id, | |
listKey: 'User', | |
}); | |
if (currentUser) { | |
return await sudo.db.lists.User.findOne({ where: { id: item.id } }); | |
} | |
return null; | |
} catch (error) { | |
throw new Error('Error creating User.'); | |
} | |
} | |
export async function verifyEmailAddress( | |
root: any, | |
{ token }: { token: string }, | |
context: KeystoneContext | |
) { | |
const user = context?.session?.data; | |
if (!user?.id) { | |
return null; | |
} | |
try { | |
const firebaseToken = await firebase.auth().verifyIdToken(token); | |
const { email_verified } = firebaseToken; | |
const sudo = context.sudo(); | |
const registeredUser = await sudo.lists.User.updateOne({ | |
where: { id: user.id }, | |
data: { | |
isVerifiedEmail: email_verified, | |
}, | |
query: 'id', | |
}); | |
return { id: registeredUser.id }; | |
} catch (error) { | |
console.log('error', error); | |
return null; | |
} | |
} | |
export async function verifyMobile( | |
root: any, | |
{ phone }: { phone: string }, | |
context: KeystoneContext | |
) { | |
const sudo = context.sudo(); | |
const isValid = await sudo.lists.User.findOne({ | |
where: { phone }, | |
query: 'id', | |
}); | |
return { success: isValid?.id ? true : false }; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { graphQLSchemaExtension } from '@keystone-next/keystone'; | |
import { | |
authenticateWithFirebase, | |
authMutations, | |
authTypes, | |
signupWithFirebase, | |
verifyEmailAddress, | |
verifyMobile, | |
} from './auth'; | |
const typeDefs = String.raw` | |
${authTypes} | |
type Mutation { | |
${authMutations} | |
} | |
`; | |
export const extendGraphqlSchema = graphQLSchemaExtension({ | |
typeDefs, | |
resolvers: { | |
Mutation: { | |
authenticateWithFirebase, | |
signupWithFirebase, | |
verifyEmailAddress, | |
verifyMobile, | |
}, | |
}, | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi,
Thank you, Sir!
That looks very exciting!