Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ export interface Env {
S3_SECRET_ACCESS_KEY: string;
IMS_ORIGIN: string;
AEM_BUCKET_NAME: string;
// shared secret used as authorization when invoking the collab service (eg for syncadmin)
COLLAB_SHARED_SECRET: string;

DA_AUTH: KVNamespace,
DA_CONFIG: KVNamespace,
Expand Down
4 changes: 2 additions & 2 deletions src/routes/source.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import getObject from '../storage/object/get.js';
import putObject from '../storage/object/put.js';
import deleteObjects from '../storage/object/delete.js';
import { invalidateCollab } from '../storage/utils/object.js';
import { notifyCollab } from '../storage/utils/object.js';

import putHelper from '../helpers/source.js';
import deleteHelper from '../helpers/delete.js';
Expand All @@ -32,7 +32,7 @@ export async function postSource({ req, env, daCtx }) {
if (resp.status === 201 || resp.status === 200) {
const initiator = req.headers.get('x-da-initiator');
if (initiator !== 'collab') {
await invalidateCollab('syncadmin', req.url, env);
await notifyCollab('syncadmin', req.url, env);
}
}
return resp;
Expand Down
4 changes: 2 additions & 2 deletions src/storage/object/copy.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {

import getObject from './get.js';
import getS3Config from '../utils/config.js';
import { invalidateCollab } from '../utils/object.js';
import { notifyCollab } from '../utils/object.js';
import { putObjectWithVersion } from '../version/put.js';
import { getUsersForMetadata } from '../utils/version.js';
import { listCommand } from '../utils/list.js';
Expand Down Expand Up @@ -113,7 +113,7 @@ export const copyFile = async (config, env, daCtx, sourceKey, details, isRename)
} finally {
if (Key.endsWith('.html')) {
// Reset the collab cached state for the copied object
await invalidateCollab('syncAdmin', `${daCtx.origin}/source/${daCtx.org}/${Key}`, env);
await notifyCollab('syncAdmin', `${daCtx.origin}/source/${daCtx.org}/${Key}`, env);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see this was the case before already, but we should probably align the capitalization of syncAdmin vs syncadmin

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, see #198

}
}
};
Expand Down
4 changes: 2 additions & 2 deletions src/storage/object/delete.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
} from '@aws-sdk/client-s3';
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
import getS3Config from '../utils/config.js';
import { invalidateCollab } from '../utils/object.js';
import { notifyCollab } from '../utils/object.js';
// import { postObjectVersionWithLabel } from '../version/put.js';
import { listCommand } from '../utils/list.js';
import { hasPermission } from '../../utils/auth.js';
Expand All @@ -41,7 +41,7 @@ export async function deleteObject(client, daCtx, Key, env /* , isMove = false *
}

if (Key.endsWith('.html')) {
await invalidateCollab('deleteadmin', `${daCtx.origin}/source/${daCtx.org}/${Key}`, env);
await notifyCollab('deleteadmin', `${daCtx.origin}/source/${daCtx.org}/${Key}`, env);
}

return resp;
Expand Down
19 changes: 17 additions & 2 deletions src/storage/utils/object.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,14 @@
* OF ANY KIND, either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/
export async function invalidateCollab(api, url, env) {
/**
* Sends a `api` request to collab
* @param {string} api The API ('syncadmin' or 'deleteadmin')
* @param {string} url Url of the resource
* @param {Env} env
* @returns {Promise<void>}
*/
export async function notifyCollab(api, url, env) {
if (!url.endsWith('.html')) {
// collab only deals with .html files, no need to invalidate anything else
return;
Expand All @@ -19,5 +26,13 @@ export async function invalidateCollab(api, url, env) {

// Use dacollab service binding, hostname is not relevant
const invURL = `https://localhost${invPath}`;
await env.dacollab.fetch(invURL);
const headers = {};
if (env.COLLAB_SHARED_SECRET) {
headers.authorization = `token ${env.COLLAB_SHARED_SECRET}`;
}
await env.dacollab.fetch(invURL, {
// TODO: use POST for state changing operations
// method: 'POST',
headers,
});
}
26 changes: 22 additions & 4 deletions test/storage/utils/object.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

/* eslint-env mocha */
import assert from 'node:assert';
import { invalidateCollab } from '../../../src/storage/utils/object.js';
import { notifyCollab } from '../../../src/storage/utils/object.js';

describe('Storage Object Utils tests', () => {
function setupEnv() {
Expand All @@ -31,7 +31,7 @@ describe('Storage Object Utils tests', () => {
const { called, env } = setupEnv();

assert.strictEqual(called.length, 0, 'precondition');
await invalidateCollab('syncAdmin', 'https://admin.da.live/source/a/b/c.html', env);
await notifyCollab('syncAdmin', 'https://admin.da.live/source/a/b/c.html', env);
assert.strictEqual(called.length, 1);
assert.strictEqual(called[0], 'https://localhost/api/v1/syncAdmin?doc=https://admin.da.live/source/a/b/c.html');
});
Expand All @@ -40,8 +40,26 @@ describe('Storage Object Utils tests', () => {
const { called, env } = setupEnv();

assert.strictEqual(called.length, 0, 'precondition');
await invalidateCollab('syncAdmin', 'https://admin.da.live/source/a/b/c.jpg', env);
await invalidateCollab('syncAdmin', 'https://admin.da.live/source/a/b/c/d', env);
await notifyCollab('syncAdmin', 'https://admin.da.live/source/a/b/c.jpg', env);
await notifyCollab('syncAdmin', 'https://admin.da.live/source/a/b/c/d', env);
assert.strictEqual(called.length, 0, 'should not have invalidated anything');
});

it('Should invalidate (with shared secret', async () => {
const called = [];
const env = {
dacollab: {
fetch: async (url, opts) => {
console.log(`invalidate called with ${url}`);
assert.strictEqual(opts.headers.authorization, 'token example-secret');
called.push(url);
},
},
COLLAB_SHARED_SECRET: 'example-secret',
};
assert.strictEqual(called.length, 0, 'precondition');
await notifyCollab('syncAdmin', 'https://admin.da.live/source/a/b/c.html', env);
assert.strictEqual(called.length, 1);
assert.strictEqual(called[0], 'https://localhost/api/v1/syncAdmin?doc=https://admin.da.live/source/a/b/c.html');
});
});