Skip to content

Commit

Permalink
Fix DocRegistry "garbage collector"
Browse files Browse the repository at this point in the history
  • Loading branch information
SleepyLeslie committed Jul 19, 2024
1 parent dc696fc commit 46a0fa0
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 23 deletions.
24 changes: 17 additions & 7 deletions ext/app/electron/DocRegistry.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as path from "path";
import { HomeDBManager } from "app/gen-server/lib/homedb/HomeDBManager";
import { fileExists } from "./utils";

export class DocRegistry {

Expand All @@ -20,13 +21,17 @@ export class DocRegistry {
// Go over all documents we know about.
for (const doc of await dr.db.getAllDocs()) {
// All documents are supposed to have externalId set.
if (doc.options?.externalId) {
const docPath = doc.options?.externalId;
if (docPath && fileExists(docPath)) {
// Cache the two-way mapping docID <-> path.
dr.idToPathMap.set(doc.id, doc.options?.externalId);
dr.pathToIdMap.set(doc.options?.externalId, doc.id);
dr.idToPathMap.set(doc.id, docPath);
dr.pathToIdMap.set(docPath, doc.id);
} else {
// Remove this document - it should not appear in a DB for Grist Desktop.
await dr.db.connection.manager.remove(doc);
await dr.db.deleteDocument({
userId: (await dr.getDefaultUser()).id,
urlId: doc.id
});
}
}
return dr;
Expand All @@ -40,18 +45,23 @@ export class DocRegistry {
return this.pathToIdMap.get(docPath) ?? null;
}

public async registerDoc(docPath: string): Promise<string> {
private async getDefaultUser() {
const user = await this.db.getUserByLogin(process.env.GRIST_DEFAULT_EMAIL as string);
if (!user) { throw new Error('cannot find default user'); }
const wss = this.db.unwrapQueryResult(await this.db.getOrgWorkspaces({userId: user.id}, 0));
return user;
}

public async registerDoc(docPath: string): Promise<string> {
const defaultUser = await this.getDefaultUser();
const wss = this.db.unwrapQueryResult(await this.db.getOrgWorkspaces({userId: defaultUser.id}, 0));
for (const doc of wss[0].docs) {
if (doc.options?.externalId === docPath) {
// We might be able to do better.
throw Error("DocRegistry cache incoherent. Please try restarting the app.");
}
}
const docId = this.db.unwrapQueryResult(await this.db.addDocument({
userId: user.id,
userId: defaultUser.id,
}, wss[0].id, {
name: path.basename(docPath, '.grist'),
options: { externalId: docPath },
Expand Down
11 changes: 3 additions & 8 deletions ext/app/electron/GristApp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { WindowManager } from "app/electron/WindowManager";
import { updateDb } from "app/server/lib/dbUtils";
import webviewOptions from "app/electron/webviewOptions";
import { Document } from "app/gen-server/entity/Document";
import { fileExists } from "./utils";

const GRIST_DOCUMENT_FILTER = {name: "Grist documents", extensions: ["grist"]};

Expand Down Expand Up @@ -61,7 +62,7 @@ export class GristApp {
* Opens a Grist document at docPath.
*/
private async openGristDocument(docPath: string, win?: electron.BrowserWindow) {
log.error(`Opening Grist document ${docPath}`);
log.debug(`Opening Grist document ${docPath}`);
// Do we know about this document?
let docId = this.docRegistry.lookupByPath(docPath);
if (docId === null) {
Expand Down Expand Up @@ -268,13 +269,7 @@ export class GristApp {
return null;
}
let docPath = result.filePath;
let fileExists = true;
try {
await fse.access(docPath, fse.constants.F_OK);
} catch {
fileExists = false;
}
if (fileExists) {
if (fileExists(docPath)) {
electron.dialog.showErrorBox("Cannot create document", `Document ${docPath} already exists.`);
return null;
}
Expand Down
15 changes: 7 additions & 8 deletions ext/app/electron/LoginSystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,8 @@ export class ElectronLoginSystem implements GristLoginSystem {
}

async getMiddleware(gristServer: GristServer) {
const loginSystem = this;
async function getLoginRedirectUrl(req: Request, url: URL) {
if (loginSystem.authMode !== 'none' && !(req as any).electronDirect) {
const getLoginRedirectUrl = async (req: Request, url: URL) => {
if (this.authMode !== 'none' && !(req as any).electronDirect) {
return getOrgUrl(req) + 'electron_only';
}
await setUserInSession(req, gristServer, getProfile());
Expand All @@ -61,10 +60,10 @@ export class ElectronLoginSystem implements GristLoginSystem {
const middleware: GristLoginMiddleware = {
getLoginRedirectUrl,
getSignUpRedirectUrl: getLoginRedirectUrl,
async getLogoutRedirectUrl(_: Request, url: URL) {
getLogoutRedirectUrl: async (_: Request, url: URL) => {
return url.href;
},
async addEndpoints(app) {
addEndpoints: async (app) => {
// Make sure default user exists.
const dbManager = gristServer.getHomeDBManager();
const profile = getProfile();
Expand All @@ -80,8 +79,8 @@ export class ElectronLoginSystem implements GristLoginSystem {
}));
return 'electron-login';
},
getWildcardMiddleware() {
if (loginSystem.authMode === 'none') {
getWildcardMiddleware: () => {
if (this.authMode === 'none') {
return [];
}
return [expressWrap(async (req, res, next) => {
Expand All @@ -95,7 +94,7 @@ export class ElectronLoginSystem implements GristLoginSystem {
if (keyPresented && keyPresented !== keyRemembered) {
res.cookie('electron_key', keyPresented);
}
if (keyPresented === loginSystem.credential || keyRemembered === loginSystem.credential) {
if (keyPresented === this.credential || keyRemembered === this.credential) {
(req as any).electronDirect = true;
}
return next();
Expand Down
11 changes: 11 additions & 0 deletions ext/app/electron/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import * as fse from "fs-extra";

export function fileExists(filePath: string): boolean {
let ret = true;
try {
fse.accessSync(filePath, fse.constants.F_OK);
} catch {
ret = false;
}
return ret;
}

0 comments on commit 46a0fa0

Please sign in to comment.