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.
- 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/plugins/auth/authzPerRoute.js +1 -1
- package/dist/plugins/auth/rateLimit.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/weblogs.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 +6 -0
- package/dist/src/lib/auth/base.d.ts +82 -1
- package/dist/src/lib/ldapSchema.d.ts +159 -0
- package/dist/src/plugins/ldap/raw.d.ts +251 -0
- package/dist/src/plugins/weblogs.d.ts +7 -0
- package/docs/client-development/browser/libraries.md +142 -1
- package/docs/usage/configuration.md +20 -0
- 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 +32 -0
- package/docs/usage/plugins/ldap/README.md +12 -0
- package/docs/usage/plugins/ldap/raw.md +226 -0
- package/docs/usage/plugins/utilities/weblogs.md +47 -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,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lazy directory tree: one root per exposed base, children fetched on expand.
|
|
3
|
+
* @module browser/ldap-browser/components/EntryTree
|
|
4
|
+
*/
|
|
5
|
+
import { DisposableComponent } from '../../shared/components/DisposableComponent';
|
|
6
|
+
import type { RawApiClient } from '../api/RawApiClient';
|
|
7
|
+
export declare class EntryTree extends DisposableComponent {
|
|
8
|
+
private container;
|
|
9
|
+
private api;
|
|
10
|
+
private onSelect;
|
|
11
|
+
private onError;
|
|
12
|
+
private roots;
|
|
13
|
+
private children;
|
|
14
|
+
private expanded;
|
|
15
|
+
private loading;
|
|
16
|
+
private selectedDn;
|
|
17
|
+
constructor(container: HTMLElement, api: RawApiClient, onSelect: (dn: string) => void | Promise<void>, onError: (error: Error) => void);
|
|
18
|
+
/**
|
|
19
|
+
* Load the exposed bases and draw them as roots.
|
|
20
|
+
*
|
|
21
|
+
* @param bases base DNs to use as roots
|
|
22
|
+
*/
|
|
23
|
+
init(bases: string[]): Promise<void>;
|
|
24
|
+
/**
|
|
25
|
+
* DN currently highlighted in the tree.
|
|
26
|
+
*
|
|
27
|
+
* @returns selected DN, or null
|
|
28
|
+
*/
|
|
29
|
+
getSelectedDn(): string | null;
|
|
30
|
+
/**
|
|
31
|
+
* Highlight an entry and notify the parent component.
|
|
32
|
+
*
|
|
33
|
+
* @param dn DN to select
|
|
34
|
+
* @returns whatever the selection handler returns, so callers can await
|
|
35
|
+
* the entry actually being displayed
|
|
36
|
+
*/
|
|
37
|
+
select(dn: string): void | Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* Expand the tree down to a DN, loading every level on the way, then
|
|
40
|
+
* select it. Used to follow a search result or a DN typed by the user.
|
|
41
|
+
*
|
|
42
|
+
* @param dn DN to reveal
|
|
43
|
+
*/
|
|
44
|
+
revealAndSelect(dn: string): Promise<void>;
|
|
45
|
+
/**
|
|
46
|
+
* Drop cached children so the next expand hits the server again.
|
|
47
|
+
*
|
|
48
|
+
* @param dn DN whose children must be reloaded, or undefined for all
|
|
49
|
+
*/
|
|
50
|
+
invalidate(dn?: string): void;
|
|
51
|
+
/**
|
|
52
|
+
* Expand a node, fetching its children the first time.
|
|
53
|
+
*
|
|
54
|
+
* @param dn DN of the node
|
|
55
|
+
*/
|
|
56
|
+
private expand;
|
|
57
|
+
/**
|
|
58
|
+
* Expand or collapse a node.
|
|
59
|
+
*
|
|
60
|
+
* @param dn DN of the node
|
|
61
|
+
*/
|
|
62
|
+
private toggle;
|
|
63
|
+
/** Redraw the whole tree */
|
|
64
|
+
private render;
|
|
65
|
+
/**
|
|
66
|
+
* Render one node and, when expanded, its children.
|
|
67
|
+
*
|
|
68
|
+
* @param dn DN of the node
|
|
69
|
+
* @param label text shown for the node
|
|
70
|
+
* @param objectClass object classes, used to pick the icon
|
|
71
|
+
* @param expandable whether the node may have children
|
|
72
|
+
* @returns HTML of the node
|
|
73
|
+
*/
|
|
74
|
+
private renderNode;
|
|
75
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Attribute table of one entry, annotated with the directory schema.
|
|
3
|
+
* @module browser/ldap-browser/components/EntryView
|
|
4
|
+
*/
|
|
5
|
+
import type { SchemaView } from '../schema';
|
|
6
|
+
import type { RawEntry } from '../types';
|
|
7
|
+
export declare class EntryView {
|
|
8
|
+
private container;
|
|
9
|
+
private schema;
|
|
10
|
+
constructor(container: HTMLElement, schema: SchemaView | null);
|
|
11
|
+
/** Draw the placeholder shown when nothing is selected */
|
|
12
|
+
renderEmpty(): void;
|
|
13
|
+
/**
|
|
14
|
+
* Draw an error in place of the entry.
|
|
15
|
+
*
|
|
16
|
+
* @param message message to display
|
|
17
|
+
*/
|
|
18
|
+
renderError(message: string): void;
|
|
19
|
+
/** Draw a loading indicator */
|
|
20
|
+
renderLoading(): void;
|
|
21
|
+
/**
|
|
22
|
+
* Draw an entry: its DN, its object classes with the attributes they allow,
|
|
23
|
+
* then the attribute table.
|
|
24
|
+
*
|
|
25
|
+
* @param entry entry to display
|
|
26
|
+
*/
|
|
27
|
+
render(entry: RawEntry): void;
|
|
28
|
+
/**
|
|
29
|
+
* Render the object class list and, when the schema is available, the
|
|
30
|
+
* attributes those classes allow.
|
|
31
|
+
*
|
|
32
|
+
* @param objectClasses object classes of the entry
|
|
33
|
+
* @param resolved mandatory and optional attributes they imply
|
|
34
|
+
* @returns HTML of the section
|
|
35
|
+
*/
|
|
36
|
+
private renderObjectClasses;
|
|
37
|
+
/**
|
|
38
|
+
* Render one attribute table.
|
|
39
|
+
*
|
|
40
|
+
* @param entry entry being displayed
|
|
41
|
+
* @param mandatory lowercase names of the mandatory attributes
|
|
42
|
+
* @param names attributes to include, in display order
|
|
43
|
+
* @param title heading of the table
|
|
44
|
+
* @returns HTML of the table
|
|
45
|
+
*/
|
|
46
|
+
private renderTable;
|
|
47
|
+
/**
|
|
48
|
+
* Render the values of one attribute: images as thumbnails, other binary
|
|
49
|
+
* values as their size plus the base64 payload, text as text.
|
|
50
|
+
*
|
|
51
|
+
* @param name attribute name
|
|
52
|
+
* @param attribute values and binary flag
|
|
53
|
+
* @returns HTML of the value cell
|
|
54
|
+
*/
|
|
55
|
+
private renderValues;
|
|
56
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LDAP Browser - low-level directory browser (read-only)
|
|
3
|
+
* @author Xavier Guimard
|
|
4
|
+
*/
|
|
5
|
+
import './styles.css';
|
|
6
|
+
export { LdapBrowser } from './LdapBrowser';
|
|
7
|
+
export { RawApiClient } from './api/RawApiClient';
|
|
8
|
+
export { SchemaView } from './schema';
|
|
9
|
+
export type { BrowserOptions, LdapSchema, RawAttribute, RawChild, RawEntry, RawSearchResult, ObjectClassDefinition, AttributeTypeDefinition, } from './types';
|
|
@@ -0,0 +1,62 @@
|
|
|
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
|
+
import type { AttributeTypeDefinition, LdapSchema, ObjectClassDefinition } from './types';
|
|
11
|
+
export declare class SchemaView {
|
|
12
|
+
readonly schema: LdapSchema;
|
|
13
|
+
private objectClasses;
|
|
14
|
+
private attributeTypes;
|
|
15
|
+
constructor(schema: LdapSchema);
|
|
16
|
+
/**
|
|
17
|
+
* Look up an object class by name or OID.
|
|
18
|
+
*
|
|
19
|
+
* @param name object class name or OID
|
|
20
|
+
* @returns the definition, or undefined when unknown
|
|
21
|
+
*/
|
|
22
|
+
getObjectClass(name: string): ObjectClassDefinition | undefined;
|
|
23
|
+
/**
|
|
24
|
+
* Look up an attribute type by name or OID, ignoring attribute options.
|
|
25
|
+
*
|
|
26
|
+
* @param name attribute name, `;binary` and friends included
|
|
27
|
+
* @returns the definition, or undefined when unknown
|
|
28
|
+
*/
|
|
29
|
+
getAttributeType(name: string): AttributeTypeDefinition | undefined;
|
|
30
|
+
/**
|
|
31
|
+
* Resolve the syntax of an attribute through its `SUP` chain.
|
|
32
|
+
*
|
|
33
|
+
* @param name attribute name
|
|
34
|
+
* @returns syntax OID, or undefined
|
|
35
|
+
*/
|
|
36
|
+
getAttributeSyntax(name: string): string | undefined;
|
|
37
|
+
/**
|
|
38
|
+
* Tell whether an attribute is meant to be displayed as an image.
|
|
39
|
+
*
|
|
40
|
+
* @param name attribute name
|
|
41
|
+
* @returns true for photo-like attributes
|
|
42
|
+
*/
|
|
43
|
+
isImageAttribute(name: string): boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Tell whether an attribute holds octets rather than text.
|
|
46
|
+
*
|
|
47
|
+
* @param name attribute name
|
|
48
|
+
* @returns true when values are binary
|
|
49
|
+
*/
|
|
50
|
+
isBinaryAttribute(name: string): boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Collect the mandatory and optional attributes of a set of object
|
|
53
|
+
* classes, walking every `SUP` chain.
|
|
54
|
+
*
|
|
55
|
+
* @param objectClasses object class names carried by an entry
|
|
56
|
+
* @returns `must` and `may` attribute names, `may` excluding mandatory ones
|
|
57
|
+
*/
|
|
58
|
+
resolveAttributes(objectClasses: string[]): {
|
|
59
|
+
must: string[];
|
|
60
|
+
may: string[];
|
|
61
|
+
};
|
|
62
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Types of the low-level LDAP browser, mirroring the responses of the
|
|
3
|
+
* `core/ldap/raw` server plugin.
|
|
4
|
+
* @module browser/ldap-browser/types
|
|
5
|
+
*/
|
|
6
|
+
/** Values of a single attribute; base64-encoded when `binary` is true */
|
|
7
|
+
export interface RawAttribute {
|
|
8
|
+
values: string[];
|
|
9
|
+
binary: boolean;
|
|
10
|
+
}
|
|
11
|
+
/** A directory entry with all its attributes */
|
|
12
|
+
export interface RawEntry {
|
|
13
|
+
dn: string;
|
|
14
|
+
attributes: Record<string, RawAttribute>;
|
|
15
|
+
}
|
|
16
|
+
/** Direct child of an entry, as needed to draw a tree node */
|
|
17
|
+
export interface RawChild {
|
|
18
|
+
dn: string;
|
|
19
|
+
rdn: string;
|
|
20
|
+
objectClass: string[];
|
|
21
|
+
hasChildren: boolean;
|
|
22
|
+
}
|
|
23
|
+
/** Direct children of an entry, with the truncation flag */
|
|
24
|
+
export interface RawChildren {
|
|
25
|
+
children: RawChild[];
|
|
26
|
+
/** True when the server's result limit cut the listing short */
|
|
27
|
+
truncated: boolean;
|
|
28
|
+
}
|
|
29
|
+
/** Result of a raw search */
|
|
30
|
+
export interface RawSearchResult {
|
|
31
|
+
entries: RawEntry[];
|
|
32
|
+
truncated: boolean;
|
|
33
|
+
}
|
|
34
|
+
/** Parsed `objectClasses` definition */
|
|
35
|
+
export interface ObjectClassDefinition {
|
|
36
|
+
oid: string;
|
|
37
|
+
names: string[];
|
|
38
|
+
desc?: string;
|
|
39
|
+
obsolete: boolean;
|
|
40
|
+
sup: string[];
|
|
41
|
+
kind: 'STRUCTURAL' | 'ABSTRACT' | 'AUXILIARY';
|
|
42
|
+
must: string[];
|
|
43
|
+
may: string[];
|
|
44
|
+
}
|
|
45
|
+
/** Parsed `attributeTypes` definition */
|
|
46
|
+
export interface AttributeTypeDefinition {
|
|
47
|
+
oid: string;
|
|
48
|
+
names: string[];
|
|
49
|
+
desc?: string;
|
|
50
|
+
obsolete: boolean;
|
|
51
|
+
sup?: string;
|
|
52
|
+
equality?: string;
|
|
53
|
+
ordering?: string;
|
|
54
|
+
substr?: string;
|
|
55
|
+
syntax?: string;
|
|
56
|
+
syntaxLength?: number;
|
|
57
|
+
singleValue: boolean;
|
|
58
|
+
collective: boolean;
|
|
59
|
+
noUserModification: boolean;
|
|
60
|
+
usage: string;
|
|
61
|
+
}
|
|
62
|
+
/** Parsed `ldapSyntaxes` definition */
|
|
63
|
+
export interface SyntaxDefinition {
|
|
64
|
+
oid: string;
|
|
65
|
+
desc?: string;
|
|
66
|
+
binary: boolean;
|
|
67
|
+
}
|
|
68
|
+
/** Parsed `matchingRules` definition */
|
|
69
|
+
export interface MatchingRuleDefinition {
|
|
70
|
+
oid: string;
|
|
71
|
+
names: string[];
|
|
72
|
+
desc?: string;
|
|
73
|
+
syntax?: string;
|
|
74
|
+
}
|
|
75
|
+
/** Whole schema as served by `GET /api/v1/ldap/raw/schema` */
|
|
76
|
+
export interface LdapSchema {
|
|
77
|
+
objectClasses: ObjectClassDefinition[];
|
|
78
|
+
attributeTypes: AttributeTypeDefinition[];
|
|
79
|
+
syntaxes: SyntaxDefinition[];
|
|
80
|
+
matchingRules: MatchingRuleDefinition[];
|
|
81
|
+
}
|
|
82
|
+
/** Options of the {@link LdapBrowser} constructor */
|
|
83
|
+
export interface BrowserOptions {
|
|
84
|
+
/** id of the element the browser renders into */
|
|
85
|
+
containerId: string;
|
|
86
|
+
/** Origin of the API, e.g. `window.location.origin` */
|
|
87
|
+
apiBaseUrl?: string;
|
|
88
|
+
/** Bearer token sent with every request */
|
|
89
|
+
authToken?: string;
|
|
90
|
+
/** DN to select on startup; defaults to the first exposed base */
|
|
91
|
+
initialDn?: string;
|
|
92
|
+
/** Called whenever an entry is displayed */
|
|
93
|
+
onEntrySelected?: (dn: string) => void;
|
|
94
|
+
/** Called on any error the browser handles itself */
|
|
95
|
+
onError?: (error: Error) => void;
|
|
96
|
+
}
|
|
@@ -58,6 +58,11 @@ export interface Config {
|
|
|
58
58
|
ldap_organization_max_subnodes?: number;
|
|
59
59
|
organization_schema?: string;
|
|
60
60
|
ldap_flat_schema?: string[];
|
|
61
|
+
ldap_raw_base?: string[];
|
|
62
|
+
ldap_raw_hidden_attribute?: string[];
|
|
63
|
+
ldap_raw_show_secrets?: boolean;
|
|
64
|
+
ldap_raw_max_results?: number;
|
|
65
|
+
ldap_raw_schema_cache_ttl?: number;
|
|
61
66
|
bulk_import_schemas?: string;
|
|
62
67
|
bulk_import_max_file_size?: string;
|
|
63
68
|
bulk_import_batch_size?: string;
|
|
@@ -65,6 +70,7 @@ export interface Config {
|
|
|
65
70
|
external_branch_class?: string[];
|
|
66
71
|
static_path?: string;
|
|
67
72
|
static_name?: string;
|
|
73
|
+
auth_path_prefix?: string | string[];
|
|
68
74
|
llng_ini?: string;
|
|
69
75
|
auth_token?: string[];
|
|
70
76
|
auth_totp?: string[];
|
|
@@ -3,7 +3,88 @@ export type DmRequest = Request & {
|
|
|
3
3
|
user?: string;
|
|
4
4
|
};
|
|
5
5
|
import DmPlugin from '../../abstract/plugin';
|
|
6
|
+
/**
|
|
7
|
+
* Tell whether a mount prefix covers a request path, with the rule Express
|
|
8
|
+
* itself applies: on segment boundaries, so `/api/m` covers `/api/m` and
|
|
9
|
+
* `/api/m/entry` but never `/api/machines`.
|
|
10
|
+
*
|
|
11
|
+
* The catch-all uses this to decide what another plugin already guards, so
|
|
12
|
+
* it must agree with Express exactly — a looser rule here would skip paths
|
|
13
|
+
* nobody guards.
|
|
14
|
+
*
|
|
15
|
+
* @param prefix mount prefix
|
|
16
|
+
* @param path request path
|
|
17
|
+
* @returns true when the prefix covers the path
|
|
18
|
+
*/
|
|
19
|
+
export declare function prefixCoversPath(prefix: string, path: string): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Path prefixes claimed by scoped authentication plugins.
|
|
22
|
+
*
|
|
23
|
+
* Takes the registry as an argument rather than reaching for the server, so
|
|
24
|
+
* `DM` and `AuthBase` share one definition of what "claimed" means. The
|
|
25
|
+
* registry is a live reference: it keeps filling as the remaining plugins
|
|
26
|
+
* register, which is why the catch-all consults it per request.
|
|
27
|
+
*
|
|
28
|
+
* @param loadedPlugins the server's plugin registry
|
|
29
|
+
* @param except name of the plugin asking, excluded from the result
|
|
30
|
+
* @returns the prefixes other authentication plugins guard
|
|
31
|
+
*/
|
|
32
|
+
export declare function claimedPrefixes(loadedPlugins: Record<string, DmPlugin>, except?: string): string[];
|
|
6
33
|
export default abstract class AuthBase extends DmPlugin {
|
|
7
34
|
abstract authMethod(req: DmRequest, res: Response, next: () => void): void;
|
|
8
|
-
|
|
35
|
+
/** Validated prefixes, computed once: the catch-all reads them per request */
|
|
36
|
+
private _pathPrefixes?;
|
|
37
|
+
/**
|
|
38
|
+
* Path prefixes this authentication applies to, empty when it guards the
|
|
39
|
+
* whole server.
|
|
40
|
+
*
|
|
41
|
+
* Loading the same plugin twice with different prefixes lets one server
|
|
42
|
+
* serve populations that authenticate differently — machines with a token
|
|
43
|
+
* on one branch of the API, administrators with an SSO session on another:
|
|
44
|
+
*
|
|
45
|
+
* ```
|
|
46
|
+
* --plugin 'core/auth/token:tok:{"auth_path_prefix":"/api/m"}'
|
|
47
|
+
* --plugin 'core/auth/openidconnect:oidc:{"auth_path_prefix":"/api/admin"}'
|
|
48
|
+
* ```
|
|
49
|
+
*
|
|
50
|
+
* A credential is then only valid on the branch it was scoped to, which is
|
|
51
|
+
* the point: a leaked machine token buys nothing on the admin API.
|
|
52
|
+
*
|
|
53
|
+
* A malformed entry is refused rather than skipped. Dropping one silently
|
|
54
|
+
* would shrink what the plugin guards — the failure mode that leaves a
|
|
55
|
+
* branch open while the configuration still reads as if it were covered.
|
|
56
|
+
*
|
|
57
|
+
* `/` is not a prefix but the whole server, so a list containing it makes
|
|
58
|
+
* the plugin a catch-all: `["/", "/api/admin"]` guards everything, not
|
|
59
|
+
* only `/api/admin`.
|
|
60
|
+
*
|
|
61
|
+
* @returns the configured prefixes without their trailing slashes, empty
|
|
62
|
+
* when the plugin guards the whole server
|
|
63
|
+
* @throws Error when an entry is not a usable path prefix
|
|
64
|
+
*/
|
|
65
|
+
get pathPrefixes(): string[];
|
|
66
|
+
/**
|
|
67
|
+
* Run this plugin's authentication on a request, hooks included.
|
|
68
|
+
*
|
|
69
|
+
* The dispatcher calls this; the plugin no longer owns a layer of its own.
|
|
70
|
+
*
|
|
71
|
+
* @param req incoming request
|
|
72
|
+
* @param res response, ended here when authentication fails
|
|
73
|
+
* @param next called only when the request is authenticated
|
|
74
|
+
*/
|
|
75
|
+
authenticate(req: Request, res: Response, next: () => void): Promise<void>;
|
|
76
|
+
/**
|
|
77
|
+
* Register with the server's authentication dispatcher instead of mounting
|
|
78
|
+
* a middleware.
|
|
79
|
+
*
|
|
80
|
+
* Mounting per plugin made protection depend on registration order: a
|
|
81
|
+
* plugin whose `app.use` landed after the routes it was meant to guard
|
|
82
|
+
* never ran for them, and the catch-all — stepping aside for a branch that
|
|
83
|
+
* guard was supposed to cover — turned that into anonymous access. The
|
|
84
|
+
* dispatcher is mounted by `DM` before any plugin loads, so it always
|
|
85
|
+
* precedes every route, whatever order the plugins register in.
|
|
86
|
+
*
|
|
87
|
+
* @param _app unused: the dispatcher owns the only authentication layer
|
|
88
|
+
*/
|
|
89
|
+
api(_app: Express): void;
|
|
9
90
|
}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LDAP schema (RFC 4512) parser
|
|
3
|
+
*
|
|
4
|
+
* The directory publishes its schema as a set of string definitions in the
|
|
5
|
+
* subschema entry (`objectClasses`, `attributeTypes`, `ldapSyntaxes`,
|
|
6
|
+
* `matchingRules`). This module turns those strings into plain objects and
|
|
7
|
+
* resolves the inheritance chains, so a client can know which attributes an
|
|
8
|
+
* entry may carry, which ones are mandatory, and how to render their values.
|
|
9
|
+
*
|
|
10
|
+
* @module lib/ldapSchema
|
|
11
|
+
* @author Xavier Guimard <xguimard@linagora.com>
|
|
12
|
+
*/
|
|
13
|
+
/** Parsed `attributeTypes` definition (RFC 4512 §4.1.2) */
|
|
14
|
+
export interface AttributeTypeDefinition {
|
|
15
|
+
oid: string;
|
|
16
|
+
names: string[];
|
|
17
|
+
desc?: string;
|
|
18
|
+
obsolete: boolean;
|
|
19
|
+
sup?: string;
|
|
20
|
+
equality?: string;
|
|
21
|
+
ordering?: string;
|
|
22
|
+
substr?: string;
|
|
23
|
+
syntax?: string;
|
|
24
|
+
/** Suggested maximum length, from the `{len}` suffix of the syntax OID */
|
|
25
|
+
syntaxLength?: number;
|
|
26
|
+
singleValue: boolean;
|
|
27
|
+
collective: boolean;
|
|
28
|
+
noUserModification: boolean;
|
|
29
|
+
/** `userApplications` (default), `directoryOperation`, `distributedOperation` or `dSAOperation` */
|
|
30
|
+
usage: string;
|
|
31
|
+
}
|
|
32
|
+
/** Parsed `objectClasses` definition (RFC 4512 §4.1.1) */
|
|
33
|
+
export interface ObjectClassDefinition {
|
|
34
|
+
oid: string;
|
|
35
|
+
names: string[];
|
|
36
|
+
desc?: string;
|
|
37
|
+
obsolete: boolean;
|
|
38
|
+
sup: string[];
|
|
39
|
+
kind: 'STRUCTURAL' | 'ABSTRACT' | 'AUXILIARY';
|
|
40
|
+
must: string[];
|
|
41
|
+
may: string[];
|
|
42
|
+
}
|
|
43
|
+
/** Parsed `ldapSyntaxes` definition (RFC 4512 §4.1.5) */
|
|
44
|
+
export interface SyntaxDefinition {
|
|
45
|
+
oid: string;
|
|
46
|
+
desc?: string;
|
|
47
|
+
/** True when values of this syntax are not human-readable text */
|
|
48
|
+
binary: boolean;
|
|
49
|
+
}
|
|
50
|
+
/** Parsed `matchingRules` definition (RFC 4512 §4.1.3) */
|
|
51
|
+
export interface MatchingRuleDefinition {
|
|
52
|
+
oid: string;
|
|
53
|
+
names: string[];
|
|
54
|
+
desc?: string;
|
|
55
|
+
syntax?: string;
|
|
56
|
+
}
|
|
57
|
+
/** Whole schema, indexed by lowercase name for lookups */
|
|
58
|
+
export interface LdapSchema {
|
|
59
|
+
attributeTypes: AttributeTypeDefinition[];
|
|
60
|
+
objectClasses: ObjectClassDefinition[];
|
|
61
|
+
syntaxes: SyntaxDefinition[];
|
|
62
|
+
matchingRules: MatchingRuleDefinition[];
|
|
63
|
+
}
|
|
64
|
+
/** Raw definitions as read from the subschema entry */
|
|
65
|
+
export interface RawSchemaDefinitions {
|
|
66
|
+
attributeTypes?: string[];
|
|
67
|
+
objectClasses?: string[];
|
|
68
|
+
ldapSyntaxes?: string[];
|
|
69
|
+
matchingRules?: string[];
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Parse an `attributeTypes` definition.
|
|
73
|
+
*
|
|
74
|
+
* @param definition definition string
|
|
75
|
+
* @returns parsed definition, or null when it cannot be parsed
|
|
76
|
+
*/
|
|
77
|
+
export declare function parseAttributeType(definition: string): AttributeTypeDefinition | null;
|
|
78
|
+
/**
|
|
79
|
+
* Parse an `objectClasses` definition.
|
|
80
|
+
*
|
|
81
|
+
* @param definition definition string
|
|
82
|
+
* @returns parsed definition, or null when it cannot be parsed
|
|
83
|
+
*/
|
|
84
|
+
export declare function parseObjectClass(definition: string): ObjectClassDefinition | null;
|
|
85
|
+
/**
|
|
86
|
+
* Parse an `ldapSyntaxes` definition.
|
|
87
|
+
*
|
|
88
|
+
* @param definition definition string
|
|
89
|
+
* @returns parsed definition, or null when it cannot be parsed
|
|
90
|
+
*/
|
|
91
|
+
export declare function parseSyntax(definition: string): SyntaxDefinition | null;
|
|
92
|
+
/**
|
|
93
|
+
* Parse a `matchingRules` definition.
|
|
94
|
+
*
|
|
95
|
+
* @param definition definition string
|
|
96
|
+
* @returns parsed definition, or null when it cannot be parsed
|
|
97
|
+
*/
|
|
98
|
+
export declare function parseMatchingRule(definition: string): MatchingRuleDefinition | null;
|
|
99
|
+
/**
|
|
100
|
+
* Parse the four definition lists of a subschema entry. Unparseable
|
|
101
|
+
* definitions are skipped rather than failing the whole schema.
|
|
102
|
+
*
|
|
103
|
+
* @param raw definition strings as read from the subschema entry
|
|
104
|
+
* @returns parsed schema
|
|
105
|
+
*/
|
|
106
|
+
export declare function parseSchema(raw: RawSchemaDefinitions): LdapSchema;
|
|
107
|
+
/**
|
|
108
|
+
* Indexed view of a schema, with the lookups a client needs: resolution of
|
|
109
|
+
* object class inheritance and detection of binary attributes.
|
|
110
|
+
*/
|
|
111
|
+
export declare class SchemaIndex {
|
|
112
|
+
readonly schema: LdapSchema;
|
|
113
|
+
private objectClassesByName;
|
|
114
|
+
private attributeTypesByName;
|
|
115
|
+
private syntaxesByOid;
|
|
116
|
+
constructor(schema: LdapSchema);
|
|
117
|
+
/**
|
|
118
|
+
* Look up an object class by name or OID (case-insensitive).
|
|
119
|
+
*
|
|
120
|
+
* @param name object class name or OID
|
|
121
|
+
* @returns the definition, or undefined when unknown
|
|
122
|
+
*/
|
|
123
|
+
getObjectClass(name: string): ObjectClassDefinition | undefined;
|
|
124
|
+
/**
|
|
125
|
+
* Look up an attribute type by name or OID (case-insensitive).
|
|
126
|
+
*
|
|
127
|
+
* @param name attribute name or OID
|
|
128
|
+
* @returns the definition, or undefined when unknown
|
|
129
|
+
*/
|
|
130
|
+
getAttributeType(name: string): AttributeTypeDefinition | undefined;
|
|
131
|
+
/**
|
|
132
|
+
* Resolve the syntax of an attribute, following the `SUP` chain when the
|
|
133
|
+
* attribute does not declare one itself.
|
|
134
|
+
*
|
|
135
|
+
* @param name attribute name or OID
|
|
136
|
+
* @returns syntax OID, or undefined when it cannot be resolved
|
|
137
|
+
*/
|
|
138
|
+
getAttributeSyntax(name: string): string | undefined;
|
|
139
|
+
/**
|
|
140
|
+
* Tell whether an attribute holds octets rather than text, and therefore
|
|
141
|
+
* must be base64-encoded in JSON.
|
|
142
|
+
*
|
|
143
|
+
* @param name attribute name, options included (`jpegPhoto;binary`)
|
|
144
|
+
* @returns true when values must be treated as binary
|
|
145
|
+
*/
|
|
146
|
+
isBinaryAttribute(name: string): boolean;
|
|
147
|
+
/**
|
|
148
|
+
* Collect the mandatory and optional attributes of a set of object classes,
|
|
149
|
+
* walking every `SUP` chain.
|
|
150
|
+
*
|
|
151
|
+
* @param objectClasses object class names carried by an entry
|
|
152
|
+
* @returns deduplicated `must` and `may` attribute names, `may` excluding
|
|
153
|
+
* anything already mandatory
|
|
154
|
+
*/
|
|
155
|
+
resolveAttributes(objectClasses: string[]): {
|
|
156
|
+
must: string[];
|
|
157
|
+
may: string[];
|
|
158
|
+
};
|
|
159
|
+
}
|