Skip to content

Commit

Permalink
feat: automatically share gsheets with editors (#291)
Browse files Browse the repository at this point in the history
  • Loading branch information
stevenle authored Mar 21, 2024
1 parent 8d0191a commit 12f69ee
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 3 deletions.
5 changes: 5 additions & 0 deletions .changeset/dry-gifts-sin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@blinkk/root-cms': minor
---

feat: automatically share gsheets with editors
1 change: 1 addition & 0 deletions packages/root-cms/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@
"@tabler/icons-preact": "2.39.0",
"@types/body-parser": "1.19.3",
"@types/gapi": "0.0.47",
"@types/gapi.client.drive-v3": "0.0.4",
"@types/gapi.client.sheets-v4": "0.0.4",
"@types/google.accounts": "0.0.14",
"@types/jsonwebtoken": "9.0.1",
Expand Down
1 change: 1 addition & 0 deletions packages/root-cms/ui/hooks/useGapiClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const SCOPES = [
];

const DISCOVERY_DOCS = [
'https://www.googleapis.com/discovery/v1/apis/drive/v3/rest',
'https://sheets.googleapis.com/$discovery/rest?version=v4',
];

Expand Down
1 change: 1 addition & 0 deletions packages/root-cms/ui/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"outDir": "dist",
"types": [
"@types/gapi",
"@types/gapi.client.drive-v3",
"@types/gapi.client.sheets-v4",
"@types/google.accounts",
"vite/client"
Expand Down
35 changes: 35 additions & 0 deletions packages/root-cms/ui/utils/gsheets.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import {getAllEditors} from './users.js';

export interface GoogleSheetId {
spreadsheetId: string;
gid?: number;
Expand Down Expand Up @@ -34,6 +36,11 @@ export class GSpreadsheet {
const spreadsheet = res.result;
const gspreadsheet = new GSpreadsheet(spreadsheet.spreadsheetId!);
gspreadsheet.setSpreadsheet(spreadsheet);

// Give all admins and editors "write" access.
const editors = await getAllEditors();
await gspreadsheet.share(editors, 'writer');

return gspreadsheet;
}

Expand Down Expand Up @@ -101,6 +108,34 @@ export class GSpreadsheet {
});
this.sheets = gsheets;
}

private async share(users: string[], role: 'reader' | 'writer') {
await Promise.all(
users.map(async (user) => {
let permission: any;
if (user.startsWith('*@')) {
const domain = user.slice(2);
permission = {
type: 'domain',
domain: domain,
role: role,
};
} else {
permission = {
type: 'user',
emailAddress: user,
role: role,
};
}
await gapi.client.drive.permissions.create({
fileId: this.spreadsheetId,
resource: permission,
sendNotificationEmail: false,
fields: 'id',
});
})
);
}
}

export class GSheet {
Expand Down
23 changes: 23 additions & 0 deletions packages/root-cms/ui/utils/users.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import {doc, getDoc} from 'firebase/firestore';

/**
* Returns a list of users that can edit, e.g. users with role EDITOR or ADMIN.
*/
export async function getAllEditors(): Promise<string[]> {
const db = window.firebase.db;
const projectId = window.__ROOT_CTX.rootConfig.projectId || 'default';
const docRef = doc(db, 'Projects', projectId);
const snapshot = await getDoc(docRef);
if (!snapshot.exists) {
return [];
}
const data: any = snapshot.data() || {};
const roles: Record<string, string> = data.roles || {};
const editors: string[] = [];
Object.entries(roles).forEach(([email, role]) => {
if (role === 'ADMIN' || role === 'EDITOR') {
editors.push(email);
}
});
return editors;
}
24 changes: 21 additions & 3 deletions pnpm-lock.yaml

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

0 comments on commit 12f69ee

Please sign in to comment.