fix: very old .etherpad imports could break import due to lack of aut… (#7473)

* fix: very old .etherpad imports could break import due to lack of author metadata, allow this now

* test: add regression tests for old .etherpad import without author

Tests that importing an old .etherpad export (circa 2014) where
revision records lack meta.author succeeds without error, and that
getRevisionAuthor returns '' for such revisions.

Covers the fix for #6785.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
John McLear 2026-04-06 13:31:57 +01:00 committed by GitHub
parent e488a4338e
commit 270e3c6576
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 44 additions and 1 deletions

View File

@ -173,7 +173,7 @@ class Pad {
async getRevisionAuthor(revNum: number) {
// @ts-ignore
return await this.db.getSub(`pad:${this.id}:revs:${revNum}`, ['meta', 'author']);
return await this.db.getSub(`pad:${this.id}:revs:${revNum}`, ['meta', 'author']) ?? '';
}
async getRevisionDate(revNum: number) {

View File

@ -171,6 +171,49 @@ describe(__filename, function () {
}
});
// Regression test for https://github.com/ether/etherpad-lite/issues/6785
describe('old .etherpad imports without author metadata', function () {
// Old exports (circa 2014) have revisions where meta.author is missing entirely
const makeOldExportNoAuthor = () => ({
'pad:testing': {
atext: {
text: 'foo\n',
attribs: '|1+4',
},
pool: {
numToAttrib: {},
nextNum: 0,
},
head: 0,
savedRevisions: [],
},
// Revision 0 has no meta.author — this is how very old etherpads exported
'pad:testing:revs:0': {
changeset: 'Z:1>3+3$foo',
meta: {
timestamp: 1273769875976,
atext: {
text: 'foo\n',
attribs: '|1+4',
},
},
},
});
it('imports without error when revision lacks meta.author', async function () {
await importEtherpad.setPadRaw(padId, JSON.stringify(makeOldExportNoAuthor()));
const pad = await padManager.getPad(padId);
assert.equal(pad.text(), 'foo\n');
assert.equal(pad.head, 0);
});
it('getRevisionAuthor returns empty string for missing author', async function () {
await importEtherpad.setPadRaw(padId, JSON.stringify(makeOldExportNoAuthor()));
const pad = await padManager.getPad(padId);
assert.equal(await pad.getRevisionAuthor(0), '');
});
});
describe('exportEtherpadAdditionalContent', function () {
let hookBackup: Function;