forked from bigcommerce/sample-app-nodejs
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfirebase.ts
More file actions
109 lines (88 loc) · 3.34 KB
/
firebase.ts
File metadata and controls
109 lines (88 loc) · 3.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import { cert, getApp, getApps, initializeApp } from 'firebase-admin/app';
import { getFirestore } from 'firebase-admin/firestore';
import serviceAccount from '../../sample-firebase-keys.json';
import { SessionProps, UserData } from '../../types';
const app = getApps().length
? getApp()
: initializeApp({ credential: cert(serviceAccount as any) });
const db = getFirestore(app);
// Firestore data management functions
// Use setUser for storing global user data (persists between installs)
export async function setUser({ user }: SessionProps) {
if (!user) return null;
const { email, id, username } = user;
const ref = db.collection('user').doc(String(id));
const data: UserData = { email };
if (username) {
data.username = username;
}
await ref.set(data, {merge: true });
}
export async function setStore(session: SessionProps) {
const {
access_token: accessToken,
context,
scope,
user: { id },
} = session;
// Only set on app install or update
if (!accessToken || !scope) return null;
const storeHash = context?.split('/')[1] || '';
const ref = db.collection('store').doc(storeHash);
const data = { accessToken, adminId: id, scope };
await ref.set(data);
}
// User management for multi-user apps
// Use setStoreUser for storing store specific variables
export async function setStoreUser(session: SessionProps) {
const {
access_token: accessToken,
context,
owner,
sub,
user: { id: userId },
} = session;
if (!userId) return null;
const contextString = context ?? sub;
const storeHash = contextString?.split('/')[1] || '';
const documentId = `${userId}_${storeHash}`; // users can belong to multiple stores
const ref = db.collection('storeUsers').doc(documentId);
const storeUser = await ref.get();
// Set admin (store owner) if installing/ updating the app
// https://developer.bigcommerce.com/api-docs/apps/guide/users
if (accessToken) {
// Create a new admin user if none exists
if (!storeUser.exists) {
await ref.set({ storeHash, isAdmin: true });
} else if (!storeUser.data()?.isAdmin) {
await ref.update({ isAdmin: true });
}
} else {
// Create a new user if it doesn't exist
if (!storeUser.exists) {
await ref.set({ storeHash, isAdmin: owner.id === userId });
}
}
}
export async function deleteUser({ context, user, sub }: SessionProps) {
const contextString = context ?? sub;
const storeHash = contextString?.split('/')[1] || '';
const docId = `${user?.id}_${storeHash}`;
const ref = db.collection('storeUsers').doc(docId);
await ref.delete();
}
export async function hasStoreUser(storeHash: string, userId: string) {
if (!storeHash || !userId) return false;
const docId = `${userId}_${storeHash}`;
const userDoc = await db.collection('storeUsers').doc(docId).get();
return userDoc.exists;
}
export async function getStoreToken(storeHash: string) {
if (!storeHash) return null;
const storeDoc = await db.collection('store').doc(storeHash).get();
return storeDoc.data()?.accessToken ?? null;
}
export async function deleteStore({ store_hash: storeHash }: SessionProps) {
const ref = db.collection('store').doc(storeHash);
await ref.delete();
}