Skip to content

Commit

Permalink
Add WIP functionality for designers to add and edit their own sets.
Browse files Browse the repository at this point in the history
  • Loading branch information
EskiMojo14 committed Jul 13, 2020
1 parent 1c9033c commit abf9fee
Show file tree
Hide file tree
Showing 16 changed files with 407 additions and 266 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,5 @@ yarn-debug.log*
yarn-error.log*
firebase-debug.log
.firebase/*.cache
logo.ai
keycaplendar.xd
8 changes: 2 additions & 6 deletions firebase.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,8 @@
],
"rewrites": [
{
"source": "/api/isEditor",
"function": "isEditor"
},
{
"source": "/api/isAdmin",
"function": "isAdmin"
"source": "/api/getClaims",
"function": "getClaims"
},
{
"source": "/api/listUsers",
Expand Down
111 changes: 69 additions & 42 deletions functions/index.js
Original file line number Diff line number Diff line change
@@ -1,102 +1,129 @@

const admin = require('firebase-admin');
const functions = require('firebase-functions');
const admin = require("firebase-admin");
const functions = require("firebase-functions");

const app = admin.initializeApp();

exports.isEditor = functions.https.onCall((data, context) => {
if (context.auth && (context.auth.token.editor === true)) {
return true;
}
return false;
});

exports.isAdmin = functions.https.onCall((data, context) => {
if (context.auth && (context.auth.token.admin === true)) {
return true;
exports.getClaims = functions.https.onCall((data, context) => {
if (context.auth) {
return {
nickname: context.auth.token.nickname ? context.auth.token.nickname : "",
designer: context.auth.token.designer ? context.auth.token.designer : false,
editor: context.auth.token.editor ? context.auth.token.editor : false,
admin: context.auth.token.admin ? context.auth.token.admin : false,
};
}
return false;
return {
nickname: "",
designer: false,
editor: false,
admin: false,
};
});

exports.listUsers = functions.https.onCall(async (data, context) => {
if (!context.auth || context.auth.token.admin !== true) {
return {
error: "Current user is not an admin. Access is not permitted."
}
error: "Current user is not an admin. Access is not permitted.",
};
}
// List batch of users, 1000 at a time.
const users = await admin.auth().listUsers(1000)
const users = await admin
.auth()
.listUsers(1000)
.then((result) => {
const newArray = result.users.map((user) => {
if (user.customClaims) {
return {
displayName: user.displayName,
email: user.email,
photoURL: user.photoURL,
editor: (user.customClaims.editor ? true : false),
admin: (user.customClaims.admin ? true : false )
nickname: user.customClaims.nickname ? user.customClaims.nickname : "",
designer: user.customClaims.designer ? true : false,
editor: user.customClaims.editor ? true : false,
admin: user.customClaims.admin ? true : false,
};
} else {
return {
displayName: user.displayName,
email: user.email,
photoURL: user.photoURL,
nickname: "",
designer: false,
editor: false,
admin: false
admin: false,
};
}
})
});
return newArray;
})
.catch((error) => {
return { error: 'Error listing users: ' + error };
return { error: "Error listing users: " + error };
});
return users;
});


exports.deleteUser = functions.https.onCall(async (data, context) => {
if (!context.auth || context.auth.token.admin !== true) {
return {
error: "Current user is not an admin. Access is not permitted."
}
error: "Current user is not an admin. Access is not permitted.",
};
}
if (data.email === '[email protected]') {
if (data.email === "[email protected]") {
return {
error: "This user cannot be deleted"
}
error: "This user cannot be deleted",
};
}
const currentUser = await admin.auth().getUser(context.auth.uid);
const user = await admin.auth().getUserByEmail(data.email);
admin.auth().deleteUser(user.uid)
admin
.auth()
.deleteUser(user.uid)
.then(() => {
console.log(currentUser.displayName + ' successfully deleted account of ' + user.displayName + '.');
console.log(currentUser.displayName + " successfully deleted account of " + user.displayName + ".");
return null;
})
.catch((error) => {
return { error: 'Error deleting user: ' + error};
return { error: "Error deleting user: " + error };
});
return 'Success';
return "Success";
});

exports.setRoles = functions.https.onCall(async (data, context) => {
if (!context.auth || context.auth.token.admin !== true) {
return {
error: "User not admin."
}
error: "User not admin.",
};
}
const currentUser = await admin.auth().getUser(context.auth.uid);
const user = await admin.auth().getUserByEmail(data.email);
const claims = {
designer: data.designer,
nickname: data.nickname,
editor: data.editor,
admin: data.admin
}
await admin.auth().setCustomUserClaims(user.uid, claims).then(() => {
console.log(currentUser.displayName + ' successfully edited account of ' + user.displayName + '. Editor: ' + data.editor + ', admin: ' + data.admin);
return null
}).catch((error) => {
return { error: 'Error setting roles: ' + error};
})
admin: data.admin,
};
await admin
.auth()
.setCustomUserClaims(user.uid, claims)
.then(() => {
console.log(
currentUser.displayName +
" successfully edited account of " +
user.displayName +
". Designer: " +
data.designer +
", editor: " +
data.editor +
", admin: " +
data.admin +
", nickname: " +
data.nickname
);
return null;
})
.catch((error) => {
return { error: "Error setting roles: " + error };
});
const newUser = await admin.auth().getUserByEmail(data.email);
return newUser.customClaims;
});
Binary file removed keycaplendar.xd
Binary file not shown.
20 changes: 10 additions & 10 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

50 changes: 21 additions & 29 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class App extends React.Component {
loading: false,
content: true,
search: "",
user: { email: null, name: null, avatar: null, isEditor: false, isAdmin: false },
user: { email: null, name: null, avatar: null, isEditor: false, isAdmin: false, nickname: "", isDesigner: false },
whitelist: { vendors: [], profiles: [], edited: false },
cookies: true,
applyTheme: "manual",
Expand Down Expand Up @@ -689,40 +689,27 @@ class App extends React.Component {
document.querySelector("html").classList = this.state.theme;
this.unregisterAuthObserver = firebase.auth().onAuthStateChanged((user) => {
if (user) {
const isEditorFn = firebase.functions().httpsCallable("isEditor");
isEditorFn()
const getClaimsFn = firebase.functions().httpsCallable("getClaims");
getClaimsFn()
.then((result) => {
const isEditor = result.data;
const isAdminFn = firebase.functions().httpsCallable("isAdmin");
isAdminFn()
.then((result) => {
this.setUser({
email: user.email,
name: user.displayName,
avatar: user.photoURL,
isEditor: isEditor,
isAdmin: result.data,
});
})
.catch((error) => {
console.log("Error verifying admin access: " + error);
queue.notify({ title: "Error verifying admin access: " + error });
this.setUser({
email: user.email,
name: user.displayName,
avatar: user.photoURL,
isEditor: isEditor,
isAdmin: false,
});
});
this.setUser({
email: user.email,
name: user.displayName,
avatar: user.photoURL,
nickname: result.data.nickname,
isDesigner: result.data.designer,
isEditor: result.data.editor,
isAdmin: result.data.admin,
});
})
.catch((error) => {
console.log("Error verifying editor access: " + error);
queue.notify({ title: "Error verifying editor access: " + error });
queue.notify({ title: "Error verifying custom claims: " + error });
this.setUser({
email: user.email,
name: user.displayName,
avatar: user.photoURL,
nickname: "",
isDesigner: false,
isEditor: false,
isAdmin: false,
});
Expand Down Expand Up @@ -877,7 +864,12 @@ class App extends React.Component {
<Switch>
<Route path="/users">
<div>
<Users admin={this.state.user.isAdmin} user={this.state.user} snackbarQueue={queue} />
<Users
admin={this.state.user.isAdmin}
user={this.state.user}
snackbarQueue={queue}
allDesigners={this.state.allDesigners}
/>
<SnackbarQueue messages={queue.messages} />
</div>
</Route>
Expand Down
Loading

0 comments on commit abf9fee

Please sign in to comment.