ldap-rest 0.4.6 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/bin/sync-james.mjs +6 -2
  2. package/dist/bin/index.js +1 -1
  3. package/dist/config/args.js +1 -1
  4. package/dist/lib/auth/base.js +1 -1
  5. package/dist/lib/ldapSchema.js +1 -0
  6. package/dist/plugins/auth/authzPerRoute.js +1 -1
  7. package/dist/plugins/auth/rateLimit.js +1 -1
  8. package/dist/plugins/ldap/organizations.js +1 -1
  9. package/dist/plugins/ldap/raw.js +1 -0
  10. package/dist/plugins/twake/appAccountsApi.js +1 -1
  11. package/dist/plugins/weblogs.js +1 -1
  12. package/dist/src/bin/index.d.ts +112 -0
  13. package/dist/src/browser/ldap-browser/LdapBrowser.d.ts +52 -0
  14. package/dist/src/browser/ldap-browser/api/RawApiClient.d.ts +64 -0
  15. package/dist/src/browser/ldap-browser/components/EntryTree.d.ts +75 -0
  16. package/dist/src/browser/ldap-browser/components/EntryView.d.ts +56 -0
  17. package/dist/src/browser/ldap-browser/index.d.ts +9 -0
  18. package/dist/src/browser/ldap-browser/schema.d.ts +62 -0
  19. package/dist/src/browser/ldap-browser/types.d.ts +96 -0
  20. package/dist/src/config/args.d.ts +6 -0
  21. package/dist/src/lib/auth/base.d.ts +82 -1
  22. package/dist/src/lib/ldapSchema.d.ts +159 -0
  23. package/dist/src/plugins/ldap/raw.d.ts +251 -0
  24. package/dist/src/plugins/weblogs.d.ts +7 -0
  25. package/docs/client-development/browser/libraries.md +142 -1
  26. package/docs/usage/configuration.md +20 -0
  27. package/docs/usage/plugins/README.md +10 -9
  28. package/docs/usage/plugins/auth/README.md +57 -0
  29. package/docs/usage/plugins/auth/rate-limit.md +9 -0
  30. package/docs/usage/plugins/integrations/app-accounts.md +32 -0
  31. package/docs/usage/plugins/ldap/README.md +12 -0
  32. package/docs/usage/plugins/ldap/raw.md +226 -0
  33. package/docs/usage/plugins/utilities/weblogs.md +47 -0
  34. package/examples/web/README.md +18 -0
  35. package/examples/web/ldap-browser.html +94 -0
  36. package/package.json +37 -1
  37. package/static/browser/ldap-browser/LdapBrowser.js +199 -0
  38. package/static/browser/ldap-browser/LdapBrowser.js.map +1 -0
  39. package/static/browser/ldap-browser/api/RawApiClient.js +103 -0
  40. package/static/browser/ldap-browser/api/RawApiClient.js.map +1 -0
  41. package/static/browser/ldap-browser/components/EntryTree.js +235 -0
  42. package/static/browser/ldap-browser/components/EntryTree.js.map +1 -0
  43. package/static/browser/ldap-browser/components/EntryView.js +183 -0
  44. package/static/browser/ldap-browser/components/EntryView.js.map +1 -0
  45. package/static/browser/ldap-browser/index.js +4 -0
  46. package/static/browser/ldap-browser/index.js.map +1 -0
  47. package/static/browser/ldap-browser/schema.js +135 -0
  48. package/static/browser/ldap-browser/schema.js.map +1 -0
  49. package/static/browser/ldap-browser/types.js +2 -0
  50. package/static/browser/ldap-browser/types.js.map +1 -0
  51. package/static/browser/ldap-browser.css +2 -0
  52. package/static/browser/ldap-browser.css.map +1 -0
  53. package/static/browser/ldap-browser.esm.js +915 -0
  54. package/static/browser/ldap-browser.esm.js.map +1 -0
  55. package/static/browser/ldap-browser.js +925 -0
  56. package/static/browser/ldap-browser.js.map +1 -0
  57. package/static/browser/ldap-browser.min.js +2 -0
  58. package/static/browser/ldap-browser.min.js.map +1 -0
  59. package/static/browser/ldap-unit-editor/components/UnitTree.js +0 -1
  60. package/static/browser/ldap-unit-editor/components/UnitTree.js.map +1 -1
  61. package/static/browser/ldap-unit-editor.esm.js +0 -1
  62. package/static/browser/ldap-unit-editor.esm.js.map +1 -1
  63. package/static/browser/ldap-unit-editor.js +0 -1
  64. package/static/browser/ldap-unit-editor.js.map +1 -1
  65. package/static/browser/ldap-unit-editor.min.js.map +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LdapBrowser.js","sources":["../../../../src/browser/ldap-browser/LdapBrowser.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
