ldap-rest 0.4.7 → 0.6.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.
- package/bin/sync-james.mjs +6 -2
- package/dist/bin/index.js +1 -1
- package/dist/config/args.js +1 -1
- package/dist/lib/auth/base.js +1 -1
- package/dist/lib/ldapSchema.js +1 -0
- package/dist/lib/utils.js +1 -1
- package/dist/plugins/auth/authzPerRoute.js +1 -1
- package/dist/plugins/auth/rateLimit.js +1 -1
- package/dist/plugins/ldap/groups.js +1 -1
- package/dist/plugins/ldap/organizations.js +1 -1
- package/dist/plugins/ldap/raw.js +1 -0
- package/dist/plugins/twake/appAccountsApi.js +1 -1
- package/dist/plugins/twake/appAccountsConsistency.js +1 -1
- package/dist/src/bin/index.d.ts +112 -0
- package/dist/src/browser/ldap-browser/LdapBrowser.d.ts +52 -0
- package/dist/src/browser/ldap-browser/api/RawApiClient.d.ts +64 -0
- package/dist/src/browser/ldap-browser/components/EntryTree.d.ts +75 -0
- package/dist/src/browser/ldap-browser/components/EntryView.d.ts +56 -0
- package/dist/src/browser/ldap-browser/index.d.ts +9 -0
- package/dist/src/browser/ldap-browser/schema.d.ts +62 -0
- package/dist/src/browser/ldap-browser/types.d.ts +96 -0
- package/dist/src/config/args.d.ts +7 -0
- package/dist/src/lib/auth/base.d.ts +82 -1
- package/dist/src/lib/ldapSchema.d.ts +159 -0
- package/dist/src/lib/utils.d.ts +4 -0
- package/dist/src/plugins/ldap/raw.d.ts +251 -0
- package/dist/src/plugins/twake/appAccountsConsistency.d.ts +40 -2
- package/docs/client-development/browser/libraries.md +142 -1
- package/docs/usage/configuration.md +40 -5
- package/docs/usage/plugins/README.md +10 -9
- package/docs/usage/plugins/auth/README.md +57 -0
- package/docs/usage/plugins/auth/rate-limit.md +9 -0
- package/docs/usage/plugins/integrations/app-accounts.md +35 -2
- package/docs/usage/plugins/ldap/README.md +12 -0
- package/docs/usage/plugins/ldap/raw.md +226 -0
- package/examples/web/README.md +18 -0
- package/examples/web/ldap-browser.html +94 -0
- package/package.json +37 -1
- package/static/browser/ldap-browser/LdapBrowser.js +199 -0
- package/static/browser/ldap-browser/LdapBrowser.js.map +1 -0
- package/static/browser/ldap-browser/api/RawApiClient.js +103 -0
- package/static/browser/ldap-browser/api/RawApiClient.js.map +1 -0
- package/static/browser/ldap-browser/components/EntryTree.js +235 -0
- package/static/browser/ldap-browser/components/EntryTree.js.map +1 -0
- package/static/browser/ldap-browser/components/EntryView.js +183 -0
- package/static/browser/ldap-browser/components/EntryView.js.map +1 -0
- package/static/browser/ldap-browser/index.js +4 -0
- package/static/browser/ldap-browser/index.js.map +1 -0
- package/static/browser/ldap-browser/schema.js +135 -0
- package/static/browser/ldap-browser/schema.js.map +1 -0
- package/static/browser/ldap-browser/types.js +2 -0
- package/static/browser/ldap-browser/types.js.map +1 -0
- package/static/browser/ldap-browser.css +2 -0
- package/static/browser/ldap-browser.css.map +1 -0
- package/static/browser/ldap-browser.esm.js +915 -0
- package/static/browser/ldap-browser.esm.js.map +1 -0
- package/static/browser/ldap-browser.js +925 -0
- package/static/browser/ldap-browser.js.map +1 -0
- package/static/browser/ldap-browser.min.js +2 -0
- package/static/browser/ldap-browser.min.js.map +1 -0
- package/static/browser/ldap-unit-editor/components/UnitTree.js +0 -1
- package/static/browser/ldap-unit-editor/components/UnitTree.js.map +1 -1
- package/static/browser/ldap-unit-editor.esm.js +0 -1
- package/static/browser/ldap-unit-editor.esm.js.map +1 -1
- package/static/browser/ldap-unit-editor.js +0 -1
- package/static/browser/ldap-unit-editor.js.map +1 -1
- package/static/browser/ldap-unit-editor.min.js.map +1 -1
|
@@ -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 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client-side view of the directory schema: the lookups the UI needs to
|
|
3
|
+
* annotate an entry (mandatory attributes, descriptions, binary values).
|
|
4
|
+
*
|
|
5
|
+
* This mirrors `src/lib/ldapSchema.ts` on the server, minus the parsing:
|
|
6
|
+
* the browser receives the schema already parsed.
|
|
7
|
+
*
|
|
8
|
+
* @module browser/ldap-browser/schema
|
|
9
|
+
*/
|
|
10
|
+
/** Syntaxes whose values are octets rather than text */
|
|
11
|
+
const BINARY_SYNTAXES = new Set([
|
|
12
|
+
'1.3.6.1.4.1.1466.115.121.1.5',
|
|
13
|
+
'1.3.6.1.4.1.1466.115.121.1.8',
|
|
14
|
+
'1.3.6.1.4.1.1466.115.121.1.9',
|
|
15
|
+
'1.3.6.1.4.1.1466.115.121.1.10',
|
|
16
|
+
'1.3.6.1.4.1.1466.115.121.1.28',
|
|
17
|
+
'1.3.6.1.4.1.1466.115.121.1.40',
|
|
18
|
+
'1.3.6.1.4.1.1466.115.121.1.49',
|
|
19
|
+
]);
|
|
20
|
+
/** Attributes whose values are images, previewed as such */
|
|
21
|
+
const IMAGE_ATTRIBUTES = new Set([
|
|
22
|
+
'jpegphoto',
|
|
23
|
+
'photo',
|
|
24
|
+
'thumbnailphoto',
|
|
25
|
+
'thumbnaillogo',
|
|
26
|
+
]);
|
|
27
|
+
class SchemaView {
|
|
28
|
+
constructor(schema) {
|
|
29
|
+
this.objectClasses = new Map();
|
|
30
|
+
this.attributeTypes = new Map();
|
|
31
|
+
this.schema = schema;
|
|
32
|
+
for (const oc of schema.objectClasses) {
|
|
33
|
+
this.objectClasses.set(oc.oid.toLowerCase(), oc);
|
|
34
|
+
for (const name of oc.names)
|
|
35
|
+
this.objectClasses.set(name.toLowerCase(), oc);
|
|
36
|
+
}
|
|
37
|
+
for (const at of schema.attributeTypes) {
|
|
38
|
+
this.attributeTypes.set(at.oid.toLowerCase(), at);
|
|
39
|
+
for (const name of at.names)
|
|
40
|
+
this.attributeTypes.set(name.toLowerCase(), at);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Look up an object class by name or OID.
|
|
45
|
+
*
|
|
46
|
+
* @param name object class name or OID
|
|
47
|
+
* @returns the definition, or undefined when unknown
|
|
48
|
+
*/
|
|
49
|
+
getObjectClass(name) {
|
|
50
|
+
return this.objectClasses.get(name.toLowerCase());
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Look up an attribute type by name or OID, ignoring attribute options.
|
|
54
|
+
*
|
|
55
|
+
* @param name attribute name, `;binary` and friends included
|
|
56
|
+
* @returns the definition, or undefined when unknown
|
|
57
|
+
*/
|
|
58
|
+
getAttributeType(name) {
|
|
59
|
+
return this.attributeTypes.get(name.split(';')[0].toLowerCase());
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Resolve the syntax of an attribute through its `SUP` chain.
|
|
63
|
+
*
|
|
64
|
+
* @param name attribute name
|
|
65
|
+
* @returns syntax OID, or undefined
|
|
66
|
+
*/
|
|
67
|
+
getAttributeSyntax(name) {
|
|
68
|
+
const seen = new Set();
|
|
69
|
+
let current = this.getAttributeType(name);
|
|
70
|
+
while (current && !seen.has(current.oid)) {
|
|
71
|
+
if (current.syntax)
|
|
72
|
+
return current.syntax;
|
|
73
|
+
seen.add(current.oid);
|
|
74
|
+
current = current.sup ? this.getAttributeType(current.sup) : undefined;
|
|
75
|
+
}
|
|
76
|
+
return undefined;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Tell whether an attribute is meant to be displayed as an image.
|
|
80
|
+
*
|
|
81
|
+
* @param name attribute name
|
|
82
|
+
* @returns true for photo-like attributes
|
|
83
|
+
*/
|
|
84
|
+
isImageAttribute(name) {
|
|
85
|
+
return IMAGE_ATTRIBUTES.has(name.split(';')[0].toLowerCase());
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Tell whether an attribute holds octets rather than text.
|
|
89
|
+
*
|
|
90
|
+
* @param name attribute name
|
|
91
|
+
* @returns true when values are binary
|
|
92
|
+
*/
|
|
93
|
+
isBinaryAttribute(name) {
|
|
94
|
+
if (name
|
|
95
|
+
.split(';')
|
|
96
|
+
.slice(1)
|
|
97
|
+
.some(o => o.toLowerCase() === 'binary'))
|
|
98
|
+
return true;
|
|
99
|
+
const syntax = this.getAttributeSyntax(name);
|
|
100
|
+
return syntax ? BINARY_SYNTAXES.has(syntax) : false;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Collect the mandatory and optional attributes of a set of object
|
|
104
|
+
* classes, walking every `SUP` chain.
|
|
105
|
+
*
|
|
106
|
+
* @param objectClasses object class names carried by an entry
|
|
107
|
+
* @returns `must` and `may` attribute names, `may` excluding mandatory ones
|
|
108
|
+
*/
|
|
109
|
+
resolveAttributes(objectClasses) {
|
|
110
|
+
const must = new Set();
|
|
111
|
+
const may = new Set();
|
|
112
|
+
const visited = new Set();
|
|
113
|
+
const walk = (name) => {
|
|
114
|
+
const key = name.toLowerCase();
|
|
115
|
+
if (visited.has(key))
|
|
116
|
+
return;
|
|
117
|
+
visited.add(key);
|
|
118
|
+
const oc = this.getObjectClass(name);
|
|
119
|
+
if (!oc)
|
|
120
|
+
return;
|
|
121
|
+
oc.must.forEach(a => must.add(a));
|
|
122
|
+
oc.may.forEach(a => may.add(a));
|
|
123
|
+
oc.sup.forEach(walk);
|
|
124
|
+
};
|
|
125
|
+
objectClasses.forEach(walk);
|
|
126
|
+
const mustLower = new Set([...must].map(a => a.toLowerCase()));
|
|
127
|
+
return {
|
|
128
|
+
must: [...must],
|
|
129
|
+
may: [...may].filter(a => !mustLower.has(a.toLowerCase())),
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export { SchemaView };
|
|
135
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sources":["../../../../src/browser/ldap-browser/schema.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
.ldap-browser-container{--ldap-browser-primary:#3949ab;--ldap-browser-surface:#fff;--ldap-browser-on-surface:rgba(0,0,0,.87);--ldap-browser-muted:rgba(0,0,0,.54);--ldap-browser-border:#e0e0e0;--ldap-browser-error:#b00020;--ldap-browser-warning:#b26a00;color:var(--ldap-browser-on-surface);font-family:Roboto,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;font-size:14px}.ldap-browser{background:var(--ldap-browser-surface);border:1px solid var(--ldap-browser-border);border-radius:4px;display:flex;flex-direction:column;height:100%;overflow:hidden}.ldap-browser__toolbar{align-items:center;border-bottom:1px solid var(--ldap-browser-border);display:flex;flex-wrap:wrap;gap:8px;padding:12px}.ldap-browser__base,.ldap-browser__filter,.ldap-browser__refresh,.ldap-browser__scope,.ldap-browser__search{border-radius:4px;box-sizing:border-box;font-size:14px;height:38px}.ldap-browser__filter{border:1px solid var(--ldap-browser-border);flex:1 1 260px;font-family:monospace;min-width:180px;padding:0 12px}.ldap-browser__base,.ldap-browser__scope{background:var(--ldap-browser-surface);border:1px solid var(--ldap-browser-border);padding:0 8px}.ldap-browser__refresh,.ldap-browser__search{align-items:center;background:var(--ldap-browser-primary);border:none;color:#fff;cursor:pointer;display:flex;gap:4px;padding:0 12px}.ldap-browser__refresh:hover,.ldap-browser__search:hover{filter:brightness(1.1)}.ldap-browser__body{display:flex;flex:1;min-height:0}.ldap-browser__tree{border-right:1px solid var(--ldap-browser-border);flex:0 0 320px;overflow:auto;padding:8px}.ldap-browser__entry{flex:1;min-width:0;overflow:auto;padding:16px}.ldap-browser-tree,.ldap-browser-tree ul{list-style:none;margin:0;padding:0 0 0 16px}.ldap-browser-tree{padding-left:0}.ldap-browser-tree__node{align-items:center;border-radius:4px;cursor:pointer;display:flex;gap:4px;min-width:0;padding:2px 4px}.ldap-browser-tree__node:hover{background:rgba(0,0,0,.04)}.ldap-browser-tree__node--selected{background:rgba(57,73,171,.12)}.ldap-browser-tree__toggle{color:var(--ldap-browser-muted);cursor:pointer;flex:0 0 24px;font-size:20px;user-select:none}.ldap-browser-tree__toggle--leaf{cursor:default}.ldap-browser-tree__label{align-items:center;display:flex;font-family:monospace;gap:6px;min-width:0;overflow:hidden;white-space:nowrap}.ldap-browser-tree__label .ldap-browser-tree__name{overflow:hidden;text-overflow:ellipsis}.ldap-browser-tree__label .material-icons{color:var(--ldap-browser-muted);flex:0 0 auto;font-size:18px}.ldap-browser-tree__empty{color:var(--ldap-browser-muted);font-style:italic;padding:2px 4px 2px 28px}.ldap-browser-tree__truncated{color:var(--ldap-browser-warning);font-style:italic;padding:2px 4px 2px 28px}.ldap-browser-entry__dn{align-items:center;display:flex;font-family:monospace;font-size:16px;gap:8px;margin:0 0 12px;word-break:break-all}.ldap-browser-entry__section{color:var(--ldap-browser-muted);font-size:13px;letter-spacing:.5px;margin:24px 0 8px;text-transform:uppercase}.ldap-browser-entry__classes{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:8px}.ldap-browser-chip{background:rgba(57,73,171,.12);border-radius:12px;font-size:12px;padding:2px 10px}.ldap-browser-chip--unknown{background:rgba(176,0,32,.12);color:var(--ldap-browser-error)}.ldap-browser-entry__allowed{color:var(--ldap-browser-muted);display:flex;flex-direction:column;font-size:12px;gap:2px;margin-bottom:12px}.ldap-browser-entry__warning{color:var(--ldap-browser-warning)}.ldap-browser-entry__table{border-collapse:collapse;table-layout:fixed;width:100%}.ldap-browser-entry__table th{border-bottom:1px solid var(--ldap-browser-border);color:var(--ldap-browser-muted);font-family:monospace;font-weight:400;overflow-wrap:anywhere;padding:6px 12px 6px 0;text-align:left;vertical-align:top;width:220px}@media (max-width:900px){.ldap-browser-entry__table th{width:140px}}.ldap-browser-entry__table td{border-bottom:1px solid var(--ldap-browser-border);padding:6px 0;vertical-align:top;word-break:break-word}.ldap-browser-attr--must{color:var(--ldap-browser-on-surface);font-weight:500}.ldap-browser-attr--unknown{color:var(--ldap-browser-error)}.ldap-browser-entry__value{font-family:monospace;white-space:pre-wrap}.ldap-browser-entry__binary code{background:#f5f5f5;display:block;font-size:11px;max-height:120px;overflow:auto;padding:4px;word-break:break-all}.ldap-browser-entry__photo{border-radius:4px;max-height:160px;max-width:160px}.ldap-browser-entry__empty,.ldap-browser-entry__loading{align-items:center;color:var(--ldap-browser-muted);display:flex;flex-direction:column;height:100%;justify-content:center}.ldap-browser-entry__empty .material-icons{font-size:56px;margin-bottom:12px}.ldap-browser-entry__error,.ldap-browser__error{color:var(--ldap-browser-error)}.ldap-browser__results{border-top:1px solid var(--ldap-browser-border);max-height:200px;overflow:auto;padding:8px 12px}.ldap-browser__results ul{margin:0;padding-left:18px}.ldap-browser__results a{color:var(--ldap-browser-primary);font-family:monospace}
|
|
2
|
+
/*# sourceMappingURL=ldap-browser.css.map */
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["styles.css"],"names":[],"mappings":"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","file":"ldap-browser.css","sourcesContent":["/**\n * LDAP Browser - low-level directory browser styles\n */\n\n.ldap-browser-container {\n --ldap-browser-primary: #3949ab;\n --ldap-browser-surface: #ffffff;\n --ldap-browser-on-surface: rgba(0, 0, 0, 0.87);\n --ldap-browser-muted: rgba(0, 0, 0, 0.54);\n --ldap-browser-border: #e0e0e0;\n --ldap-browser-error: #b00020;\n --ldap-browser-warning: #b26a00;\n\n font-family:\n 'Roboto',\n -apple-system,\n BlinkMacSystemFont,\n 'Segoe UI',\n sans-serif;\n font-size: 14px;\n color: var(--ldap-browser-on-surface);\n}\n\n.ldap-browser {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--ldap-browser-surface);\n border: 1px solid var(--ldap-browser-border);\n border-radius: 4px;\n overflow: hidden;\n}\n\n/* Toolbar */\n\n.ldap-browser__toolbar {\n display: flex;\n gap: 8px;\n align-items: center;\n padding: 12px;\n border-bottom: 1px solid var(--ldap-browser-border);\n flex-wrap: wrap;\n}\n\n/*\n * Inputs, selects and buttons each size themselves differently from their\n * padding and font, which left the buttons standing 4px proud of the input.\n * One explicit height for every control keeps the row on a single line.\n */\n.ldap-browser__filter,\n.ldap-browser__scope,\n.ldap-browser__base,\n.ldap-browser__search,\n.ldap-browser__refresh {\n height: 38px;\n box-sizing: border-box;\n font-size: 14px;\n border-radius: 4px;\n}\n\n.ldap-browser__filter {\n flex: 1 1 260px;\n min-width: 180px;\n padding: 0 12px;\n font-family: monospace;\n border: 1px solid var(--ldap-browser-border);\n}\n\n.ldap-browser__scope,\n.ldap-browser__base {\n padding: 0 8px;\n border: 1px solid var(--ldap-browser-border);\n background: var(--ldap-browser-surface);\n}\n\n.ldap-browser__search,\n.ldap-browser__refresh {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 0 12px;\n color: #fff;\n background: var(--ldap-browser-primary);\n border: none;\n cursor: pointer;\n}\n\n.ldap-browser__search:hover,\n.ldap-browser__refresh:hover {\n filter: brightness(1.1);\n}\n\n.ldap-browser__body {\n display: flex;\n flex: 1;\n min-height: 0;\n}\n\n.ldap-browser__tree {\n flex: 0 0 320px;\n overflow: auto;\n padding: 8px;\n border-right: 1px solid var(--ldap-browser-border);\n}\n\n.ldap-browser__entry {\n flex: 1;\n overflow: auto;\n padding: 16px;\n min-width: 0;\n}\n\n/* Tree */\n\n.ldap-browser-tree,\n.ldap-browser-tree ul {\n margin: 0;\n padding: 0 0 0 16px;\n list-style: none;\n}\n\n.ldap-browser-tree {\n padding-left: 0;\n}\n\n.ldap-browser-tree__node {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 2px 4px;\n border-radius: 4px;\n cursor: pointer;\n /* Let the label be the part that gives way, not the icons */\n min-width: 0;\n}\n\n.ldap-browser-tree__node:hover {\n background: rgba(0, 0, 0, 0.04);\n}\n\n.ldap-browser-tree__node--selected {\n background: rgba(57, 73, 171, 0.12);\n}\n\n/*\n * `flex: 0 0 24px` rather than `width`: as a shrinkable flex item the\n * chevron gave way under a long label, so rows whose entry name overflowed\n * sat a few pixels left of their siblings and the column of icons zig-zagged.\n */\n.ldap-browser-tree__toggle {\n flex: 0 0 24px;\n font-size: 20px;\n color: var(--ldap-browser-muted);\n cursor: pointer;\n user-select: none;\n}\n\n.ldap-browser-tree__toggle--leaf {\n cursor: default;\n}\n\n.ldap-browser-tree__label {\n display: flex;\n align-items: center;\n gap: 6px;\n /* min-width:0 is what lets the text actually ellipsize inside a flex row */\n min-width: 0;\n overflow: hidden;\n white-space: nowrap;\n font-family: monospace;\n}\n\n/* The text node itself carries the ellipsis; the icon must never shrink */\n.ldap-browser-tree__label .ldap-browser-tree__name {\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.ldap-browser-tree__label .material-icons {\n flex: 0 0 auto;\n font-size: 18px;\n color: var(--ldap-browser-muted);\n}\n\n.ldap-browser-tree__empty {\n padding: 2px 4px 2px 28px;\n color: var(--ldap-browser-muted);\n font-style: italic;\n}\n\n.ldap-browser-tree__truncated {\n padding: 2px 4px 2px 28px;\n color: var(--ldap-browser-warning);\n font-style: italic;\n}\n\n/* Entry */\n\n.ldap-browser-entry__dn {\n display: flex;\n align-items: center;\n gap: 8px;\n margin: 0 0 12px;\n font-size: 16px;\n font-family: monospace;\n word-break: break-all;\n}\n\n.ldap-browser-entry__section {\n margin: 24px 0 8px;\n font-size: 13px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--ldap-browser-muted);\n}\n\n.ldap-browser-entry__classes {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n margin-bottom: 8px;\n}\n\n.ldap-browser-chip {\n padding: 2px 10px;\n font-size: 12px;\n background: rgba(57, 73, 171, 0.12);\n border-radius: 12px;\n}\n\n.ldap-browser-chip--unknown {\n background: rgba(176, 0, 32, 0.12);\n color: var(--ldap-browser-error);\n}\n\n.ldap-browser-entry__allowed {\n display: flex;\n flex-direction: column;\n gap: 2px;\n margin-bottom: 12px;\n font-size: 12px;\n color: var(--ldap-browser-muted);\n}\n\n.ldap-browser-entry__warning {\n color: var(--ldap-browser-warning);\n}\n\n/*\n * `table-layout: fixed` is what keeps the two tables (attributes and\n * operational attributes) in one column grid: with the default `auto`\n * layout, a long attribute name widens its own table's first column and\n * the value columns of the two tables no longer line up.\n */\n.ldap-browser-entry__table {\n width: 100%;\n border-collapse: collapse;\n table-layout: fixed;\n}\n\n.ldap-browser-entry__table th {\n width: 220px;\n padding: 6px 12px 6px 0;\n text-align: left;\n vertical-align: top;\n font-family: monospace;\n font-weight: 400;\n color: var(--ldap-browser-muted);\n border-bottom: 1px solid var(--ldap-browser-border);\n /* A name longer than the column wraps rather than pushing it */\n overflow-wrap: anywhere;\n}\n\n/* A fixed 220px name column eats too much of a narrow panel */\n@media (max-width: 900px) {\n .ldap-browser-entry__table th {\n width: 140px;\n }\n}\n\n.ldap-browser-entry__table td {\n padding: 6px 0;\n vertical-align: top;\n word-break: break-word;\n border-bottom: 1px solid var(--ldap-browser-border);\n}\n\n.ldap-browser-attr--must {\n font-weight: 500;\n color: var(--ldap-browser-on-surface);\n}\n\n.ldap-browser-attr--unknown {\n color: var(--ldap-browser-error);\n}\n\n.ldap-browser-entry__value {\n font-family: monospace;\n white-space: pre-wrap;\n}\n\n.ldap-browser-entry__binary code {\n display: block;\n max-height: 120px;\n overflow: auto;\n padding: 4px;\n font-size: 11px;\n background: #f5f5f5;\n word-break: break-all;\n}\n\n.ldap-browser-entry__photo {\n max-width: 160px;\n max-height: 160px;\n border-radius: 4px;\n}\n\n.ldap-browser-entry__empty,\n.ldap-browser-entry__loading {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n color: var(--ldap-browser-muted);\n}\n\n.ldap-browser-entry__empty .material-icons {\n font-size: 56px;\n margin-bottom: 12px;\n}\n\n.ldap-browser-entry__error,\n.ldap-browser__error {\n color: var(--ldap-browser-error);\n}\n\n/* Search results */\n\n.ldap-browser__results {\n max-height: 200px;\n overflow: auto;\n padding: 8px 12px;\n border-top: 1px solid var(--ldap-browser-border);\n}\n\n.ldap-browser__results ul {\n margin: 0;\n padding-left: 18px;\n}\n\n.ldap-browser__results a {\n font-family: monospace;\n color: var(--ldap-browser-primary);\n}\n"]}
|