fix: improve token management

This commit is contained in:
tdurieux
2024-06-18 12:00:45 +02:00
parent 9271332d5b
commit 532c094388
9 changed files with 90 additions and 32 deletions
+2 -1
View File
@@ -37,13 +37,14 @@ services:
mode: replicated mode: replicated
replicas: 4 replicas: 4
endpoint_mode: dnsrr endpoint_mode: dnsrr
entrypoint: ["node", "./build/streamer/index.js"] entrypoint: ["node", "--require", "./opentelemetry.js", "./build/streamer/index.js"]
env_file: env_file:
- ./.env - ./.env
volumes: volumes:
- ./repositories:/app/repositories/ - ./repositories:/app/repositories/
environment: environment:
- PORT=5000 - PORT=5000
- SERVICE_NAME=Streamer
healthcheck: healthcheck:
test: test:
- CMD - CMD
+1 -1
View File
@@ -14,7 +14,7 @@ const { diag, DiagConsoleLogger, DiagLogLevel } = require("@opentelemetry/api");
// diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.INFO); // diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.INFO);
const sdk = new opentelemetry.NodeSDK({ const sdk = new opentelemetry.NodeSDK({
serviceName: "Anonymous-GitHub", serviceName: process.env.SERVICE_NAME || "Anonymous-GitHub",
logRecordProcessor: getNodeAutoInstrumentations().logRecordProcessor, logRecordProcessor: getNodeAutoInstrumentations().logRecordProcessor,
traceExporter: new OTLPTraceExporter({ traceExporter: new OTLPTraceExporter({
url: "http://opentelemetry:4317/v1/traces", url: "http://opentelemetry:4317/v1/traces",
+53 -20
View File
@@ -29,35 +29,68 @@ export async function getToken(repository: Repository) {
span.setAttribute("repoId", repository.repoId); span.setAttribute("repoId", repository.repoId);
try { try {
// only check the token if the repo has been visited more than one day ago // only check the token if the repo has been visited more than one day ago
if ( // if (
repository.model.source.accessToken && // repository.model.source.accessToken &&
repository.model.lastView > new Date(Date.now() - 1000 * 60 * 60 * 24) // repository.model.lastView > new Date(Date.now() - 1000 * 60 * 60 * 24)
) { // ) {
return repository.model.source.accessToken; // return repository.model.source.accessToken;
} // }
if (repository.model.source.accessToken) { if (repository.model.source.accessToken) {
if (await checkToken(repository.model.source.accessToken)) { if (await checkToken(repository.model.source.accessToken)) {
return repository.model.source.accessToken; return repository.model.source.accessToken;
} }
} }
if (!repository.owner.model.accessTokens?.github) { if (!repository.owner.model.accessTokens?.github) {
const accessTokens = ( const query = await UserModel.findById(repository.owner.id, {
await UserModel.findById(repository.owner.id, { accessTokens: 1,
accessTokens: 1, accessTokenDates: 1,
}) });
)?.accessTokens; if (query?.accessTokens) {
if (accessTokens) { repository.owner.model.accessTokens = query.accessTokens;
repository.owner.model.accessTokens = accessTokens; repository.owner.model.accessTokenDates = query.accessTokenDates;
} }
} }
if (repository.owner.model.accessTokens?.github) { const ownerAccessToken = repository.owner.model.accessTokens?.github;
const check = await checkToken( if (ownerAccessToken) {
repository.owner.model.accessTokens?.github const tokenAge = repository.owner.model.accessTokenDates?.github;
); if (!tokenAge || tokenAge < new Date(Date.now() - 1000 * 60 * 60 * 24)) {
const url = `https://api.github.com/applications/${config.CLIENT_ID}/token`;
const headers = {
Accept: "application/vnd.github+json",
"X-GitHub-Api-Version": "2022-11-28",
};
const res = await fetch(url, {
method: "PATCH",
body: JSON.stringify({
access_token: ownerAccessToken,
}),
credentials: "include",
headers: {
...headers,
Authorization:
"Basic " +
Buffer.from(
config.CLIENT_ID + ":" + config.CLIENT_SECRET
).toString("base64"),
},
});
const resBody = (await res.json()) as { token: string };
repository.owner.model.accessTokens.github = resBody.token;
if (!repository.owner.model.accessTokenDates) {
repository.owner.model.accessTokenDates = {
github: new Date(),
};
} else {
repository.owner.model.accessTokenDates.github = new Date();
}
await repository.owner.model.save();
return resBody.token;
}
const check = await checkToken(ownerAccessToken);
if (check) { if (check) {
repository.model.source.accessToken = repository.model.source.accessToken = ownerAccessToken;
repository.owner.model.accessTokens?.github; return ownerAccessToken;
return repository.owner.model.accessTokens?.github;
} }
} }
return config.GITHUB_TOKEN; return config.GITHUB_TOKEN;
+6 -2
View File
@@ -518,7 +518,11 @@ export default class Repository {
await storage.rm(this.repoId); await storage.rm(this.repoId);
this.model.isReseted = true; this.model.isReseted = true;
if (isConnected) { if (isConnected) {
await this.model.save(); try {
await this.model.save();
} catch (error) {
console.error("[ERROR] removeCache save", error);
}
} }
} finally { } finally {
span.end(); span.end();
@@ -542,7 +546,7 @@ export default class Repository {
}> { }> {
const span = trace const span = trace
.getTracer("ano-file") .getTracer("ano-file")
.startSpan("Repository.removeCache"); .startSpan("Repository.computeSize");
span.setAttribute("repoId", this.repoId); span.setAttribute("repoId", this.repoId);
try { try {
if (this.status !== RepositoryStatus.READY) if (this.status !== RepositoryStatus.READY)
+3
View File
@@ -4,6 +4,9 @@ const UserSchema = new Schema({
accessTokens: { accessTokens: {
github: { type: String }, github: { type: String },
}, },
accessTokenDates: {
github: { type: Date },
},
externalIDs: { externalIDs: {
github: { type: String, index: true }, github: { type: String, index: true },
}, },
+3
View File
@@ -4,6 +4,9 @@ export interface IUser {
accessTokens: { accessTokens: {
github: string; github: string;
}; };
accessTokenDates?: {
github: Date;
};
externalIDs: { externalIDs: {
github: string; github: string;
}; };
+8 -8
View File
@@ -130,14 +130,6 @@ export default async function start() {
keyGenerator, keyGenerator,
}); });
app.use(
express.static(join("public"), {
etag: true,
lastModified: true,
maxAge: 3600, // 1h
})
);
app.use(function (req, res, next) { app.use(function (req, res, next) {
const start = Date.now(); const start = Date.now();
res.on("finish", function () { res.on("finish", function () {
@@ -216,6 +208,14 @@ export default async function start() {
// web view // web view
app.use("/w/", rate, webViewSpeedLimiter, router.webview); app.use("/w/", rate, webViewSpeedLimiter, router.webview);
app.use(
express.static(join("public"), {
etag: true,
lastModified: true,
maxAge: 3600, // 1h
})
);
app app
.get("/", indexResponse) .get("/", indexResponse)
.get("/404", indexResponse) .get("/404", indexResponse)
+7
View File
@@ -50,6 +50,13 @@ const verify = async (
}); });
if (user.emails?.length) user.emails[0].default = true; if (user.emails?.length) user.emails[0].default = true;
} }
if (!user.accessTokenDates) {
user.accessTokenDates = {
github: new Date(),
};
} else {
user.accessTokenDates.github = new Date();
}
await user.save(); await user.save();
} catch (error) { } catch (error) {
console.error(error); console.error(error);
+7
View File
@@ -48,6 +48,13 @@ router.post(
const archive = archiver("zip", {}); const archive = archiver("zip", {});
downloadStream downloadStream
.on("error", (error) => {
console.error(error);
archive.finalize();
})
.on("close", () => {
archive.finalize();
})
.pipe(Parse()) .pipe(Parse())
.on("entry", (entry) => { .on("entry", (entry) => {
if (entry.type === "File") { if (entry.type === "File") {