Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Firebase generator #643

Merged
merged 24 commits into from
Jun 15, 2020
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
b3b4924
Added firebase generator
noire-munich Jun 2, 2020
1436a37
Modified how the imports are handled because some packages will not i…
noire-munich Jun 2, 2020
3bc9d6b
Fixed the import to make it work.
noire-munich Jun 2, 2020
730cead
Added auth.firebase.js.template, to the reviewer's discretion.
noire-munich Jun 2, 2020
d0181f3
Merge branch 'master' into firebase_generator
noire-munich Jun 3, 2020
71bed91
Update packages/cli/src/commands/generate/auth/auth.js
noire-munich Jun 3, 2020
c21f04b
Simplified getCurrentUser implementation
noire-munich Jun 3, 2020
e21ebe7
Merge branch 'firebase_generator' of github.com:noire-munich/redwood …
noire-munich Jun 3, 2020
6c1cb93
Merge branch 'master' into firebase_generator
noire-munich Jun 6, 2020
dbb54e6
Firebase: fixed the CLI missing parameter ( now they are listed to av…
noire-munich Jun 6, 2020
45f8ec5
Take provider template if provided, otherwise standard auth.js.template.
noire-munich Jun 6, 2020
3fe07d0
Fixed lint.
noire-munich Jun 6, 2020
6c31678
Merge branch 'master' into firebase_generator
noire-munich Jun 8, 2020
ded79b9
Templates are fetched automatically - no error handling.
noire-munich Jun 8, 2020
b35a9d3
Supported providers as options - from file list.
noire-munich Jun 8, 2020
4f2bd0f
Lint fix.
noire-munich Jun 9, 2020
3fef880
Merge branch 'master' into firebase_generator
noire-munich Jun 9, 2020
82b891f
Review fixes
noire-munich Jun 9, 2020
f5387ab
Merge branch 'master' into firebase_generator
noire-munich Jun 9, 2020
87bbfd9
Merge branch 'master' into firebase_generator
noire-munich Jun 11, 2020
56d0150
Merge branch 'master' into firebase_generator
cannikin Jun 12, 2020
107bfd4
Merge branch 'master' into firebase_generator
cannikin Jun 12, 2020
a200f87
Reformat template part for appropriate linting, changed variable name…
noire-munich Jun 14, 2020
39f2e0d
Merge branch 'master' into firebase_generator
noire-munich Jun 14, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 20 additions & 11 deletions packages/cli/src/commands/generate/auth/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,31 @@ import c from 'src/lib/colors'

const API_GRAPHQL_PATH = path.join(getPaths().api.functions, 'graphql.js')
const API_SRC_PATH = path.join(getPaths().api.src)
const TEMPLATE_PATH = path.resolve(__dirname, 'templates', 'auth.js.template')
const TEMPLATE = fs.readFileSync(TEMPLATE_PATH).toString()
const TEMPLATES = fs
.readdirSync(path.resolve(__dirname, 'templates'))
.reduce((templates, file) => {
if (file === 'auth.js.template') {
return { ...templates, base: path.resolve(__dirname, 'templates', file) }
} else {
const provider = file.replace('.auth.js.template', '')
return {
...templates,
[provider]: path.resolve(__dirname, 'templates', file),
}
}
}, {})
const OUTPUT_PATH = path.join(getPaths().api.lib, 'auth.js')
const WEB_SRC_INDEX_PATH = path.join(getPaths().web.src, 'index.js')
const SUPPORTED_PROVIDERS = fs
.readdirSync(path.resolve(__dirname, 'providers'))
.map((file) => path.basename(file, '.js'))
.filter((file) => file !== 'README.md')

// returns the content of index.js with import statements added
const addWebImports = (content, imports) => {
const importStatements = imports.map((imp) => {
return `import ${imp.import} from '${imp.from}'`
})

return (
`import { AuthProvider } from '@redwoodjs/auth'\n` +
importStatements.join('\n') +
imports.join('\n') +
'\n' +
content
)
Expand Down Expand Up @@ -60,9 +68,10 @@ const addWebRender = (content, authProvider) => {
}

// the files to create to support auth
export const files = () => {
export const files = (provider) => {
const template = TEMPLATES[provider] ?? TEMPLATES.base
return {
[OUTPUT_PATH]: TEMPLATE,
[OUTPUT_PATH]: fs.readFileSync(template).toString(),
}
}

Expand Down Expand Up @@ -114,7 +123,7 @@ export const description = 'Generate an auth configuration'
export const builder = (yargs) => {
yargs
.positional('provider', {
choices: ['netlify', 'auth0', 'magic-link'],
choices: SUPPORTED_PROVIDERS,
description: 'Auth provider to configure',
type: 'string',
})
Expand Down Expand Up @@ -162,7 +171,7 @@ export const handler = async ({ provider, force }) => {
title: 'Generating auth lib...',
task: (_ctx, task) => {
if (apiSrcDoesExist()) {
return writeFilesTask(files(), { overwriteExisting: force })
return writeFilesTask(files(provider), { overwriteExisting: force })
} else {
task.skip('api/src not found, skipping')
}
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/commands/generate/auth/providers/auth0.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// the lines that need to be added to index.js
export const config = {
imports: [{ import: '{ Auth0Client }', from: '@auth0/auth0-spa-js' }],
imports: [`import { Auth0Client } from '@auth0/auth0-spa-js'`],
init: `const auth0 = new Auth0Client({
domain: process.env.AUTH0_DOMAIN,
client_id: process.env.AUTH0_CLIENT_ID,
Expand Down
30 changes: 30 additions & 0 deletions packages/cli/src/commands/generate/auth/providers/firebase.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
export const config = {
imports: [
`import * as firebase from 'firebase/app'`,
`import 'firebase/auth'`,
],
init: `const config = {
apiKey: process.env.FIREBASE_API_KEY,
authDomain: process.env.FIREBASE_AUTH_DOMAIN,
databaseURL: process.env.FIREBASE_DATABASE_URL,
projectId: process.env.FIREBASE_PROJECT_ID,
storageBucket: process.env.FIREBASE_STORAGE_BUCKET,
messagingSenderId: process.env.FIREBASE_MESSAGING_SENDER_ID,
appId: process.env.FIREBASE_APP_ID,
}

const firebaseClient = ((config) => {
firebase.initializeApp(config)
return firebase
})(config)
`,
authProvider: { client: 'firebaseClient', type: 'firebase' },
}

export const packages = ['firebase']

export const notes = [
'You will need to create several environment variables with your Firebase config options.',
'Check out web/src/index.js for the variables you need to add.',
'See: https://firebase.google.com/docs/web/setup#config-object',
]
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export const config = {
imports: [{ import: '{ Magic }', from: 'magic-sdk' }],
imports: [`import { Magic } from 'magic-sdk'`],
init: 'const m = new Magic(process.env.MAGICLINK_PUBLIC)',
authProvider: {
client: 'm',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// the lines that need to be added to index.js
export const config = {
imports: [{ import: 'netlifyIdentity', from: 'netlify-identity-widget' }],
imports: [`import netlifyIdentity from 'netlify-identity-widget'`],
init: 'netlifyIdentity.init()',
authProvider: {
client: 'netlifyIdentity',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Define what you want `currentUser` to return throughout your app. For example,
// to return a real user from your database, you could do something like:
//
// export const getCurrentUser = async ({ email }) => {
// return await db.user.findOne({ where: { email } })
// }

import { AuthenticationError } from '@redwoodjs/api'
import admin from 'firebase-admin'

import { db } from './db'

const config = {
apiKey: process.env.FIREBASE_API_KEY,
authDomain: process.env.FIREBASE_AUTH_DOMAIN,
databaseURL: process.env.FIREBASE_DATABASE_URL,
projectId: process.env.FIREBASE_PROJECT_ID,
storageBucket: process.env.FIREBASE_STORAGE_BUCKET,
messagingSenderId: process.env.FIREBASE_MESSAGING_SENDER_ID,
appId: process.env.FIREBASE_APP_ID,
}

const adminApp = admin.initializeApp(config)

export const getCurrentUser = async (token) => {
const { email, uid } = await adminApp.auth().verifyToken(token)
return { email, uid }
}

// Use this function in your services to check that a user is logged in, and
// optionally raise an error if they're not.

export const requireAuth = () => {
if (!context.currentUser) {
throw new AuthenticationError("You don't have permission to do that.")
}
}