Skip to content
This repository was archived by the owner on Apr 17, 2025. It is now read-only.

Commit bad61c7

Browse files
authored
Lazy Load Secrets (#47)
1 parent 8273451 commit bad61c7

File tree

3 files changed

+139
-44
lines changed

3 files changed

+139
-44
lines changed

app/elements/search-page.html

Lines changed: 73 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -61,22 +61,45 @@
6161
font-size: 16px;
6262
font-weight: bold;
6363
}
64+
paper-button {
65+
text-transform: none;
66+
}
67+
paper-button.accent {
68+
background-color: var(--accent-color);
69+
color: white;
70+
}
71+
paper-button[disabled] {
72+
color: #a7a9ab !important;
73+
background: transparent;
74+
border: 2px solid #a7a9ab !important;
75+
font-weight: 700
76+
}
6477
a {
6578
text-decoration: none;
66-
color: black;
79+
color: black;
6780
}
6881
</style>
6982

7083
<template>
7184
<div id="list">
72-
<div style="float: right">
85+
<div style="float: right; padding-top: 14px;">
7386
<paper-checkbox checked="{{fuzzy}}" on-tap="_showResults">
7487
Fuzzy Search
7588
<paper-tooltip position="top" animation-delay="0" style="width: 175px;">Approximate string matching. <br />Ex: "ysph" would match "symphony"</paper-tooltip>
7689
</paper-checkbox>
7790
</div>
91+
<div style="float: left; padding-top: 9px;">
92+
<h2 style="margin-top: 0px;">Secrets</h2>
93+
</div>
94+
<div style="float: left; padding-left: 20px" class="vertical">
95+
<paper-button raised class="accent" on-tap="_indexAllSecrets" disabled="{{indexAllSecrets}}">
96+
<iron-icon icon="file-download" style="padding-right: 7px;"></iron-icon>
97+
Index all secrets
98+
<paper-tooltip position="top" animation-delay="0" style="width: 300px;">Currently only searching secrets that have been viewed. <br />Click to search all accessible secrets</paper-tooltip>
99+
</paper-button>
100+
</div>
101+
<div style="height: 60px;"></div>
78102

79-
<h2 style="margin-top: 0px;">Secrets</h2>
80103
<template is="dom-repeat" items="[[results]]" filter="_filterFolders">
81104
<a href="secret/[[item.location]]">
82105
<div class="pad">
@@ -95,45 +118,54 @@ <h2 style="margin-top: 0px;">Secrets</h2>
95118
is: 'search-page',
96119
properties: {
97120
secrets: Array,
98-
query: {
99-
type: String,
100-
notify: true,
101-
observer: '_showResults'
102-
},
103-
results: {
104-
type: Array,
105-
value: []
106-
},
107-
fuzzy: {
108-
type: Boolean,
109-
value: true
110-
}
121+
query: {
122+
type: String,
123+
notify: true,
124+
observer: '_showResults'
125+
},
126+
results: {
127+
type: Array,
128+
value: []
129+
},
130+
fuzzy: {
131+
type: Boolean,
132+
value: true
133+
},
134+
indexAllSecrets: {
135+
type: Boolean,
136+
notify: true
137+
}
111138
},
112-
_showResults: function() {
113-
if (this.fuzzy) {
114-
var options = {
115-
shouldSort: true,
116-
threshold: 0.6,
117-
location: 0,
118-
distance: 100,
119-
maxPatternLength: 100,
120-
minMatchCharLength: 1,
121-
tokenize: true,
122-
matchAllTokens: true,
123-
keys: [ "location" ]
124-
};
125-
var fuse = new Fuse(this.secrets, options); // "list" is the item array
126-
this.results = fuse.search(this.query.replace(' ', '_'));
127-
} else {
128-
this.results = [];
129-
for (var i = 0; i < this.secrets.length; i++) {
130-
if (this.secrets[i].location.includes(this.query.toLowerCase().replace(' ', '_'))) this.push('results', this.secrets[i]);
131-
}
132-
}
133-
},
134-
_filterFolders: function(item) {
135-
return item.type != 'folder';
136-
},
139+
_indexAllSecrets: function() {
140+
this.indexAllSecrets = true;
141+
},
142+
_showResults: function() {
143+
this.debounce('newcharacter', function() {
144+
if (this.fuzzy) {
145+
var options = {
146+
shouldSort: true,
147+
threshold: 0.6,
148+
location: 0,
149+
distance: 100,
150+
maxPatternLength: 100,
151+
minMatchCharLength: 1,
152+
tokenize: true,
153+
matchAllTokens: true,
154+
keys: [ "location" ]
155+
};
156+
var fuse = new Fuse(this.secrets, options); // "list" is the item array
157+
this.results = fuse.search(this.query.replace(' ', '_'));
158+
} else {
159+
this.results = [];
160+
for (var i = 0; i < this.secrets.length; i++) {
161+
if (this.secrets[i].location.includes(this.query.toLowerCase().replace(' ', '_'))) this.push('results', this.secrets[i]);
162+
}
163+
}
164+
}, 600);
165+
},
166+
_filterFolders: function(item) {
167+
return item.type != 'folder';
168+
},
137169
});
138170
})();
139171
</script>

