Skip to content

Commit b5058b6

Browse files
authored
fix: cert expire refresh (#93)
1 parent db51752 commit b5058b6

File tree

7 files changed

+155
-6
lines changed

7 files changed

+155
-6
lines changed

src/channel/channel.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,7 @@ module.exports = class ZitiChannel {
377377

378378
case edge_protocol.content_type.StateClosed:
379379

380-
this._ctx.logger.warn("conn[%d] failed to connect", conn.getId());
380+
this._ctx.logger.warn("conn[%d] failed to connect on ch[%d]", conn.getId(), this.getId());
381381
conn.setState(edge_protocol.conn_state.Closed);
382382
break;
383383

@@ -1001,7 +1001,7 @@ module.exports = class ZitiChannel {
10011001
if (len > 2000) {
10021002
len = 2000;
10031003
}
1004-
this._ctx.logger.debug("recv <- unencrypted_data (first 2000): %s", m1.substring(0, len));
1004+
this._ctx.logger.trace("recv <- unencrypted_data (first 2000): %s", m1.substring(0, len));
10051005
} catch (e) { /* nop */ }
10061006

10071007
bodyView = unencrypted_data.message;
@@ -1011,7 +1011,7 @@ module.exports = class ZitiChannel {
10111011
len = 2000;
10121012
}
10131013
let dbgStr = String.fromCharCode.apply(null, bodyView).substring(0, len);
1014-
this._ctx.logger.debug("recv <- data (first 2000): %s", dbgStr);
1014+
this._ctx.logger.trace("recv <- data (first 2000): %s", dbgStr);
10151015

10161016
//temp debugging
10171017
// if (dbgStr.includes("var openMe = (window.parent")) {

src/client.js

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -548,7 +548,7 @@ zitiFetch = async ( url, opts ) => {
548548
});
549549

550550
_internal_generateKeyPair();
551-
_internal_isIdentityPresent();
551+
let identyPresent = await _internal_isIdentityPresent();
552552

553553
// We only want to intercept fetch requests that target the Ziti HTTP Agent
554554
var regex = new RegExp( zitiConfig.httpAgent.self.host, 'g' );
@@ -572,6 +572,12 @@ zitiFetch = async ( url, opts ) => {
572572
reject( err );
573573
});
574574
});
575+
576+
// Trigger a page reload now that we have a fresh identity
577+
updb.relodingPage();
578+
setTimeout(function(){
579+
window.location.reload();
580+
}, 500);
575581
}
576582

577583
})
@@ -864,6 +870,14 @@ _internal_isIdentityPresent = async ( ) => {
864870
let cert = await ls.getWithExpiry(zitiConstants.get().ZITI_IDENTITY_CERT);
865871
if (!isNull( cert ) && !isUndefined( cert )) {
866872
identyPresent = true;
873+
} else {
874+
// If cert expired, purge any session data we might have
875+
await ls.removeItem( zitiConstants.get().ZITI_API_SESSION_TOKEN );
876+
await ls.removeItem( zitiConstants.get().ZITI_NETWORK_SESSIONS );
877+
// and also reset the channels
878+
if (!isUndefined(ziti._ctx)) {
879+
ziti._ctx.closeAllChannels();
880+
}
867881
}
868882
}
869883

