|
|
@ -1,16 +1,14 @@ |
|
|
|
|
|
|
|
import assert from 'assert'; |
|
|
|
import expressSession, { |
|
|
|
import expressSession, { |
|
|
|
SessionData, |
|
|
|
SessionData, |
|
|
|
Store as BaseSessionStore, |
|
|
|
Store as BaseSessionStore, |
|
|
|
} from 'express-session'; |
|
|
|
} from 'express-session'; |
|
|
|
|
|
|
|
|
|
|
|
import { |
|
|
|
import { DELETED } from './lib/consts'; |
|
|
|
awrite, |
|
|
|
|
|
|
|
dbQuery, |
|
|
|
import { getLocalHostUUID, query, timestamp, write } from './lib/accessModule'; |
|
|
|
getLocalHostUUID, |
|
|
|
|
|
|
|
timestamp, |
|
|
|
|
|
|
|
} from './lib/accessModule'; |
|
|
|
|
|
|
|
import { getSessionSecret } from './lib/getSessionSecret'; |
|
|
|
import { getSessionSecret } from './lib/getSessionSecret'; |
|
|
|
import { stderr, stdout, stdoutVar, uuidgen } from './lib/shell'; |
|
|
|
import { stderr, stdout, stdoutVar, uuid } from './lib/shell'; |
|
|
|
|
|
|
|
|
|
|
|
const DEFAULT_COOKIE_ORIGINAL_MAX_AGE = 3600000; |
|
|
|
const DEFAULT_COOKIE_ORIGINAL_MAX_AGE = 3600000; |
|
|
|
|
|
|
|
|
|
|
@ -19,38 +17,33 @@ export class SessionStore extends BaseSessionStore { |
|
|
|
super(options); |
|
|
|
super(options); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public destroy( |
|
|
|
public async destroy( |
|
|
|
sid: string, |
|
|
|
sid: string, |
|
|
|
done?: ((err?: unknown) => void) | undefined, |
|
|
|
done?: ((err?: unknown) => void) | undefined, |
|
|
|
): void { |
|
|
|
): Promise<void> { |
|
|
|
stdout(`Destroy session ${sid}`); |
|
|
|
stdout(`Destroy session ${sid}`); |
|
|
|
|
|
|
|
|
|
|
|
try { |
|
|
|
try { |
|
|
|
awrite(`DELETE FROM sessions WHERE session_uuid = '${sid}';`, { |
|
|
|
const wcode = await write( |
|
|
|
onClose({ wcode }) { |
|
|
|
`UPDATE sessions SET session_salt = '${DELETED}' WHERE session_uuid = '${sid}';`, |
|
|
|
if (wcode !== 0) { |
|
|
|
); |
|
|
|
stderr( |
|
|
|
|
|
|
|
`SQL script failed during destroy session ${sid}; code: ${wcode}`, |
|
|
|
assert(wcode === 0, `Write exited with code ${wcode}`); |
|
|
|
); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
onError(error) { |
|
|
|
|
|
|
|
stderr( |
|
|
|
|
|
|
|
`Failed to complete DB write in destroy session ${sid}; CAUSE: ${error}`, |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
} catch (error) { |
|
|
|
} catch (error) { |
|
|
|
|
|
|
|
stderr( |
|
|
|
|
|
|
|
`Failed to complete DB write in destroy session ${sid}; CAUSE: ${error}`, |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
return done?.call(null, error); |
|
|
|
return done?.call(null, error); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return done?.call(null); |
|
|
|
return done?.call(null); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public get( |
|
|
|
public async get( |
|
|
|
sid: string, |
|
|
|
sid: string, |
|
|
|
done: (err: unknown, session?: SessionData | null | undefined) => void, |
|
|
|
done: (err: unknown, session?: SessionData | null | undefined) => void, |
|
|
|
): void { |
|
|
|
): Promise<void> { |
|
|
|
stdout(`Get session ${sid}`); |
|
|
|
stdout(`Get session ${sid}`); |
|
|
|
|
|
|
|
|
|
|
|
let rows: [ |
|
|
|
let rows: [ |
|
|
@ -60,7 +53,7 @@ export class SessionStore extends BaseSessionStore { |
|
|
|
][]; |
|
|
|
][]; |
|
|
|
|
|
|
|
|
|
|
|
try { |
|
|
|
try { |
|
|
|
rows = dbQuery( |
|
|
|
rows = await query( |
|
|
|
`SELECT
|
|
|
|
`SELECT
|
|
|
|
s.session_uuid, |
|
|
|
s.session_uuid, |
|
|
|
u.user_uuid, |
|
|
|
u.user_uuid, |
|
|
@ -69,7 +62,7 @@ export class SessionStore extends BaseSessionStore { |
|
|
|
JOIN users AS u |
|
|
|
JOIN users AS u |
|
|
|
ON s.session_user_uuid = u.user_uuid |
|
|
|
ON s.session_user_uuid = u.user_uuid |
|
|
|
WHERE s.session_uuid = '${sid}';`,
|
|
|
|
WHERE s.session_uuid = '${sid}';`,
|
|
|
|
).stdout; |
|
|
|
); |
|
|
|
} catch (queryError) { |
|
|
|
} catch (queryError) { |
|
|
|
return done(queryError); |
|
|
|
return done(queryError); |
|
|
|
} |
|
|
|
} |
|
|
@ -90,20 +83,18 @@ export class SessionStore extends BaseSessionStore { |
|
|
|
maxAge: cookieMaxAge, |
|
|
|
maxAge: cookieMaxAge, |
|
|
|
originalMaxAge: DEFAULT_COOKIE_ORIGINAL_MAX_AGE, |
|
|
|
originalMaxAge: DEFAULT_COOKIE_ORIGINAL_MAX_AGE, |
|
|
|
}, |
|
|
|
}, |
|
|
|
passport: { |
|
|
|
passport: { user: userUuid }, |
|
|
|
user: userUuid, |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
return done(null, data); |
|
|
|
return done(null, data); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public set( |
|
|
|
public async set( |
|
|
|
sid: string, |
|
|
|
sid: string, |
|
|
|
session: SessionData, |
|
|
|
session: SessionData, |
|
|
|
done?: ((err?: unknown) => void) | undefined, |
|
|
|
done?: ((err?: unknown) => void) | undefined, |
|
|
|
): void { |
|
|
|
): Promise<void> { |
|
|
|
stdout(`Set session ${sid}`); |
|
|
|
stdoutVar({ session }, `Set session ${sid}`); |
|
|
|
|
|
|
|
|
|
|
|
const { |
|
|
|
const { |
|
|
|
passport: { user: userUuid }, |
|
|
|
passport: { user: userUuid }, |
|
|
@ -113,7 +104,7 @@ export class SessionStore extends BaseSessionStore { |
|
|
|
const localHostUuid = getLocalHostUUID(); |
|
|
|
const localHostUuid = getLocalHostUUID(); |
|
|
|
const modifiedDate = timestamp(); |
|
|
|
const modifiedDate = timestamp(); |
|
|
|
|
|
|
|
|
|
|
|
awrite( |
|
|
|
const wcode = await write( |
|
|
|
`INSERT INTO
|
|
|
|
`INSERT INTO
|
|
|
|
sessions ( |
|
|
|
sessions ( |
|
|
|
session_uuid, |
|
|
|
session_uuid, |
|
|
@ -131,56 +122,39 @@ export class SessionStore extends BaseSessionStore { |
|
|
|
'${modifiedDate}' |
|
|
|
'${modifiedDate}' |
|
|
|
) |
|
|
|
) |
|
|
|
ON CONFLICT (session_uuid) |
|
|
|
ON CONFLICT (session_uuid) |
|
|
|
DO UPDATE SET session_host_uuid = '${localHostUuid}', |
|
|
|
DO UPDATE SET modified_date = '${modifiedDate}';`,
|
|
|
|
modified_date = '${modifiedDate}';`,
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
onClose: ({ wcode }) => { |
|
|
|
|
|
|
|
if (wcode !== 0) { |
|
|
|
|
|
|
|
stderr( |
|
|
|
|
|
|
|
`SQL script failed during set session ${sid}; code: ${wcode}`, |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
onError: (error) => { |
|
|
|
|
|
|
|
stderr( |
|
|
|
|
|
|
|
`Failed to complete DB write in set session ${sid}; CAUSE: ${error}`, |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
); |
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assert(wcode === 0, `Write exited with code ${wcode}`); |
|
|
|
} catch (error) { |
|
|
|
} catch (error) { |
|
|
|
|
|
|
|
stderr( |
|
|
|
|
|
|
|
`Failed to complete DB write in set session ${sid}; CAUSE: ${error}`, |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
return done?.call(null, error); |
|
|
|
return done?.call(null, error); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return done?.call(null); |
|
|
|
return done?.call(null); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public touch( |
|
|
|
public async touch( |
|
|
|
sid: string, |
|
|
|
sid: string, |
|
|
|
session: SessionData, |
|
|
|
session: SessionData, |
|
|
|
done?: ((err?: unknown) => void) | undefined, |
|
|
|
done?: ((err?: unknown) => void) | undefined, |
|
|
|
): void { |
|
|
|
): Promise<void> { |
|
|
|
stdout(`Touch session ${sid}`); |
|
|
|
stdoutVar({ session }, `Touch session ${sid}`); |
|
|
|
|
|
|
|
|
|
|
|
try { |
|
|
|
try { |
|
|
|
awrite( |
|
|
|
const wcode = await write( |
|
|
|
`UPDATE sessions SET modified_date = '${timestamp()}' WHERE session_uuid = '${sid}';`, |
|
|
|
`UPDATE sessions SET modified_date = '${timestamp()}' WHERE session_uuid = '${sid}';`, |
|
|
|
{ |
|
|
|
|
|
|
|
onClose: ({ wcode }) => { |
|
|
|
|
|
|
|
if (wcode !== 0) { |
|
|
|
|
|
|
|
stderr( |
|
|
|
|
|
|
|
`SQL script failed during touch session ${sid}; code: ${wcode}`, |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
onError: (error) => { |
|
|
|
|
|
|
|
stderr( |
|
|
|
|
|
|
|
`Failed to complete DB write in touch session ${sid}; CAUSE: ${error}`, |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
); |
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assert(wcode === 0, `Write exited with code ${wcode}`); |
|
|
|
} catch (error) { |
|
|
|
} catch (error) { |
|
|
|
|
|
|
|
stderr( |
|
|
|
|
|
|
|
`Failed to complete DB write in touch session ${sid}; CAUSE: ${error}`, |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
return done?.call(null, error); |
|
|
|
return done?.call(null, error); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -201,19 +175,18 @@ export class SessionStore extends BaseSessionStore { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const session = expressSession({ |
|
|
|
export default (async () => |
|
|
|
cookie: { maxAge: DEFAULT_COOKIE_ORIGINAL_MAX_AGE }, |
|
|
|
expressSession({ |
|
|
|
genid: ({ path }) => { |
|
|
|
cookie: { maxAge: DEFAULT_COOKIE_ORIGINAL_MAX_AGE }, |
|
|
|
const sid = uuidgen('--random').trim(); |
|
|
|
genid: ({ path }) => { |
|
|
|
|
|
|
|
const sid = uuid(); |
|
|
|
stdout(`Generated session identifier ${sid}; request.path=${path}`); |
|
|
|
|
|
|
|
|
|
|
|
stdout(`Generated session identifier ${sid}; request.path=${path}`); |
|
|
|
return sid; |
|
|
|
|
|
|
|
}, |
|
|
|
return sid; |
|
|
|
resave: false, |
|
|
|
}, |
|
|
|
saveUninitialized: false, |
|
|
|
resave: false, |
|
|
|
secret: getSessionSecret(), |
|
|
|
saveUninitialized: false, |
|
|
|
store: new SessionStore(), |
|
|
|
secret: await getSessionSecret(), |
|
|
|
}); |
|
|
|
store: new SessionStore(), |
|
|
|
|
|
|
|
}))(); |
|
|
|
export default session; |
|
|
|
|
|
|
|