@@ -0,0 +1,103 @@
1
+ /**
2
+ * Client of the low-level LDAP API (`core/ldap/raw` plugin).
3
+ * @module browser/ldap-browser/api/RawApiClient
4
+ */
5
+ class RawApiClient {
6
+ constructor(baseUrl = '', authToken) {
7
+ this.baseUrl = baseUrl.replace(/\/$/, '');
8
+ this.authToken = authToken;
9
+ }
10
+ /**
11
+ * Issue a GET on the raw API and decode its JSON answer.
12
+ *
13
+ * @param path path below `/api/v1/ldap/raw`
14
+ * @returns decoded body
15
+ * @throws Error carrying the server message when the status is not 2xx
16
+ */
17
+ async get(path) {
18
+ const headers = { Accept: 'application/json' };
19
+ if (this.authToken)
20
+ headers.Authorization = `Bearer ${this.authToken}`;
21
+ const response = await fetch(`${this.baseUrl}/api/v1/ldap/raw${path}`, {
22
+ headers,
23
+ });
24
+ if (!response.ok) {
25
+ let message = response.statusText;
26
+ try {
27
+ const body = (await response.json());
28
+ if (body.error)
29
+ message = body.error;
30
+ }
31
+ catch {
32
+ // keep the status text
33
+ }
34
+ throw new Error(`${response.status}: ${message}`);
35
+ }
36
+ return (await response.json());
37
+ }
38
+ /**
39
+ * Subtrees the server exposes, used as roots of the tree.
40
+ *
41
+ * @returns list of base DNs
42
+ */
43
+ async getBases() {
44
+ const data = await this.get('/bases');
45
+ return data.bases;
46
+ }
47
+ /**
48
+ * Server capabilities.
49
+ *
50
+ * @returns root DSE
51
+ */
52
+ getRootDse() {
53
+ return this.get('/rootdse');
54
+ }
55
+ /**
56
+ * Directory schema.
57
+ *
58
+ * @returns object classes, attribute types, syntaxes and matching rules
59
+ */
60
+ getSchema() {
61
+ return this.get('/schema');
62
+ }
63
+ /**
64
+ * Read one entry.
65
+ *
66
+ * @param dn DN of the entry
67
+ * @returns the entry with all its attributes
68
+ */
69
+ getEntry(dn) {
70
+ return this.get(`/entry/${encodeURIComponent(dn)}`);
71
+ }
72
+ /**
73
+ * List the direct children of an entry.
74
+ *
75
+ * @param dn DN of the parent
76
+ * @param withChildrenFlag ask the server which children have children
77
+ * @returns children sorted by RDN, with the truncation flag
78
+ */
79
+ getChildren(dn, withChildrenFlag = true) {
80
+ return this.get(`/children/${encodeURIComponent(dn)}${withChildrenFlag ? '?children=1' : ''}`);
81
+ }
82
+ /**
83
+ * Run a search.
84
+ *
85
+ * @param params search base, scope, filter and limit
86
+ * @returns matching entries
87
+ */
88
+ search(params) {
89
+ const query = new URLSearchParams({ base: params.base });
90
+ if (params.scope)
91
+ query.set('scope', params.scope);
92
+ if (params.filter)
93
+ query.set('filter', params.filter);
94
+ if (params.attributes?.length)
95
+ query.set('attributes', params.attributes.join(','));
96
+ if (params.limit)
97
+ query.set('limit', String(params.limit));
98
+ return this.get(`/search?${query.toString()}`);
99
+ }
100
+ }
101
+
102
+ export { RawApiClient };
103
+ //# sourceMappingURL=RawApiClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RawApiClient.js","sources":["../../../../../src/browser/ldap-browser/api/RawApiClient.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
@@ -0,0 +1,235 @@
1
+ import { DisposableComponent } from '../../shared/components/DisposableComponent.js';
2
+ import { escapeHtml } from '../../shared/utils/dom.js';
3
+
4
+ /**
5
+ * Lazy directory tree: one root per exposed base, children fetched on expand.
6
+ * @module browser/ldap-browser/components/EntryTree
7
+ */
8
+ /** Icon picked from the object classes of an entry */
9
+ function iconFor(objectClass) {
10
+ const classes = objectClass.map(c => c.toLowerCase());
11
+ if (classes.includes('organizationalunit') ||
12
+ classes.includes('organization'))
13
+ return 'folder';
14
+ if (classes.includes('groupofnames') ||
15
+ classes.includes('groupofuniquenames') ||
16
+ classes.includes('posixgroup'))
17
+ return 'group';
18
+ if (classes.includes('inetorgperson') ||
19
+ classes.includes('person') ||
20
+ classes.includes('organizationalperson'))
21
+ return 'person';
22
+ if (classes.includes('domain') || classes.includes('dcobject'))
23
+ return 'dns';
24
+ return 'article';
25
+ }
26
+ class EntryTree extends DisposableComponent {
27
+ constructor(container, api, onSelect, onError) {
28
+ super();
29
+ this.roots = [];
30
+ this.children = new Map();
31
+ this.expanded = new Set();
32
+ this.loading = new Set();
33
+ this.selectedDn = null;
34
+ this.container = container;
35
+ this.api = api;
36
+ this.onSelect = onSelect;
37
+ this.onError = onError;
38
+ this.addManagedEventListener(this.container, 'click', event => {
39
+ const target = event.target.closest('[data-dn]');
40
+ if (!target)
41
+ return;
42
+ const dn = target.dataset.dn;
43
+ if (target.classList.contains('ldap-browser-tree__toggle')) {
44
+ void this.toggle(dn);
45
+ }
46
+ else {
47
+ void this.select(dn);
48
+ }
49
+ });
50
+ }
51
+ /**
52
+ * Load the exposed bases and draw them as roots.
53
+ *
54
+ * @param bases base DNs to use as roots
55
+ */
56
+ async init(bases) {
57
+ this.roots = bases;
58
+ // Open the first root so the tree is never empty on arrival
59
+ if (bases.length > 0)
60
+ await this.expand(bases[0]);
61
+ this.render();
62
+ }
63
+ /**
64
+ * DN currently highlighted in the tree.
65
+ *
66
+ * @returns selected DN, or null
67
+ */
68
+ getSelectedDn() {
69
+ return this.selectedDn;
70
+ }
71
+ /**
72
+ * Highlight an entry and notify the parent component.
73
+ *
74
+ * @param dn DN to select
75
+ * @returns whatever the selection handler returns, so callers can await
76
+ * the entry actually being displayed
77
+ */
78
+ select(dn) {
79
+ this.selectedDn = dn;
80
+ this.render();
81
+ return this.onSelect(dn);
82
+ }
83
+ /**
84
+ * Expand the tree down to a DN, loading every level on the way, then
85
+ * select it. Used to follow a search result or a DN typed by the user.
86
+ *
87
+ * @param dn DN to reveal
88
+ */
89
+ async revealAndSelect(dn) {
90
+ const root = this.roots.find(base => dn.toLowerCase() === base.toLowerCase() ||
91
+ dn.toLowerCase().endsWith(`,${base.toLowerCase()}`));
92
+ if (root) {
93
+ // Walk down from the root, expanding each ancestor
94
+ const relative = dn
95
+ .substring(0, dn.length - root.length)
96
+ .replace(/,$/, '');
97
+ const rdns = relative ? splitDn(relative) : [];
98
+ let current = root;
99
+ await this.expand(current);
100
+ // Expand the ancestors only: the target itself stays closed
101
+ for (let i = rdns.length - 1; i >= 1; i--) {
102
+ current = `${rdns[i]},${current}`;
103
+ await this.expand(current);
104
+ }
105
+ }
106
+ await this.select(dn);
107
+ }
108
+ /**
109
+ * Drop cached children so the next expand hits the server again.
110
+ *
111
+ * @param dn DN whose children must be reloaded, or undefined for all
112
+ */
113
+ invalidate(dn) {
114
+ if (dn)
115
+ this.children.delete(dn);
116
+ else
117
+ this.children.clear();
118
+ }
119
+ /**
120
+ * Expand a node, fetching its children the first time.
121
+ *
122
+ * @param dn DN of the node
123
+ */
124
+ async expand(dn) {
125
+ this.expanded.add(dn);
126
+ if (this.children.has(dn))
127
+ return;
128
+ this.loading.add(dn);
129
+ this.render();
130
+ try {
131
+ this.children.set(dn, await this.api.getChildren(dn));
132
+ }
133
+ catch (err) {
134
+ this.expanded.delete(dn);
135
+ this.onError(err);
136
+ }
137
+ finally {
138
+ this.loading.delete(dn);
139
+ this.render();
140
+ }
141
+ }
142
+ /**
143
+ * Expand or collapse a node.
144
+ *
145
+ * @param dn DN of the node
146
+ */
147
+ async toggle(dn) {
148
+ if (this.expanded.has(dn)) {
149
+ this.expanded.delete(dn);
150
+ this.render();
151
+ return;
152
+ }
153
+ await this.expand(dn);
154
+ }
155
+ /** Redraw the whole tree */
156
+ render() {
157
+ if (this.isDestroyed)
158
+ return;
159
+ this.container.innerHTML = `<ul class="ldap-browser-tree">${this.roots
160
+ .map(root => this.renderNode(root, root, ['dcObject'], true))
161
+ .join('')}</ul>`;
162
+ }
163
+ /**
164
+ * Render one node and, when expanded, its children.
165
+ *
166
+ * @param dn DN of the node
167
+ * @param label text shown for the node
168
+ * @param objectClass object classes, used to pick the icon
169
+ * @param expandable whether the node may have children
170
+ * @returns HTML of the node
171
+ */
172
+ renderNode(dn, label, objectClass, expandable) {
173
+ const isExpanded = this.expanded.has(dn);
174
+ const isLoading = this.loading.has(dn);
175
+ const isSelected = this.selectedDn === dn;
176
+ const children = this.children.get(dn);
177
+ const toggle = expandable
178
+ ? `<span class="ldap-browser-tree__toggle material-icons" data-dn="${escapeHtml(dn)}">${isLoading
179
+ ? 'hourglass_empty'
180
+ : isExpanded
181
+ ? 'expand_more'
182
+ : 'chevron_right'}</span>`
183
+ : '<span class="ldap-browser-tree__toggle ldap-browser-tree__toggle--leaf"></span>';
184
+ const sub = isExpanded && children
185
+ ? `<ul>${children.children.length === 0
186
+ ? '<li class="ldap-browser-tree__empty">(no child)</li>'
187
+ : children.children
188
+ .map(child => this.renderNode(child.dn, child.rdn, child.objectClass, child.hasChildren))
189
+ .join('')}${children.truncated
190
+ ? `<li class="ldap-browser-tree__truncated" title="Raise --ldap-raw-max-results to see more">
191
+ first ${children.children.length} entries only — use the search to find the others
192
+ </li>`
193
+ : ''}</ul>`
194
+ : '';
195
+ return `<li>
196
+ <div class="ldap-browser-tree__node${isSelected ? ' ldap-browser-tree__node--selected' : ''}">
197
+ ${toggle}
198
+ <span class="ldap-browser-tree__label" data-dn="${escapeHtml(dn)}" title="${escapeHtml(dn)}">
199
+ <span class="material-icons">${iconFor(objectClass)}</span>
200
+ <span class="ldap-browser-tree__name">${escapeHtml(label)}</span>
201
+ </span>
202
+ </div>
203
+ ${sub}
204
+ </li>`;
205
+ }
206
+ }
207
+ /**
208
+ * Split a DN into its components, honouring `\,` escapes.
209
+ *
210
+ * @param dn DN to split
211
+ * @returns RDN components, outermost first
212
+ */
213
+ function splitDn(dn) {
214
+ const parts = [];
215
+ let current = '';
216
+ for (let i = 0; i < dn.length; i++) {
217
+ if (dn[i] === '\\' && i + 1 < dn.length) {
218
+ current += dn[i] + dn[i + 1];
219
+ i++;
220
+ }
221
+ else if (dn[i] === ',') {
222
+ parts.push(current.trim());
223
+ current = '';
224
+ }
225
+ else {
226
+ current += dn[i];
227
+ }
228
+ }
229
+ if (current.trim())
230
+ parts.push(current.trim());
231
+ return parts;
232
+ }
233
+
234
+ export { EntryTree };
235
+ //# sourceMappingURL=EntryTree.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EntryTree.js","sources":["../../../../../src/browser/ldap-browser/components/EntryTree.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
@@ -0,0 +1,183 @@
1
+ import { escapeHtml } from '../../shared/utils/dom.js';
2
+
3
+ /**
4
+ * Attribute table of one entry, annotated with the directory schema.
5
+ * @module browser/ldap-browser/components/EntryView
6
+ */
7
+ /** Operational attributes are shown apart from the ones the admin sets */
8
+ const OPERATIONAL_USAGE = new Set([
9
+ 'directoryOperation',
10
+ 'distributedOperation',
11
+ 'dSAOperation',
12
+ ]);
13
+ class EntryView {
14
+ constructor(container, schema) {
15
+ this.container = container;
16
+ this.schema = schema;
17
+ }
18
+ /** Draw the placeholder shown when nothing is selected */
19
+ renderEmpty() {
20
+ this.container.innerHTML = `
21
+ <div class="ldap-browser-entry__empty">
22
+ <span class="material-icons">description</span>
23
+ <p>Select an entry in the tree</p>
24
+ </div>`;
25
+ }
26
+ /**
27
+ * Draw an error in place of the entry.
28
+ *
29
+ * @param message message to display
30
+ */
31
+ renderError(message) {
32
+ this.container.innerHTML = `<div class="ldap-browser-entry__error">${escapeHtml(message)}</div>`;
33
+ }
34
+ /** Draw a loading indicator */
35
+ renderLoading() {
36
+ this.container.innerHTML =
37
+ '<div class="ldap-browser-entry__loading">Loading…</div>';
38
+ }
39
+ /**
40
+ * Draw an entry: its DN, its object classes with the attributes they allow,
41
+ * then the attribute table.
42
+ *
43
+ * @param entry entry to display
44
+ */
45
+ render(entry) {
46
+ const objectClasses = entry.attributes.objectClass?.values || [];
47
+ const resolved = this.schema?.resolveAttributes(objectClasses);
48
+ const mandatory = new Set((resolved?.must || []).map(name => name.toLowerCase()));
49
+ const present = new Set(Object.keys(entry.attributes).map(name => name.split(';')[0].toLowerCase()));
50
+ const names = Object.keys(entry.attributes).sort((a, b) => a.localeCompare(b));
51
+ const isOperational = (name) => {
52
+ const type = this.schema?.getAttributeType(name);
53
+ return type ? OPERATIONAL_USAGE.has(type.usage) : false;
54
+ };
55
+ const userAttributes = names.filter(name => !isOperational(name));
56
+ const operational = names.filter(isOperational);
57
+ // Mandatory attributes the entry does not carry: the directory should
58
+ // reject that, but a UI that hides it makes debugging harder
59
+ const missing = (resolved?.must || []).filter(name => !present.has(name.toLowerCase()));
60
+ this.container.innerHTML = `
61
+ <div class="ldap-browser-entry">
62
+ <h2 class="ldap-browser-entry__dn" title="${escapeHtml(entry.dn)}">
63
+ <span class="material-icons">description</span>
64
+ ${escapeHtml(entry.dn || '(root DSE)')}
65
+ </h2>
66
+
67
+ ${this.renderObjectClasses(objectClasses, resolved)}
68
+
69
+ ${missing.length
70
+ ? `<p class="ldap-browser-entry__warning">
71
+ Missing mandatory attribute(s): ${escapeHtml(missing.join(', '))}
72
+ </p>`
73
+ : ''}
74
+
75
+ ${this.renderTable(entry, mandatory, userAttributes, 'Attributes')}
76
+ ${operational.length
77
+ ? this.renderTable(entry, mandatory, operational, 'Operational attributes')
78
+ : ''}
79
+ </div>`;
80
+ }
81
+ /**
82
+ * Render the object class list and, when the schema is available, the
83
+ * attributes those classes allow.
84
+ *
85
+ * @param objectClasses object classes of the entry
86
+ * @param resolved mandatory and optional attributes they imply
87
+ * @returns HTML of the section
88
+ */
89
+ renderObjectClasses(objectClasses, resolved) {
90
+ if (objectClasses.length === 0)
91
+ return '';
92
+ const chips = objectClasses
93
+ .map(name => {
94
+ const definition = this.schema?.getObjectClass(name);
95
+ const title = definition
96
+ ? `${definition.kind}${definition.desc ? ` — ${definition.desc}` : ''}`
97
+ : 'unknown in schema';
98
+ return `<span class="ldap-browser-chip${definition ? '' : ' ldap-browser-chip--unknown'}" title="${escapeHtml(title)}">${escapeHtml(name)}</span>`;
99
+ })
100
+ .join('');
101
+ const allowed = resolved
102
+ ? `<div class="ldap-browser-entry__allowed">
103
+ <span><strong>Required:</strong> ${escapeHtml(resolved.must.join(', ') || '—')}</span>
104
+ <span><strong>Allowed:</strong> ${escapeHtml(resolved.may.join(', ') || '—')}</span>
105
+ </div>`
106
+ : '';
107
+ return `<div class="ldap-browser-entry__classes">${chips}</div>${allowed}`;
108
+ }
109
+ /**
110
+ * Render one attribute table.
111
+ *
112
+ * @param entry entry being displayed
113
+ * @param mandatory lowercase names of the mandatory attributes
114
+ * @param names attributes to include, in display order
115
+ * @param title heading of the table
116
+ * @returns HTML of the table
117
+ */
118
+ renderTable(entry, mandatory, names, title) {
119
+ if (names.length === 0)
120
+ return '';
121
+ const rows = names
122
+ .map(name => {
123
+ const attribute = entry.attributes[name];
124
+ const type = this.schema?.getAttributeType(name);
125
+ const isMandatory = mandatory.has(name.split(';')[0].toLowerCase());
126
+ const tooltip = type
127
+ ? [
128
+ type.desc,
129
+ type.syntax ? `syntax ${type.syntax}` : '',
130
+ type.singleValue ? 'single-valued' : '',
131
+ type.noUserModification ? 'read-only' : '',
132
+ ]
133
+ .filter(Boolean)
134
+ .join(' — ')
135
+ : 'unknown in schema';
136
+ return `<tr>
137
+ <th class="${isMandatory ? 'ldap-browser-attr--must' : ''}${type ? '' : ' ldap-browser-attr--unknown'}" title="${escapeHtml(tooltip)}">
138
+ ${escapeHtml(name)}${isMandatory ? ' *' : ''}
139
+ </th>
140
+ <td>${this.renderValues(name, attribute)}</td>
141
+ </tr>`;
142
+ })
143
+ .join('');
144
+ return `<h3 class="ldap-browser-entry__section">${escapeHtml(title)}</h3>
145
+ <table class="ldap-browser-entry__table"><tbody>${rows}</tbody></table>`;
146
+ }
147
+ /**
148
+ * Render the values of one attribute: images as thumbnails, other binary
149
+ * values as their size plus the base64 payload, text as text.
150
+ *
151
+ * @param name attribute name
152
+ * @param attribute values and binary flag
153
+ * @returns HTML of the value cell
154
+ */
155
+ renderValues(name, attribute) {
156
+ return attribute.values
157
+ .map(value => {
158
+ if (attribute.binary && this.schema?.isImageAttribute(name))
159
+ // Keep only base64 characters: the value ends up in an attribute
160
+ return `<img class="ldap-browser-entry__photo" alt="${escapeHtml(name)}" src="data:image/jpeg;base64,${value.replace(/[^A-Za-z0-9+/=]/g, '')}" />`;
161
+ if (attribute.binary)
162
+ return `<details class="ldap-browser-entry__binary">
163
+ <summary>${byteLength(value)} bytes (base64)</summary>
164
+ <code>${escapeHtml(value)}</code>
165
+ </details>`;
166
+ return `<div class="ldap-browser-entry__value">${escapeHtml(value)}</div>`;
167
+ })
168
+ .join('');
169
+ }
170
+ }
171
+ /**
172
+ * Decoded size of a base64 payload, without decoding it.
173
+ *
174
+ * @param base64 base64-encoded value
175
+ * @returns number of octets
176
+ */
177
+ function byteLength(base64) {
178
+ const padding = base64.endsWith('==') ? 2 : base64.endsWith('=') ? 1 : 0;
179
+ return Math.max(0, Math.floor((base64.length * 3) / 4) - padding);
180
+ }
181
+
182
+ export { EntryView };
183
+ //# sourceMappingURL=EntryView.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EntryView.js","sources":["../../../../../src/browser/ldap-browser/components/EntryView.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export { LdapBrowser } from './LdapBrowser.js';
2
+ export { RawApiClient } from './api/RawApiClient.js';
3
+ export { SchemaView } from './schema.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;"}