Skip to content
Open
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
23 changes: 12 additions & 11 deletions kbase-extension/static/kbase/js/api/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,18 @@
},
};

const DEFAULT_TOKEN_LIFE = 14 * 24 * 60 * 60 * 1000; // millis

/**
* Meant for managing auth or session cookies (mainly auth cookies as set by
* a developer working locally - which is why this is very very simple).
* Get a cookie "object" (key-value pairs) as input.
* If it's missing name or value, does nothing.
* Default expiration time is 14 days.
* domain, expires, and max-age are optional
* expires is expected to be the timestamp (ms since epoch) it will expire
* If it's missing name, does nothing.
* expires is REQUIRED and is expected to be the timestamp (ms since epoch)
* at which the cookie expires. It must be sourced from the auth service
* (a token's real expiration) rather than a hardcoded client-side lifetime,
* so the cookie always tracks the actual token lifetime.
* domain and max-age are optional.
* default fields are:
* - path = '/'
* - expires = now + 14 days
* @param {object} cookie
* - has the cookie keys: name, value, path, expires, max-age, domain
* - adds secure=true, samesite=Lax for KBase use.
Expand All @@ -47,16 +46,18 @@
if (!cookie.name) {
return;
}
if (!Number.isInteger(cookie.expires)) {
throw new Error(

Check warning on line 50 in kbase-extension/static/kbase/js/api/auth.js

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

`new Error()` is too unspecific for a type check. Use `new TypeError()` instead.

See more on https://sonarcloud.io/project/issues?id=kbase_narrative&issues=AZ8-HzPojjqmKh2C1_Ay&open=AZ8-HzPojjqmKh2C1_Ay&pullRequest=3732
'setCookie requires an integer `expires` (ms since epoch) sourced from the auth service'
);
}
const name = encodeURIComponent(cookie.name);
const value = encodeURIComponent(cookie.value || '');
const props = {
expires: Date.now() + DEFAULT_TOKEN_LIFE, // gets translated to GMT string
expires: cookie.expires, // gets translated to GMT string
path: '/',
samesite: 'Lax',
};
if (Number.isInteger(cookie.expires)) {
props.expires = cookie.expires;
}

// Default to secure cookies global setting if not specified.
if (typeof cookie.secure === 'undefined') {
Expand Down
17 changes: 15 additions & 2 deletions kbase-extension/static/kbase/js/narrativeLogin.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,14 +80,27 @@ define([
buttons: [
$('<a type="button" class="btn btn-default">')
.append('OK')
.click(() => {
dialog.hide();
.click(async () => {
const newToken = $inputField.val();
// Look up the token's real expiration from the auth service
// rather than assuming a fixed lifetime, so the dev cookie
// matches the actual token lifetime.
let tokenInfo;
try {
tokenInfo = await authClient.getTokenInfo(newToken);
} catch (error) {
alert(
'That auth token could not be validated against the auth service. Please check the token and try again.'
);
return;
}
dialog.hide();
authClient.setCookie({
name: 'kbase_session',
value: newToken,
domain: 'localhost',
secure: false,
expires: tokenInfo.expires,
});
location.reload();
}),
Expand Down
1 change: 1 addition & 0 deletions test/unit/spec/api/authSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,7 @@ define(['api/auth', 'narrativeConfig', 'uuid', 'testUtil'], (Auth, Config, Uuid,
name: backupCookieName,
value: backupCookieValue,
domain: 'localhost',
expires: Date.now() + 14 * 1000 * 60 * 60 * 24,
});

// The backup cookie should be set.
Expand Down
Loading