@@ -1026,11 +1040,18 @@ if (!zitiConfig.serviceWorker.active) {
10261040
/**
10271041
* Service Worker registration
10281042
*/
1029-
navigator.serviceWorker.register('ziti-sw.js', {scope: './'} ).then( function() {
1043+
navigator.serviceWorker.register('ziti-sw.js', {scope: './'} ).then( function( reg ) {
10301044

10311045
if (navigator.serviceWorker.controller) {
10321046
// If .controller is set, then this page is being actively controlled by our service worker.
10331047
console.log('The Ziti service worker is now registered.');
1048+
1049+
// (function checkForUpdatedServiceWorker() {
1050+
// console.log('checking for updated service worker.');
1051+
// reg.update();
1052+
// setTimeout( checkForUpdatedServiceWorker, 1000 * 60 * 30 );
1053+
// })();
1054+
10341055
} else {
10351056
// If .controller isn't set, then prompt the user to reload the page so that the service worker can take
10361057
// control. Until that happens, the service worker's fetch handler won't be used.

src/context/context.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1028,7 +1028,7 @@ ZitiContext.prototype.getControllerChannel = function() {
10281028
/**
10291029
* Remain in lazy-sleepy loop until specified channel is connected.
10301030
*
1031-
* @param {*} conn
1031+
* @param {*} channel
10321032
*/
10331033
ZitiContext.prototype.awaitChannelConnectComplete = function(ch) {
10341034
return new Promise((resolve) => {
@@ -1086,6 +1086,9 @@ ZitiContext.prototype.closeChannelByEdgeRouter = function( edgeRouter ) {
10861086
this._channels.delete( edgeRouter );
10871087
}
10881088

1089+
ZitiContext.prototype.closeAllChannels = function() {
1090+
this._channels = new Map();
1091+
}
10891092

10901093
ZitiContext.prototype.getServiceIdByDNSHostName = function(name) {
10911094
let service_id = result(find(this._services, function(obj) {

src/enroll/enroller.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,17 @@ ZitiEnroller.prototype.createEphemeralCert = async function() {
388388
let expiryTime = pkiUtil.getExpiryTimeFromCertificate(certificate);
389389
let expiryDate = new Date(expiryTime);
390390

391+
//
392+
let becomesUsableTime = pkiUtil.getBecomesUsableTimeFromCertificate(certificate);
393+
let becomesUsableTimeString = pkiUtil.getBecomesUsableStringFromCertificate(certificate);
394+
let now = new Date();
395+
let nowTime = now.getTime();
396+
self.logger.info('controllerClient.createCurrentApiSessionCertificate returned cert with NotBefore time [%o][%o], it is now [%o][%o], difference of [%o]', becomesUsableTime, becomesUsableTimeString, nowTime, now, (nowTime-becomesUsableTime));
397+
if (nowTime < becomesUsableTime) {
398+
self.logger.error('controllerClient.createCurrentApiSessionCertificate returned cert with NotBefore IN THE FUTURE', becomesUsableTimeString);
399+
}
400+
//
401+
391402
self.logger.debug('controllerClient.createCurrentApiSessionCertificate returned cert with expiryTime: [%o] expiryDate:[%o]', expiryTime, expiryDate);
392403

393404
await ls.setWithExpiry(zitiConstants.get().ZITI_IDENTITY_CERT, certPEM, expiryTime);
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
Copyright 2019-2020 Netfoundry, Inc.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
https://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
18+
const MicroModal = require('micromodal');
19+
const isNull = require('lodash.isnull');
20+
const isUndefined = require('lodash.isundefined');
21+
22+
/**
23+
* Inject HTML needed for the 'Reloading Page' Modal.
24+
*
25+
*/
26+
exports.inject = () => {
27+
28+
let self = this;
29+
30+
htmlString = `
31+
<div class="modal micromodal-slide" id="ziti-reloadingpage-modal" aria-hidden="true">
32+
<div class="wrapper">
33+
<form class="form-signin" name="zitireloadingpage" id="ziti-reloadingpage-form">
34+
<header class="modal__header">
35+
<h2 class="modal__title" id="modal-1-title">
36+
<img src="https://ziti-logo.s3.amazonaws.com/ziti-logo_avatar.png" width=25 >
37+
<span>
38+
Now Reloading App
39+
</span>
40+
</h2>
41+
</header>
42+
<div style="text-align: center; padding-top: 15px;">
43+
<span id="ziti-keypair-error" style="color: #e80853; font-weight: 800; font-size: 0.9em;"></span>
44+
</div>
45+
<div style="text-align: center; padding-top: 15px;">
46+
<span id="ziti-keypair-progress" style="color: #145fe9; font-weight: 800; font-size: 0.9em;">Please Stand By</span>
47+
</div>
48+
</form>
49+
</div>
50+
</div>
51+
`;
52+
53+
if (isNull(document.body) || isUndefined(document.body)) {
54+
var body = document.createElement("body");
55+
document.documentElement.appendChild(body);
56+
}
57+
58+
document.body.insertAdjacentHTML('afterbegin', htmlString);
59+
}
60+

src/updb/updb.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ let updbModalHTML;
4343
if (typeof window !== 'undefined') {
4444
identityModalCSS = require('../ui/identity_modal/css');
4545
updbModalHTML = require('../ui/identity_modal/updb_prompt_html');
46+
reloadingpageModalHTML = require('../ui/identity_modal/reloading_page_html');
4647
}
4748

4849

@@ -197,6 +198,39 @@ ZitiUPDB.prototype.promptForCreds = async function() {
197198
}
198199

199200

201+
/**
202+
* Display 'Reloading Page'
203+
*
204+
* @params {nothing}
205+
* @returns {nothing}
206+
*/
207+
ZitiUPDB.prototype.relodingPage = function() {
208+
209+
let self = this;
210+
211+
if (typeof window !== 'undefined') {
212+
213+
identityModalCSS.inject();
214+
reloadingpageModalHTML.inject();
215+
216+
MicroModal.init({
217+
onShow: modal => console.info(`${modal.id} is shown`), // [1]
218+
onClose: modal => console.info(`${modal.id} is hidden`), // [2]
219+
openTrigger: 'ziti-data-micromodal-trigger', // [3]
220+
closeTrigger: 'data-custom-close', // [4]
221+
openClass: 'is-open', // [5]
222+
disableScroll: true, // [6]
223+
disableFocus: false, // [7]
224+
awaitOpenAnimation: false, // [8]
225+
awaitCloseAnimation: true, // [9]
226+
debugMode: false // [10]
227+
});
228+
229+
MicroModal.show('ziti-reloadingpage-modal');
230+
}
231+
}
232+
233+
200234
/**
201235
* Prompt the user for their creds
202236
*

src/utils/pki.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,3 +123,23 @@ exports.getExpiryTimeFromCertificate = (certificate) => {
123123
exports.getExpiryStringFromCertificate = (certificate) => {
124124
return certificate.notAfter.toSchema().toDate().toString();
125125
}
126+
127+
128+
/**
129+
* Return time (in millis) for when Certificate becomes usable
130+
*
131+
* @param {Buffer} certificateBuffer
132+
*/
133+
exports.getBecomesUsableTimeFromCertificate = (certificate) => {
134+
return certificate.notBefore.toSchema().toDate().getTime();
135+
}
136+
137+
138+
/**
139+
* Return time (human-readable) for when Certificate becomes usable
140+
*
141+
* @param {Buffer} certificateBuffer
142+
*/
143+
exports.getBecomesUsableStringFromCertificate = (certificate) => {
144+
return certificate.notBefore.toSchema().toDate().toString();
145+
}

0 commit comments

Comments
 (0)