app/elements/secrets-init.html

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,26 @@
5252
value: [],
5353
notify: true
5454
},
55+
indexAllSecrets: {
56+
type: Boolean,
57+
value: false,
58+
observer: '_watchIndexAllSecrets',
59+
notify: true
60+
},
61+
deferredRequests: {
62+
type: Array,
63+
value: [],
64+
notify: true
65+
},
66+
completedRequests: {
67+
type: Array,
68+
value: [],
69+
notify: true
70+
},
71+
folderRoute: {
72+
type: String,
73+
observer: '_watchFolderRoute'
74+
},
5575
policyRequests: {
5676
type: Array,
5777
value: []
@@ -79,6 +99,9 @@
7999
// Todo: Check for list permissions on folder before executing
80100
// Execute list on a folder
81101
if (!key.startsWith('sys') && !key.startsWith('cubbyhole')) {
102+
// Track completed requests
103+
this.push('completedRequests', key);
104+
82105
this.listSecretsURL = app.url + 'v1/' + key.replace('*', '') + '?list=true';
83106
this.push('listRequests', this.$.listSecrets.generateRequest());
84107
}
@@ -88,7 +111,12 @@
88111
var base = e.detail.url.replace(app.url + 'v1/', '').replace('?list=true','');
89112
var data = e.detail.response.data.keys;
90113
for (var i = 0; i < data.length; i++) {
91-
if (data[i].endsWith('/')) this._listSecrets(base + data[i]);
114+
if (data[i].endsWith('/')) {
115+
if (base.split('/').length <= 3) this._listSecrets(base + data[i]);
116+
else if (this.indexAllSecrets) this._listSecrets(base + data[i]);
117+
else if (!this.completedRequests.includes(base + data[i])) this.push('deferredRequests', base + data[i])
118+
else this._listSecrets(base + data[i]);
119+
}
92120
else this._addSecret(base + data[i]);
93121
}
94122
// Add containing folder to secrets array
@@ -98,6 +126,38 @@
98126
_listError: function(e) {
99127
// No access to list on this folder
100128
},
129+
_watchIndexAllSecrets: function() {
130+
if (this.indexAllSecrets) {
131+
this.loading = true;
132+
this.deferredRequests.forEach(function(route) {
133+
this._listSecrets(route);
134+
}, this);
135+
this.deferredRequests = [];
136+
}
137+
},
138+
_watchFolderRoute: function() {
139+
var path = this.folderRoute;
140+
var parts = this.folderRoute.split('/');
141+
// Lookup the backend to check for v2 secret engine
142+
for (var i in this.backends) {
143+
if (this.backends[i].name == parts[0]) {
144+
// If v2 secret backend, replace 'data' with 'metadata'
145+
if (this.backends[i].type === '2') path = path.replace(this.backends[i].name + '/data', this.backends[i].name + '/metadata');
146+
break;
147+
}
148+
}
149+
var matches = this.deferredRequests.filter(function(value) {
150+
if (value.includes(path + '/')) value = value.replace(path + '/', '');
151+
return value.split('/').length == 2
152+
});
153+
matches.forEach(function(route) {
154+
this._listSecrets(route);
155+
this.loading = true;
156+
var index = this.deferredRequests.indexOf(route);
157+
if (index > -1) this.deferredRequests.splice(index, 1);
158+
}, this);
159+
// if (this.folderRoute in this.deferredRequests) this._listSecrets(this.folderRoute);
160+
},
101161
_addSecret: function(location) {
102162
var parts = location.split('/');
103163
if (!['sys', 'auth', 'cubbyhole'].includes(parts[0])) {
@@ -294,6 +354,9 @@
294354
this.policyRequests = [];
295355
this.listRequests = [];
296356
this.secrets = [];
357+
this.deferredRequests = [];
358+
this.completedRequests = [];
359+
this.indexAllSecrets = false;
297360
}
298361
}
299362
});

app/index.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
<div id="blocker"></div> <!-- blocker: an element to obscure background-loading content at load time. -->
3434
<login-form status="{{status}}" username="{{u}}" url="{{url}}" header="{{header}}" login-response="{{loginResponse}}" loading="{{loading}}" backends="{{backends}}"></login-form>
3535
<login-status id="login-status" status="{{status}}" url="{{url}}" header="{{header}}"></login-status>
36-
<secrets-init status="{{status}}" header="{{header}}" login-response="{{loginResponse}}" secrets="{{secrets}}" access="{{access}}" loading="{{loading}}" backends="{{backends}}"></secrets-init>
36+
<secrets-init status="{{status}}" header="{{header}}" deferred-requests="{{deferredRequests}}" completed-requests="{{completedRequests}}" folder-route="{{folderRoute}}" login-response="{{loginResponse}}" secrets="{{secrets}}" access="{{access}}" loading="{{loading}}" backends="{{backends}}" index-all-secrets="{{indexAllSecrets}}"></secrets-init>
3737

3838
<paper-drawer-panel id="paperDrawerPanel" drawer-width="{{drawerWidth}}">
3939
<!-- Drawer Area -->
@@ -123,7 +123,7 @@
123123
</section>
124124

125125
<section data-route="search" style="height: 100%">
126-
<search-page secrets="{{secrets}}" query="{{query}}"></search-page>
126+
<search-page secrets="{{secrets}}" query="{{query}}" index-all-secrets="{{indexAllSecrets}}"></search-page>
127127
</section>
128128
</iron-pages>
129129
</div>

0 commit comments

Comments
 (0)