Skip to content

Commit

Permalink
Merge pull request #1 from uwcirg/ltt-updates
Browse files Browse the repository at this point in the history
Ltt updates
  • Loading branch information
daniellrgn authored Mar 26, 2024
2 parents 5484c04 + a7a08eb commit d44b10e
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 15 deletions.
3 changes: 3 additions & 0 deletions server/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
FROM denoland/deno:1.25.2
EXPOSE 8000
WORKDIR /app
USER root
RUN apt-get update && \
apt-get install -y sqlite3
USER deno
COPY --chown=deno deps.ts .
RUN deno cache deps.ts
Expand Down
3 changes: 1 addition & 2 deletions server/config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
const defaultEnv = {
// PUBLIC_URL: 'http://localhost:8000',
PUBLIC_URL: 'https://smart-health-links-server.cirg.washington.edu',
PUBLIC_URL: 'https://shl-server.inform.dev.cirg.uw.edu',
EMBEDDED_LENGTH_MAX: 10_000
};

Expand Down
69 changes: 59 additions & 10 deletions server/db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,33 +38,42 @@ async function updateAccessToken(endpoint: types.HealthLinkEndpoint) {

export const DbLinks = {
create(config: types.HealthLinkConfig) {
let { userId, sessionId, ...configSansUserAndSession } = config;

const link = {
config,
config: configSansUserAndSession,
id: randomStringWithEntropy(32),
userId: userId,
sessionId: sessionId,
managementToken: randomStringWithEntropy(32),
created: new Date().getTime() / 1000,
active: true,
};
db.query(
`INSERT INTO shlink (id, management_token, active, config_exp, config_passcode)
values (:id, :managementToken, :active, :exp, :passcode)`,
`INSERT INTO shlink (id, user_id, session_id, management_token, active, created, config_exp, config_passcode)
values (:id, :userId, :sessionId, :managementToken, :active, :created, :exp, :passcode)`,
{
id: link.id,
userId: link.userId,
sessionId: link.sessionId,
managementToken: link.managementToken,
active: link.active,
created: link.created,
exp: link.config.exp,
passcode: link.config.passcode,
},
}
);

return link;
},
updateConfig(shl: types.HealthLink) {
db.query(`UPDATE shlink set config_passcode=:passcode, config_exp=:exp where id=:id`,
updateConfig(linkId:string, config: types.HealthLinkConfig) {
db.query(`UPDATE shlink set config_passcode=:passcode, config_exp=:exp, session_id=:sessionId where id=:id`,
{
id: shl.id,
exp: shl.config.exp,
passcode: shl.config.passcode
})
id: linkId,
exp: config.exp,
passcode: config.passcode,
sessionId: config.sessionId
});
return true;
},
deactivate(shl: types.HealthLink) {
Expand All @@ -83,19 +92,48 @@ export const DbLinks = {
id: linkRow.id as string,
passcodeFailuresRemaining: linkRow.passcode_failures_remaining as number,
active: Boolean(linkRow.active) as boolean,
userId: linkRow.user_id as string,
sessionId: linkRow.session_id as string,
created: linkRow.created as string,
managementToken: linkRow.management_token as string,
config: {
exp: linkRow.config_exp as number,
passcode: linkRow.config_passcode as string,
},
};
},
getUserShl(userId: string): types.HealthLink | undefined {
try {
const linkRow = db
.prepareQuery(`SELECT * from shlink where user_id=? and active=1 order by created desc limit 1`)
.oneEntry([userId]);
return {
id: linkRow.id as string,
passcodeFailuresRemaining: linkRow.passcode_failures_remaining as number,
active: Boolean(linkRow.active) as boolean,
userId: linkRow.user_id as string,
sessionId: linkRow.session_id as string,
created: linkRow.created as string,
managementToken: linkRow.management_token as string,
config: {
exp: linkRow.config_exp as number,
passcode: linkRow.config_passcode as string,
},
};
} catch (e) {
console.warn(e);
return undefined;
}
},
getShlInternal(linkId: string): types.HealthLink {
const linkRow = db.prepareQuery(`SELECT * from shlink where id=?`).oneEntry([linkId]);
return {
id: linkRow.id as string,
passcodeFailuresRemaining: linkRow.passcode_failures_remaining as number,
active: Boolean(linkRow.active) as boolean,
userId: linkRow.user_id as string,
sessionId: linkRow.session_id as string,
created: linkRow.created as string,
managementToken: linkRow.management_token as string,
config: {
exp: linkRow.config_exp as number,
Expand Down Expand Up @@ -142,6 +180,17 @@ export const DbLinks = {

return true;
},
async deleteAllFiles(linkId: string) {

db.query(
`delete from shlink_file where shlink = :linkId`,
{
linkId
}
);

return true;
},
async addEndpoint(linkId: string, endpoint: types.HealthLinkEndpoint): Promise<string> {
const id = randomStringWithEntropy(32);

Expand Down
33 changes: 31 additions & 2 deletions server/routers/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,26 @@ export const shlApiRouter = new oak.Router()
})
.put('/shl/:shlId', async (context) => {
const managementToken = await context.request.headers.get('authorization')?.split(/bearer /i)[1]!;
const config = await context.request.body({ type: 'json' }).value;
const shl = db.DbLinks.getManagedShl(context.params.shlId, managementToken)!;
if (!shl) {
throw new Error(`Can't manage SHLink ` + context.params.shlId);
}
const updated = db.DbLinks.updateConfig(shl);
context.response.body = updated;
const updated = db.DbLinks.updateConfig(context.params.shlId, config);
if (!updated) {
return (context.response.status = 500);
}
const updatedShl = db.DbLinks.getManagedShl(context.params.shlId, managementToken);
delete updatedShl.managementToken
context.response.body = updatedShl;
})
.get('/user/:userId', async (context) => {
const shl = db.DbLinks.getUserShl(context.params.userId)!;
if (!shl) {
console.log(`Can't find SHLink for user ` + context.params.userId);
return;
}
context.response.body = shl;
})
.get('/shl/:shlId/file/:fileIndex', (context) => {
const ticket = manifestAccessTickets.get(context.request.url.searchParams.get('ticket')!);
Expand Down Expand Up @@ -152,6 +166,21 @@ export const shlApiRouter = new oak.Router()
added,
};
})
.delete('/shl/:shlId/file/all', async (context) => {
const managementToken = await context.request.headers.get('authorization')?.split(/bearer /i)[1]!;
const currentFileBody = await context.request.body({type: 'bytes'});

const shl = db.DbLinks.getManagedShl(context.params.shlId, managementToken);
if (!shl) {
throw new Error(`Can't manage SHLink ` + context.params.shlId);
}

const deleted = db.DbLinks.deleteAllFiles(shl.id);
context.response.body = {
...shl,
deleted,
}
})
.delete('/shl/:shlId/file', async (context) => {
const managementToken = await context.request.headers.get('authorization')?.split(/bearer /i)[1]!;
const currentFileBody = await context.request.body({type: 'bytes'});
Expand Down
3 changes: 3 additions & 0 deletions server/schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@ CREATE TABLE IF NOT EXISTS cas_item(

CREATE TABLE IF NOT EXISTS shlink(
id VARCHAR(43) PRIMARY KEY UNIQUE,
user_id VARCHAR(43) NOT NULL,
session_id VARCHAR(43) NOT NULL,
passcode_failures_remaining INTEGER DEFAULT(5),
config_passcode TEXT,
config_exp DATETIME,
created DATETIME,
active BOOLEAN NOT NULL DEFAULT(true),
management_token VARCHAR(43) NOT NULL
);
Expand Down
7 changes: 6 additions & 1 deletion server/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,18 @@ export interface HealthLinkEndpoint {
export interface HealthLinkConfig {
passcode?: string;
exp?: number;
userId?: string;
sessionId?: string;
}

export interface HealthLink {
config: HealthLinkConfig;
active: boolean;
id: string;
managementToken: string;
userId?: string;
sessionId?: string;
created: string;
managementToken?: string;
passcodeFailuresRemaining: number;
}

Expand Down

0 comments on commit d44b10e

Please sign in to comment.