-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.ts
More file actions
129 lines (113 loc) · 3.37 KB
/
index.ts
File metadata and controls
129 lines (113 loc) · 3.37 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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
const express = require("express");
const bodyParser = require("body-parser");
const axios = require('axios');
const cors = require("cors");
import { asyncExecute } from "./compiler/terminal";
import { createStreamLogger } from "./utils";
import generateConfig from "./compiler";
import { auth } from "./firebaseConfig";
import meta from "./package.json";
import { commandErrorHandler, logErrorToDB } from "./utils";
import firebase from "firebase-admin";
const app = express();
const jsonParser = bodyParser.json();
app.use(cors());
const axiosInstance = axios.create({
baseURL: 'http://metadata.google.internal/',
timeout: 1000,
headers: {'Metadata-Flavor': 'Google'}
});
app.get("/", async (req: any, res: any) => {
const resp = await axiosInstance.get('computeMetadata/v1/project/project-id')
res.send(`Firetable cloud function builder version ${meta.version}: running on ${resp.data}`);
});
app.post("/", jsonParser, async (req: any, res: any) => {
let user: firebase.auth.UserRecord;
const userToken = req?.body?.token;
if (!userToken) {
console.log("missing auth token");
res.send({
success: false,
reason: "missing auth token",
});
return;
}
try {
const decodedToken = await auth.verifyIdToken(userToken);
const uid = decodedToken.uid;
user = await auth.getUser(uid);
const roles = user?.customClaims?.roles;
if (!roles || !Array.isArray(roles) || !roles?.includes("ADMIN")) {
await logErrorToDB({
errorDescription: `user is not admin`,
user,
});
res.send({
success: false,
reason: `user is not admin`,
});
return;
}
console.log("successfully authenticated");
} catch (error) {
await logErrorToDB({
errorDescription: `error verifying auth token: ${error}`,
user,
});
res.send({
success: false,
reason: `error verifying auth token: ${error}`,
});
return;
}
const configPath = req?.body?.configPath;
console.log("configPath:", configPath);
if (!configPath) {
await logErrorToDB({
errorDescription: `Invalid configPath (${configPath})`,
user,
});
res.send({
success: false,
reason: "invalid configPath",
});
}
const streamLogger = await createStreamLogger(configPath);
await streamLogger.info("streamLogger created");
const success = await generateConfig(configPath, user, streamLogger);
if (!success) {
await streamLogger.error("generateConfig failed to complete");
await streamLogger.fail();
res.send({
success: false,
reason: `generateConfig failed to complete`,
});
return;
}
await streamLogger.info("generateConfig success");
// get gcp project id from metadata
const projectId = (await axiosInstance.get('computeMetadata/v1/project/project-id')).data
console.log(`deploying to ${projectId}`);
await asyncExecute(
`cd build/functions; \
yarn install`,
commandErrorHandler({ user }, streamLogger)
);
await asyncExecute(
`cd build/functions; \
yarn deployFT \
--project ${projectId} \
--only functions`,
commandErrorHandler({ user }, streamLogger)
);
await streamLogger.end();
res.send({
success: true,
});
});
const port = process.env.PORT || 8080;
app.listen(port, () => {
console.log(
`Firetable cloud function builder ${meta.version}: listening on port ${port}`
);
});