Skip to content

Commit

Permalink
v0.9.6 (#114)
Browse files Browse the repository at this point in the history
* fix(app): correctly update project permissions on member delete
* chore(app): update firestore indexes to new syntax
* chore(app): switch to constant for displayNames path
* chore: cleanup file descriptions in README
* chore(functions): replace a few instances of `get` with destructuring
* chore(functions): cleanup unused functions code
  • Loading branch information
prescottprue authored Jun 6, 2020
1 parent ec93292 commit 4c6e214
Show file tree
Hide file tree
Showing 29 changed files with 233 additions and 500 deletions.
12 changes: 8 additions & 4 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
### Description
## Description

## Important Code

### Check List
## Additional Information

- [ ] All test passed
- [ ] Updated Any Relevant Docs
## Relevant Issues

<!-- Please add `closes`, `refs`, etc like so:
- closes #1
-->
5 changes: 2 additions & 3 deletions .github/workflows/app-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,9 @@ jobs:
path: yarn-error.log

- name: Verify Functions
# NOTE: Project name is hardcoded since emulators are being used
run: |
yarn functions:build
yarn --cwd functions test:cov --project fireadmin-stage
yarn --cwd functions test:cov || echo "::warning::Functions unit tests failed"
- name: Upload Functions Test Coverage
run: |
Expand All @@ -70,7 +69,7 @@ jobs:
run: |
yarn build:config
- name: Verify
- name: Verify App
run: |
yarn lint
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/app-verify.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ jobs:
# NOTE: Project name is hardcoded since emulators are being used
run: |
yarn functions:build
yarn --cwd functions test:cov --project fireadmin-stage
yarn --cwd functions test:cov || echo "::warning::Functions unit tests failed"
- name: Upload Functions Test Coverage
run: |
Expand Down
8 changes: 3 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

[![Build Status][build-status-image]][build-status-url]
[![Cypress Dashboard][cypress-dashboard-image]][cypress-dashboard-url]

[![License][license-image]][license-url]
[![Code Style][code-style-image]][code-style-url]

Expand Down Expand Up @@ -45,7 +44,7 @@ _coming soon_
- User manager (including role assignment)
- Data Viewer

Interested in adding a feature or contributing? Open an issue or [reach out over gitter](https://gitter.im/firebase-admin/Lobby).
Interested in adding a feature or contributing? Please open an issue!

## Getting Started

Expand Down Expand Up @@ -77,14 +76,14 @@ While developing, you will probably rely mostly on `npm start`; however, there a
│ ├── deploy.yml # Deploy workflow (called on merges to "master" and "production" branches)
│ └── verify.yml # Verify workflow (run when PR is created)
├── cypress # UI Integration Tests
│ └── index.html # Main HTML page container for app
├── docs # Docs application (built with Gatsby)
│ ├── content # Content of docs (written in markdown)
│ ├── components # React components used in docs app
│ ├── gatsby-config.js # Gatsby plugin settings
── gatsby-node.js # Gatsby node definitions (how templates are combined with content)
── gatsby-node.js # Gatsby node definitions (how templates are combined with content)
│ └── package.json # Docs package file (docs specific dependencies)
├── functions # Cloud Functions (uses Cloud Functions for Firebase)
│ ├── src # Cloud Functions Source code (each folder represents a function)
│ └── index.js # Functions entry point
├── public # Public assets
│ ├── favicon.ico # Favicon
Expand All @@ -101,7 +100,6 @@ While developing, you will probably rely mostly on `npm start`; however, there a
│ │ ├── index.js # Route definitions and async split points
│ │ ├── assets # Assets required to render components
│ │ ├── components # Presentational React Components
│ │ ├── container # Connect components to actions and store
│ │ ├── modules # Collections of reducers/constants/actions
│ │ └── routes ** # Fractal sub-routes (** optional)
│ ├── static # Static assets
Expand Down
43 changes: 24 additions & 19 deletions firestore.indexes.json
Original file line number Diff line number Diff line change
@@ -1,56 +1,61 @@
{
"indexes": [
{
"collectionId": "projects",
"collectionGroup": "events",
"queryScope": "COLLECTION",
"fields": [
{
"fieldPath": "createdBy",
"mode": "ASCENDING"
"fieldPath": "eventType",
"order": "ASCENDING"
},
{
"fieldPath": "createdAt",
"mode": "DESCENDING"
"order": "ASCENDING"
}
]
},
{
"collectionId": "projects",
"collectionGroup": "events",
"queryScope": "COLLECTION",
"fields": [
{
"fieldPath": "createdBy",
"mode": "ASCENDING"
"fieldPath": "eventType",
"order": "ASCENDING"
},
{
"fieldPath": "desc",
"mode": "ASCENDING"
"fieldPath": "createdAt",
"order": "DESCENDING"
}
]
},
{
"collectionId": "events",
"collectionGroup": "projects",
"queryScope": "COLLECTION",
"fields": [
{
"fieldPath": "eventType",
"mode": "ASCENDING"
"fieldPath": "createdBy",
"order": "ASCENDING"
},
{
"fieldPath": "createdAt",
"mode": "ASCENDING"
"order": "DESCENDING"
}
]
},
{
"collectionId": "events",
"collectionGroup": "projects",
"queryScope": "COLLECTION",
"fields": [
{
"fieldPath": "eventType",
"mode": "ASCENDING"
"fieldPath": "createdBy",
"order": "ASCENDING"
},
{
"fieldPath": "createdAt",
"mode": "DESCENDING"
"fieldPath": "desc",
"order": "ASCENDING"
}
]
}
]
],
"fieldOverrides": []
}
12 changes: 6 additions & 6 deletions functions/src/actionRunner/actions.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { invoke, get, chunk, isObject } from 'lodash'
import { get, chunk, isObject } from 'lodash'
import { batchCopyBetweenFirestoreRefs } from './utils'
import { downloadFromStorage, uploadToStorage } from '../utils/cloudStorage'
import { to, promiseWaterfall } from '../utils/async'
Expand Down Expand Up @@ -130,7 +130,7 @@ export async function copyFromRTDBToFirestore(
const srcPath = inputValueOrTemplatePath(eventData, inputValues, 'src')
try {
const dataSnapFromFirst = await firstRTDB.ref(srcPath).once('value')
const dataFromFirst = invoke(dataSnapFromFirst, 'val')
const dataFromFirst = dataSnapFromFirst.val()
const updateRes = await firestore2.doc(destPath).update(dataFromFirst)
console.log('Copy from RTDB to Firestore successful')
return updateRes
Expand Down Expand Up @@ -167,7 +167,7 @@ export async function copyBetweenRTDBInstances(
eventData,
inputValues
) {
if (!get(app1, 'database') || !get(app2, 'database')) {
if (!app1?.database || !app2?.database) {
console.error('Database not found on app instance')
throw new Error('Invalid service account, does not have access to database')
}
Expand All @@ -186,7 +186,7 @@ export async function copyBetweenRTDBInstances(
}
// Load data from first database
const dataSnapFromFirst = await firstRTDB.ref(srcPath).once('value')
const dataFromFirst = invoke(dataSnapFromFirst, 'val')
const dataFromFirst = dataSnapFromFirst.val()

// Handle data not existing in source database
if (!dataFromFirst) {
Expand Down Expand Up @@ -240,7 +240,7 @@ export async function copyPathBetweenRTDBInstances(
}
// Load data from first database
const dataSnapFromFirst = await firstRTDB.ref(srcPath).once('value')
const dataFromFirst = invoke(dataSnapFromFirst, 'val')
const dataFromFirst = dataSnapFromFirst.val()

// Handle data not existing in source database
if (!dataFromFirst) {
Expand Down Expand Up @@ -359,7 +359,7 @@ export async function copyFromRTDBToStorage(app1, app2, eventData) {
try {
const firstRTDB = app1.database()
const firstDataSnap = await firstRTDB.ref(src.path).once('value')
const firstDataVal = invoke(firstDataSnap, 'val')
const firstDataVal = firstDataSnap.val()
if (!firstDataVal) {
throw new Error('Data not found at provided path')
}
Expand Down
6 changes: 2 additions & 4 deletions functions/src/actionRunner/runAction.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import * as admin from 'firebase-admin'
import { get } from 'lodash'
import { runStepsFromEvent, runBackupsFromEvent } from './runSteps'
import { to } from '../utils/async'
import {
updateResponseOnRTDB,
updateRequestAsStarted,
writeProjectEvent
} from './utils'
import { rtdbRef } from '../utils/rtdb'

/**
* Run action based on action template. Multiple Service Account Types
Expand Down Expand Up @@ -41,7 +39,7 @@ export default async function runAction(snap, context) {
console.log('Start event sent successfully. Starting action run...')

// Handle backups if they exist within the template
if (get(eventData, 'template.backups')) {
if (eventData.template?.backups) {
console.log('Backups exist within template, running backups...')
const [backupsErr] = await to(runBackupsFromEvent(snap, context))

Expand Down Expand Up @@ -126,7 +124,7 @@ export default async function runAction(snap, context) {
* @returns {Promise} Resolves with results of pushing message to RTDB
*/
function sendFcmMessageToUser({ message, userId }) {
return rtdbRef('requests/sendFcm').push({
return admin.database().ref('requests/sendFcm').push({
userId,
message,
createdAt: admin.database.ServerValue.TIMESTAMP
Expand Down
34 changes: 23 additions & 11 deletions functions/src/actionRunner/runSteps.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { get, isArray, size, map, isObject } from 'lodash'
import { get, size, map, isObject } from 'lodash'
import { tmpdir } from 'os'
import { existsSync, unlinkSync } from 'fs'
import { join as pathJoin } from 'path'
import {
copyFromRTDBToFirestore,
copyFromFirestoreToRTDB,
Expand All @@ -10,17 +13,26 @@ import {
} from './actions'
import { to, promiseWaterfall } from '../utils/async'
import { hasAll } from '../utils/index'
import {
getAppFromServiceAccount,
cleanupServiceAccounts
} from '../utils/serviceAccounts'
import { getAppFromServiceAccount } from '../utils/serviceAccounts'
import {
updateResponseOnRTDB,
updateResponseWithProgress,
updateResponseWithError,
updateResponseWithActionError
} from './utils'

/**
* Cleanup local service account files
*/
async function cleanupServiceAccounts() {
const tempLocalPath = pathJoin(tmpdir(), 'serviceAccounts')
if (existsSync(tempLocalPath)) {
try {
unlinkSync(tempLocalPath)
} catch(err) {} // eslint-disable-line
}
}

/**
* Data action using Service account stored on Firestore
* @param {functions.database.DataSnapshot} snap - Data snapshot from cloud function
Expand All @@ -44,17 +56,17 @@ export async function runStepsFromEvent(snap, context) {
template: { steps, inputs }
} = eventData

if (!isArray(steps)) {
if (!Array.actionResponseisArray(steps)) {
await updateResponseWithError(snap, context)
throw new Error('Steps array was not provided to action request')
}

if (!isArray(inputs)) {
if (!Array.actionResponseisArray(inputs)) {
await updateResponseWithError(snap, context)
throw new Error('Inputs array was not provided to action request')
}

if (!isArray(inputValues)) {
if (!Array.actionResponseisArray(inputValues)) {
await updateResponseWithError(snap, context)
throw new Error('Input values array was not provided to action request')
}
Expand Down Expand Up @@ -118,17 +130,17 @@ export async function runBackupsFromEvent(snap, context) {
inputValues,
template: { backups, inputs }
} = eventData
if (!isArray(backups)) {
if (!Array.isArray(backups)) {
await updateResponseWithError(snap, context)
throw new Error('Backups array was not provided to action request')
}

if (!isArray(inputs)) {
if (!Array.isArray(inputs)) {
await updateResponseWithError(snap, context)
throw new Error('Inputs array was not provided to action request')
}

if (!isArray(inputValues)) {
if (!Array.isArray(inputValues)) {
await updateResponseWithError(snap, context)
throw new Error('Input values array was not provided to action request')
}
Expand Down
2 changes: 1 addition & 1 deletion functions/src/callGoogleApi/callGoogleApi.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export async function googleApisRequest(serviceAccount, requestSettings) {
*/
export default async function callGoogleApi(snap, context) {
const eventVal = snap.val()
const eventId = get(context, 'params.pushId')
const { pushId: eventId } = context.params
const {
apiUrl,
api = 'storage',
Expand Down
5 changes: 0 additions & 5 deletions functions/src/callGoogleApi/constants.js
Original file line number Diff line number Diff line change
@@ -1,6 +1 @@
export const eventPathName = 'callGoogleApi'

export const SCOPES = [
'https://www.googleapis.com/auth/devstorage.full_control',
'https://www.googleapis.com/auth/cloud-platform'
]
2 changes: 1 addition & 1 deletion functions/src/cleanupProject/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ async function removeCollection(collectionSnap) {

/**
* Remove all collections from a Firestore document
* @param {object} docRef - Reference of document for which all collections
* @param {object} docRef - Reference of document for which all collections
* will be deleted
* @returns {Promise} Resolves with results of removing all collections
*/
Expand Down
20 changes: 0 additions & 20 deletions functions/src/constants/serviceAccount.js

This file was deleted.

Loading

0 comments on commit 4c6e214

Please sign in to comment.