mirror of
https://github.com/rowyio/rowy.git
synced 2026-02-24 04:01:17 +01:00
Merge branch 'develop' of https://github.com/AntlerVC/firetable into develop
This commit is contained in:
@@ -44,8 +44,8 @@ supported. More coming soon, for comprehensive list see ROADMAP.md.
|
||||
|
||||
- Upgrade project to the Blaze Plan
|
||||
- Enable the Google sign-in method in **Authentication / Sign-in method**
|
||||
- **⚠️ IMPORTANT:** If you try to sign in and see “This account does not
|
||||
exist”, run
|
||||
- **⚠️ IMPORTANT:** If you try to sign in and see “This account does not have
|
||||
any roles”, run
|
||||
[the following script](https://github.com/AntlerVC/firetable/blob/develop/RULES.md#custom-claims)
|
||||
on your Firebase Authentication user.
|
||||
|
||||
@@ -126,9 +126,9 @@ yarn start
|
||||
[Please create issues here.](https://github.com/antlervc/firetable/issues)
|
||||
Make sure to provide console log outputs and screenshots!
|
||||
|
||||
### Known Issue: “This account does not exist”
|
||||
### Known Issue: “This account does not have any roles”
|
||||
|
||||
If you try to sign in and see “This account does not exist”, run
|
||||
If you try to sign in and see “This account does not have any roles”, run
|
||||
[the following script](https://github.com/AntlerVC/firetable/blob/develop/RULES.md#custom-claims)
|
||||
on your Firebase Authentication user.
|
||||
|
||||
|
||||
7
RULES.md
7
RULES.md
@@ -51,8 +51,11 @@ The firetable roles are stored in the users firebase auth token custom claims
|
||||
|
||||
### setting roles
|
||||
|
||||
this a basic script for setting your user roles. you can run this locally using
|
||||
the adm sdk or implement it in your cloud functions
|
||||
You can use the CLI tool to set your roles
|
||||
[here](https://github.com/AntlerVC/firetable/blob/master/cli/README.md#Setting-user-Roles)
|
||||
|
||||
It relays on this basic script. you can run this locally using the adm sdk or
|
||||
implement it in your cloud functions
|
||||
|
||||
```js
|
||||
import * as admin from "firebase-admin";
|
||||
|
||||
@@ -6,6 +6,7 @@ Make sure you have the following installed:
|
||||
|
||||
- [Git](https://git-scm.com/downloads)
|
||||
- [Node](https://nodejs.org/en/download/)
|
||||
- [Yarn](https://classic.yarnpkg.com/en/docs/install/)
|
||||
- [Firebase CLI](https://firebase.google.com/docs/cli)
|
||||
|
||||
Also make sure you are logged in to your Firebase account in the Firebase CLI.
|
||||
@@ -47,3 +48,25 @@ First, make sure that you have created a site in your Firebase project.
|
||||
```
|
||||
firetable deploy
|
||||
```
|
||||
|
||||
## Firebase Rules & Firetable roles
|
||||
|
||||
Read more about firebase rules for firetable
|
||||
[HERE](https://github.com/AntlerVC/firetable/blob/master/RULES.md)
|
||||
|
||||
### Setting user Roles
|
||||
|
||||
Download the admin key for your project then add it to the directory without
|
||||
renaming it. You can find your service account here:
|
||||
https://console.firebase.google.com/u/0/project/_/settings/serviceaccounts/adminsdk
|
||||
|
||||
```
|
||||
firetable auth:setRoles <email> <roles>
|
||||
```
|
||||
|
||||
email: needs to be associated with an existing firebase account on the example
|
||||
roles: can be one role `ADMIN` or a comma separated array `ADMIN,OPS,DEV`
|
||||
|
||||
```
|
||||
firetable auth:setRoles shams@antler.co OPS,INTERNAL
|
||||
```
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
"commander": "^6.0.0",
|
||||
"configstore": "^5.0.1",
|
||||
"figlet": "^1.5.0",
|
||||
"firebase-admin": "^9.1.1",
|
||||
"inquirer": "^7.3.3",
|
||||
"lodash": "^4.17.19",
|
||||
"open": "^7.1.0"
|
||||
|
||||
@@ -6,11 +6,11 @@ const terminal = require("./lib/terminal");
|
||||
const inquirer = require("./lib/inquirer");
|
||||
const Configstore = require("configstore");
|
||||
const config = new Configstore("firetable");
|
||||
const { directoryExists } = require("./lib/files");
|
||||
const { directoryExists, findFile } = require("./lib/files");
|
||||
const process = require("process");
|
||||
const { Command } = require("commander");
|
||||
const { version } = require("../package.json");
|
||||
|
||||
const { setUserRoles } = require("./lib/firebaseAdmin");
|
||||
const program = new Command();
|
||||
program.version(version);
|
||||
|
||||
@@ -34,7 +34,6 @@ const systemHealthCheck = async () => {
|
||||
Object.entries(versions).forEach(([app, version]) =>
|
||||
console.log(`${app.padEnd(8)} ${chalk.green(version)}`)
|
||||
);
|
||||
console.log();
|
||||
};
|
||||
|
||||
// checks the current directory of the cli app
|
||||
@@ -207,4 +206,41 @@ program
|
||||
}
|
||||
});
|
||||
|
||||
program
|
||||
.command("auth:setRoles <email> <roles>")
|
||||
.description(
|
||||
"Adds roles to the custom claims of a specified firebase account."
|
||||
)
|
||||
.action(async (email, roles) => {
|
||||
try {
|
||||
// check directory for admin sdk json
|
||||
const adminSDKFilePath = await findFile(/.*-firebase-adminsdk.*json/);
|
||||
|
||||
// let directory = await directoryCheck();
|
||||
// if (!directory) return;
|
||||
// await deploy2firebase(directory);
|
||||
const result = await setUserRoles(adminSDKFilePath)(
|
||||
email,
|
||||
roles.split(",")
|
||||
);
|
||||
if (result.success) {
|
||||
console.log(result.message);
|
||||
return;
|
||||
} else if (result.code === "auth/user-not-found") {
|
||||
console.log(
|
||||
chalk.bold(chalk.red("FAILED: ")),
|
||||
`could not find an account corresponding with`,
|
||||
chalk.bold(email)
|
||||
);
|
||||
return;
|
||||
} else {
|
||||
console.log(chalk.bold(chalk.red(result.message)));
|
||||
return;
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("\u{1F6D1}" + chalk.bold(chalk.red(" FAILED")));
|
||||
console.log(error);
|
||||
}
|
||||
});
|
||||
|
||||
program.parse(process.argv);
|
||||
|
||||
@@ -9,4 +9,19 @@ module.exports = {
|
||||
directoryExists: (filePath) => {
|
||||
return fs.existsSync(filePath);
|
||||
},
|
||||
findFile: (fileRegex) =>
|
||||
new Promise((resolve, reject) =>
|
||||
fs.readdir("./", (err, files) => {
|
||||
const file = files
|
||||
.map((file) => file.match(fileRegex))
|
||||
.filter((_file) => _file)[0];
|
||||
if (file) {
|
||||
resolve(file[0]);
|
||||
} else {
|
||||
reject(
|
||||
"Can not find the firebase service account key json file, download the admin key for your project then add it to this directory without renaming it.\nYou can find your service account here: https://console.firebase.google.com/u/0/project/_/settings/serviceaccounts/adminsdk"
|
||||
);
|
||||
}
|
||||
})
|
||||
),
|
||||
};
|
||||
|
||||
36
cli/src/lib/firebaseAdmin.js
Normal file
36
cli/src/lib/firebaseAdmin.js
Normal file
@@ -0,0 +1,36 @@
|
||||
const admin = require("firebase-admin");
|
||||
const fs = require("fs");
|
||||
const initializeApp = (serviceAccountFile) => {
|
||||
console.log(serviceAccountFile);
|
||||
var serviceAccount = fs.readFileSync(`./${serviceAccountFile}`, {
|
||||
encoding: "utf8",
|
||||
});
|
||||
const serviceAccountJSON = JSON.parse(serviceAccount);
|
||||
admin.initializeApp({
|
||||
credential: admin.credential.cert(serviceAccountJSON),
|
||||
databaseURL: `https://${serviceAccountJSON.project_id}.firebaseio.com`,
|
||||
});
|
||||
const auth = admin.auth();
|
||||
return { auth };
|
||||
};
|
||||
module.exports.setUserRoles = (serviceAccountFile) => async (email, roles) => {
|
||||
try {
|
||||
const { auth } = initializeApp(serviceAccountFile);
|
||||
// Initialize Auth
|
||||
// sets the custom claims on an account to the claims object provided
|
||||
const user = await auth.getUserByEmail(email);
|
||||
await auth.setCustomUserClaims(user.uid, { ...user.customClaims, roles });
|
||||
return {
|
||||
success: true,
|
||||
message: `✅ ${email} now has the following roles ✨${roles.join(
|
||||
" & "
|
||||
)}✨`,
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
success: false,
|
||||
code: "auth/user-not-found",
|
||||
message: error.message,
|
||||
};
|
||||
}
|
||||
};
|
||||
933
cli/yarn.lock
933
cli/yarn.lock
File diff suppressed because it is too large
Load Diff
@@ -40,7 +40,7 @@ const useSettings = () => {
|
||||
//create the firetable collection doc with empty columns
|
||||
db.collection("_FIRETABLE_/settings/schema")
|
||||
.doc(data.collection)
|
||||
.set({ ...data, columns: [] }, { merge: true });
|
||||
.set({ ...data }, { merge: true });
|
||||
};
|
||||
|
||||
const updateTable = (data: {
|
||||
|
||||
@@ -24,6 +24,7 @@ export const SnackProvider: React.FC<ISnackProviderProps> = ({ children }) => {
|
||||
setMessage("");
|
||||
setDuration(0);
|
||||
setSeverity(undefined);
|
||||
setAction(<div />);
|
||||
};
|
||||
const open = (props: {
|
||||
message: string;
|
||||
|
||||
@@ -8,6 +8,8 @@ import AuthCard from "./AuthCard";
|
||||
import { handleGoogleAuth } from "./utils";
|
||||
import GoogleLogo from "assets/google-icon.svg";
|
||||
import { useSnackContext } from "contexts/snackContext";
|
||||
import { Link } from "react-router-dom";
|
||||
import { auth } from "../../firebase";
|
||||
export default function GoogleAuthView() {
|
||||
const [loading, setLoading] = useState(false);
|
||||
const snack = useSnackContext();
|
||||
@@ -27,7 +29,45 @@ export default function GoogleAuthView() {
|
||||
},
|
||||
(error: Error) => {
|
||||
setLoading(false);
|
||||
snack.open({ message: error.message });
|
||||
console.log(error);
|
||||
if (
|
||||
error.message ===
|
||||
"The identity provider configuration is disabled."
|
||||
) {
|
||||
snack.open({
|
||||
severity: "warning",
|
||||
message:
|
||||
"You need to enable Google authentication in your firebase project",
|
||||
action: (
|
||||
<Button
|
||||
component="a"
|
||||
href={`https://console.firebase.google.com/u/0/project/${auth.app.options["projectId"]}/authentication/providers`}
|
||||
target="_blank"
|
||||
>
|
||||
Go to settings
|
||||
</Button>
|
||||
),
|
||||
});
|
||||
} else if (
|
||||
error.message === "This account does not have any roles"
|
||||
) {
|
||||
snack.open({
|
||||
severity: "warning",
|
||||
message:
|
||||
"You need to enable Google authentication in your firebase project",
|
||||
action: (
|
||||
<Button
|
||||
component="a"
|
||||
href={`https://github.com/AntlerVC/firetable/blob/master/RULES.md`}
|
||||
target="_blank"
|
||||
>
|
||||
Instructions
|
||||
</Button>
|
||||
),
|
||||
});
|
||||
} else {
|
||||
snack.open({ message: error.message });
|
||||
}
|
||||
},
|
||||
parsedQuery.email as string
|
||||
);
|
||||
|
||||
@@ -14,7 +14,7 @@ export const handleGoogleAuth = async (
|
||||
if (result.claims.roles && result.claims.roles.length !== 0) {
|
||||
success(authUser, result.claims.roles);
|
||||
} else {
|
||||
throw Error("This account does not exist");
|
||||
throw Error("This account does not have any roles");
|
||||
}
|
||||
} catch (error) {
|
||||
if (auth.currentUser) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React, { useEffect } from "react";
|
||||
import queryString from "query-string";
|
||||
import { useFiretableContext } from "contexts/firetableContext";
|
||||
import { useAppContext } from "contexts/appContext";
|
||||
|
||||
import { Hidden } from "@material-ui/core";
|
||||
|
||||
@@ -12,11 +13,12 @@ import { FireTableFilter } from "hooks/useFiretable";
|
||||
import useRouter from "hooks/useRouter";
|
||||
|
||||
import ImportWizard from "components/Wizards/ImportWizard";
|
||||
|
||||
import { DocActions } from "hooks/useDoc";
|
||||
export default function TableView() {
|
||||
const router = useRouter();
|
||||
const tableCollection = decodeURIComponent(router.match.params.id);
|
||||
const { tableState, tableActions, sideDrawerRef } = useFiretableContext();
|
||||
const { userDoc } = useAppContext();
|
||||
let filters: FireTableFilter[] = [];
|
||||
const parsed = queryString.parse(router.location.search);
|
||||
if (typeof parsed.filters === "string") {
|
||||
@@ -32,7 +34,15 @@ export default function TableView() {
|
||||
tableState &&
|
||||
tableState.tablePath !== tableCollection
|
||||
) {
|
||||
tableActions.table.set(tableCollection, filters);
|
||||
if (filters && filters.length !== 0) {
|
||||
tableActions.table.set(tableCollection, filters);
|
||||
userDoc.dispatch({
|
||||
action: DocActions.update,
|
||||
data: {
|
||||
tables: { [`${tableState?.tablePath}`]: { filters } },
|
||||
},
|
||||
});
|
||||
}
|
||||
if (sideDrawerRef?.current) sideDrawerRef.current.setCell!(null);
|
||||
}
|
||||
}, [tableCollection]);
|
||||
|
||||
Reference in New Issue
Block a user