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,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,2 @@
1
+
2
+ //# sourceMappingURL=types.js.map
@@ -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":"AAIA,wBACE,8BAA+B,CAC/B,2BAA+B,CAC/B,yCAA8C,CAC9C,oCAAyC,CACzC,6BAA8B,CAC9B,4BAA6B,CAC7B,8BAA+B,CAS/B,oCAAqC,CAPrC,uEAKY,CACZ,cAEF,CAEA,cAIE,sCAAuC,CACvC,2CAA4C,CAC5C,iBAAkB,CALlB,YAAa,CACb,qBAAsB,CACtB,WAAY,CAIZ,eACF,CAIA,uBAGE,kBAAmB,CAEnB,kDAAmD,CAJnD,YAAa,CAKb,cAAe,CAJf,OAAQ,CAER,YAGF,CAOA,4GAQE,iBAAkB,CAFlB,qBAAsB,CACtB,cAAe,CAFf,WAIF,CAEA,sBAKE,2CAA4C,CAJ5C,cAAe,CAGf,qBAAsB,CAFtB,eAAgB,CAChB,cAGF,CAEA,yCAIE,sCAAuC,CADvC,2CAA4C,CAD5C,aAGF,CAEA,6CAGE,kBAAmB,CAInB,sCAAuC,CACvC,WAAY,CAFZ,UAAW,CAGX,cAAe,CAPf,YAAa,CAEb,OAAQ,CACR,cAKF,CAEA,yDAEE,sBACF,CAEA,oBACE,YAAa,CACb,MAAO,CACP,YACF,CAEA,oBAIE,iDAAkD,CAHlD,cAAe,CACf,aAAc,CACd,WAEF,CAEA,qBACE,MAAO,CAGP,WAAY,CAFZ,aAAc,CACd,YAEF,CAIA,yCAIE,eAAgB,CAFhB,QAAS,CACT,kBAEF,CAEA,mBACE,cACF,CAEA,yBAEE,kBAAmB,CAGnB,iBAAkB,CAClB,cAAe,CALf,YAAa,CAEb,OAAQ,CAKR,WAAY,CAJZ,eAKF,CAEA,+BACE,0BACF,CAEA,mCACE,8BACF,CAOA,2BAGE,+BAAgC,CAChC,cAAe,CAHf,aAAc,CACd,cAAe,CAGf,gBACF,CAEA,iCACE,cACF,CAEA,0BAEE,kBAAmB,CADnB,YAAa,CAOb,qBAAsB,CALtB,OAAQ,CAER,WAAY,CACZ,eAAgB,CAChB,kBAEF,CAGA,mDACE,eAAgB,CAChB,sBACF,CAEA,0CAGE,+BAAgC,CAFhC,aAAc,CACd,cAEF,CAEA,0BAEE,+BAAgC,CAChC,iBAAkB,CAFlB,wBAGF,CAEA,8BAEE,iCAAkC,CAClC,iBAAkB,CAFlB,wBAGF,CAIA,wBAEE,kBAAmB,CADnB,YAAa,CAKb,qBAAsB,CADtB,cAAe,CAFf,OAAQ,CACR,eAAgB,CAGhB,oBACF,CAEA,6BAKE,+BAAgC,CAHhC,cAAe,CAEf,mBAAqB,CAHrB,iBAAkB,CAElB,wBAGF,CAEA,6BACE,YAAa,CACb,cAAe,CACf,OAAQ,CACR,iBACF,CAEA,mBAGE,8BAAmC,CACnC,kBAAmB,CAFnB,cAAe,CADf,gBAIF,CAEA,4BACE,6BAAkC,CAClC,+BACF,CAEA,6BAME,+BAAgC,CALhC,YAAa,CACb,qBAAsB,CAGtB,cAAe,CAFf,OAAQ,CACR,kBAGF,CAEA,6BACE,iCACF,CAQA,2BAEE,wBAAyB,CACzB,kBAAmB,CAFnB,UAGF,CAEA,8BAQE,kDAAmD,CADnD,+BAAgC,CAFhC,qBAAsB,CACtB,eAAgB,CAIhB,sBAAuB,CARvB,sBAAuB,CACvB,eAAgB,CAChB,kBAAmB,CAHnB,WAUF,CAGA,yBACE,8BACE,WACF,CACF,CAEA,8BAIE,kDAAmD,CAHnD,aAAc,CACd,kBAAmB,CACnB,qBAEF,CAEA,yBAEE,oCAAqC,CADrC,eAEF,CAEA,4BACE,+BACF,CAEA,2BACE,qBAAsB,CACtB,oBACF,CAEA,iCAME,kBAAmB,CALnB,aAAc,CAId,cAAe,CAHf,gBAAiB,CACjB,aAAc,CACd,WAAY,CAGZ,oBACF,CAEA,2BAGE,iBAAkB,CADlB,gBAAiB,CADjB,eAGF,CAEA,wDAIE,kBAAmB,CAGnB,+BAAgC,CALhC,YAAa,CACb,qBAAsB,CAGtB,WAAY,CADZ,sBAGF,CAEA,2CACE,cAAe,CACf,kBACF,CAEA,gDAEE,+BACF,CAIA,uBAIE,+CAAgD,CAHhD,gBAAiB,CACjB,aAAc,CACd,gBAEF,CAEA,0BACE,QAAS,CACT,iBACF,CAEA,yBAEE,iCAAkC,CADlC,qBAEF","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"]}