feat: Record share link last accessed time (#2047)

* chore: Migrations

* chore: Add recording of share link views

* feat: Add display of share link accessed date in admin

* translations

* test

* translations, admin pagination
This commit is contained in:
Tom Moor
2021-04-18 09:38:13 -07:00
committed by GitHub
parent e9f083feb8
commit 7f9cba9819
11 changed files with 80 additions and 36 deletions

View File

@@ -518,6 +518,8 @@ async function loadDocument({ id, shareId, user }) {
if (!team.sharing) {
throw new AuthorizationError();
}
await share.update({ lastAccessedAt: new Date() });
} else {
document = await Document.findByPk(id, {
userId: user ? user.id : undefined,

View File

@@ -93,6 +93,9 @@ describe("#documents.info", () => {
expect(body.data.id).toEqual(document.id);
expect(body.data.createdBy).toEqual(undefined);
expect(body.data.updatedBy).toEqual(undefined);
await share.reload();
expect(share.lastAccessedAt).toBeTruthy();
});
it("should not return document from shareId if sharing is disabled for team", async () => {

View File

@@ -36,7 +36,7 @@ router.post("shares.info", auth(), async (ctx) => {
authorize(user, "read", share);
ctx.body = {
data: presentShare(share),
data: presentShare(share, user.isAdmin),
policies: presentPolicies(user, [share]),
};
});
@@ -89,7 +89,7 @@ router.post("shares.list", auth(), pagination(), async (ctx) => {
ctx.body = {
pagination: ctx.state.pagination,
data: shares.map(presentShare),
data: shares.map((share) => presentShare(share, user.isAdmin)),
policies: presentPolicies(user, shares),
};
});
@@ -117,7 +117,7 @@ router.post("shares.update", auth(), async (ctx) => {
});
ctx.body = {
data: presentShare(share),
data: presentShare(share, user.isAdmin),
policies: presentPolicies(user, [share]),
};
});

View File

@@ -0,0 +1,14 @@
'use strict';
module.exports = {
up: async (queryInterface, Sequelize) => {
await queryInterface.addColumn("shares", "lastAccessedAt", {
type: Sequelize.DATE,
allowNull: true,
});
},
down: async (queryInterface, Sequelize) => {
await queryInterface.removeColumn("shares", "lastAccessedAt");
}
};

View File

@@ -12,6 +12,7 @@ const Share = sequelize.define(
published: DataTypes.BOOLEAN,
revokedAt: DataTypes.DATE,
revokedById: DataTypes.UUID,
lastAccessedAt: DataTypes.DATE,
},
{
getterMethods: {

View File

@@ -2,7 +2,7 @@
import { Event } from "../models";
import presentUser from "./user";
export default function present(event: Event, auditLog: boolean = false) {
export default function present(event: Event, isAdmin: boolean = false) {
let data = {
id: event.id,
name: event.name,
@@ -16,7 +16,7 @@ export default function present(event: Event, auditLog: boolean = false) {
actor: presentUser(event.actor),
};
if (!auditLog) {
if (!isAdmin) {
delete data.actorIpAddress;
}

View File

@@ -2,8 +2,8 @@
import { Share } from "../models";
import { presentUser } from ".";
export default function present(share: Share) {
return {
export default function present(share: Share, isAdmin: boolean = false) {
let data = {
id: share.id,
documentId: share.documentId,
documentTitle: share.document.title,
@@ -11,7 +11,14 @@ export default function present(share: Share) {
published: share.published,
url: `${share.team.url}/share/${share.id}`,
createdBy: presentUser(share.user),
lastAccessedAt: share.lastAccessedAt,
createdAt: share.createdAt,
updatedAt: share.updatedAt,
};
if (!isAdmin) {
delete data.lastAccessedAt;
}
return data;
}