1+ const crypto = require ( 'crypto' ) ;
2+ const Share = require ( './models/Share' ) ;
3+ const AccessLog = require ( './models/AccessLog' ) ;
4+
5+ async function createShareLink ( { resourceId, ownerId, expiresAt } ) {
6+ const token = crypto . randomBytes ( 32 ) . toString ( 'hex' ) ;
7+ const tokenHash = crypto . createHash ( 'sha256' ) . update ( token ) . digest ( 'hex' ) ;
8+ const share = new Share ( {
9+ tokenHash,
10+ resourceId,
11+ ownerId,
12+ expiresAt : new Date ( expiresAt ) ,
13+ revoked : false
14+ } ) ;
15+ await share . save ( ) ;
16+ return { token, url : `/share/${ token } ` } ;
17+ }
18+
19+ async function getSharedResource ( token , ip ) {
20+ const tokenHash = crypto . createHash ( 'sha256' ) . update ( token ) . digest ( 'hex' ) ;
21+ const share = await Share . findOne ( { tokenHash } ) ;
22+ if ( ! share ) {
23+ await logAccess ( tokenHash , ip , false ) ;
24+ throw new Error ( 'Invalid token' ) ;
25+ }
26+ if ( share . revoked ) {
27+ await logAccess ( tokenHash , ip , false ) ;
28+ throw new Error ( 'Link revoked' ) ;
29+ }
30+ if ( new Date ( ) > share . expiresAt ) {
31+ await logAccess ( tokenHash , ip , false ) ;
32+ throw new Error ( 'Link expired' ) ;
33+ }
34+ await logAccess ( tokenHash , ip , true ) ;
35+ return { resourceId : share . resourceId , ownerId : share . ownerId } ;
36+ }
37+
38+ async function revokeShare ( token ) {
39+ const tokenHash = crypto . createHash ( 'sha256' ) . update ( token ) . digest ( 'hex' ) ;
40+ await Share . updateOne ( { tokenHash } , { revoked : true } ) ;
41+ }
42+
43+ async function getAccessLogs ( token ) {
44+ const tokenHash = crypto . createHash ( 'sha256' ) . update ( token ) . digest ( 'hex' ) ;
45+ return await AccessLog . find ( { tokenHash } ) . sort ( { timestamp : - 1 } ) ;
46+ }
47+
48+ async function logAccess ( tokenHash , ip , success ) {
49+ const log = new AccessLog ( {
50+ tokenHash,
51+ ip,
52+ success
53+ } ) ;
54+ await log . save ( ) ;
55+ }
56+
57+ module . exports = {
58+ createShareLink,
59+ getSharedResource,
60+ revokeShare,
61+ getAccessLogs
62+ } ;
0 commit comments