@the-software-compagny/parser_ldap_rfc4512 0.1.1 → 0.2.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/README.md +64 -0
- package/cli.js +54 -11
- package/index.js +54 -11
- package/package.json +2 -4
package/README.md
CHANGED
|
@@ -15,6 +15,7 @@ This project provides a comprehensive parser for LDAP (Lightweight Directory Acc
|
|
|
15
15
|
|
|
16
16
|
### 🔧 Complete RFC 4512 Parser
|
|
17
17
|
- **Full RFC 4512 Compliance**: Strictly follows the official LDAP schema definition format
|
|
18
|
+
- **OpenLDAP cn=config Support**: Automatically handles OpenLDAP index prefixes like `{57}`
|
|
18
19
|
- **Object Class Parsing**: Complete support for STRUCTURAL, AUXILIARY, and ABSTRACT object classes
|
|
19
20
|
- **Attribute Type Parsing**: Comprehensive parsing of attribute types with all their properties
|
|
20
21
|
- **OID Validation**: Robust validation of numeric object identifiers
|
|
@@ -184,6 +185,69 @@ Complete support for attribute type definitions:
|
|
|
184
185
|
)
|
|
185
186
|
```
|
|
186
187
|
|
|
188
|
+
## 🔧 OpenLDAP cn=config Support
|
|
189
|
+
|
|
190
|
+
The parser includes built-in support for OpenLDAP's `cn=config` format, which uses index prefixes to maintain ordering of multi-valued attributes like `olcAttributeTypes` and `olcObjectClasses`.
|
|
191
|
+
|
|
192
|
+
### Index Prefix Support
|
|
193
|
+
|
|
194
|
+
OpenLDAP uses numeric prefixes in curly braces to maintain the order of schema definitions:
|
|
195
|
+
|
|
196
|
+
```ldap
|
|
197
|
+
# OpenLDAP cn=config format with index prefix
|
|
198
|
+
{57}( 1.3.6.1.4.1.7165.2.1.80 NAME 'sambaSupportedEncryptionTypes'
|
|
199
|
+
DESC 'Supported encryption types of a trust'
|
|
200
|
+
EQUALITY integerMatch
|
|
201
|
+
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
|
|
202
|
+
SINGLE-VALUE )
|
|
203
|
+
|
|
204
|
+
# Equivalent RFC 4512 pure format (without prefix)
|
|
205
|
+
( 1.3.6.1.4.1.7165.2.1.80 NAME 'sambaSupportedEncryptionTypes'
|
|
206
|
+
DESC 'Supported encryption types of a trust'
|
|
207
|
+
EQUALITY integerMatch
|
|
208
|
+
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
|
|
209
|
+
SINGLE-VALUE )
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### Automatic Prefix Removal
|
|
213
|
+
|
|
214
|
+
The parser automatically detects and removes OpenLDAP index prefixes:
|
|
215
|
+
|
|
216
|
+
```typescript
|
|
217
|
+
import { parseSchema } from '@the-software-compagny/parser_ldap_rfc4512'
|
|
218
|
+
|
|
219
|
+
// Both formats parse to identical results
|
|
220
|
+
const openLdapFormat = '{57}( 2.5.4.3 NAME \'cn\' DESC \'Common Name\' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )'
|
|
221
|
+
const rfc4512Format = '( 2.5.4.3 NAME \'cn\' DESC \'Common Name\' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )'
|
|
222
|
+
|
|
223
|
+
const result1 = parseSchema(openLdapFormat)
|
|
224
|
+
const result2 = parseSchema(rfc4512Format)
|
|
225
|
+
|
|
226
|
+
console.log(result1 === result2) // true - identical results
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### Supported Prefix Patterns
|
|
230
|
+
|
|
231
|
+
The parser handles various OpenLDAP prefix formats:
|
|
232
|
+
|
|
233
|
+
- **Basic format**: `{0}`, `{57}`, `{123}`
|
|
234
|
+
- **With whitespace**: ` {0} `, `\t{57}\t`
|
|
235
|
+
- **Leading spaces**: ` {0}(definition...)`
|
|
236
|
+
- **Any numeric index**: `{0}` to `{99999}` and beyond
|
|
237
|
+
|
|
238
|
+
### CLI Support for OpenLDAP Format
|
|
239
|
+
|
|
240
|
+
The CLI tool seamlessly handles OpenLDAP exports:
|
|
241
|
+
|
|
242
|
+
```bash
|
|
243
|
+
# Parse OpenLDAP cn=config exports directly
|
|
244
|
+
rfc4512-parser --input openldap-export.ldif --format json
|
|
245
|
+
|
|
246
|
+
# Example OpenLDAP export file content:
|
|
247
|
+
# {0}( 2.5.4.3 NAME 'cn' DESC 'Common Name' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
|
|
248
|
+
# {1}( 2.5.4.4 NAME 'sn' DESC 'Surname' SUP name )
|
|
249
|
+
```
|
|
250
|
+
|
|
187
251
|
## 🏗️ Project Architecture
|
|
188
252
|
|
|
189
253
|
```bash
|
package/cli.js
CHANGED
|
@@ -12760,21 +12760,46 @@ var __dirname = "/home/runner/work/parser_ldap_rfc4512/parser_ldap_rfc4512/src";
|
|
|
12760
12760
|
|
|
12761
12761
|
class RFC4512Parser {
|
|
12762
12762
|
_parser;
|
|
12763
|
-
|
|
12763
|
+
_options;
|
|
12764
|
+
constructor(options2, pegOptions) {
|
|
12765
|
+
this._options = {
|
|
12766
|
+
relaxedMode: false,
|
|
12767
|
+
...options2
|
|
12768
|
+
};
|
|
12764
12769
|
try {
|
|
12765
12770
|
const grammarPath = path.join(__dirname, "./_grammars/rfc4512.pegjs");
|
|
12766
12771
|
const grammar = readFileSync3(grammarPath, "utf-8");
|
|
12767
|
-
this._parser = import_peggy.generate(grammar,
|
|
12772
|
+
this._parser = import_peggy.generate(grammar, pegOptions);
|
|
12768
12773
|
} catch (error) {
|
|
12769
12774
|
throw new RFC4512ParserError(`Error loading grammar: ${error instanceof Error ? error.message : "Unknown error"}`, "GRAMMAR_LOAD_ERROR" /* GRAMMAR_LOAD_ERROR */, "", { cause: error instanceof Error ? error : undefined });
|
|
12770
12775
|
}
|
|
12771
12776
|
}
|
|
12777
|
+
removeOpenLDAPPrefix(schemaDefinition) {
|
|
12778
|
+
const openLdapPrefixPattern = /^\s*\{\d+\}\s*/;
|
|
12779
|
+
return schemaDefinition.replace(openLdapPrefixPattern, "").trim();
|
|
12780
|
+
}
|
|
12781
|
+
transformOpenLDAPOids(schemaDefinition) {
|
|
12782
|
+
if (!this._options.relaxedMode) {
|
|
12783
|
+
return schemaDefinition;
|
|
12784
|
+
}
|
|
12785
|
+
const openldapOidPattern = /\b(OLcfg(?:Ov|Db|Gl)(?:At|Oc)):([\d.]+)\b/g;
|
|
12786
|
+
return schemaDefinition.replace(openldapOidPattern, (match, prefix, suffix) => {
|
|
12787
|
+
return match;
|
|
12788
|
+
});
|
|
12789
|
+
}
|
|
12772
12790
|
parseSchema(schemaDefinition) {
|
|
12773
12791
|
try {
|
|
12774
|
-
|
|
12792
|
+
let cleanInput = this.removeOpenLDAPPrefix(schemaDefinition).trim();
|
|
12793
|
+
cleanInput = this.transformOpenLDAPOids(cleanInput);
|
|
12775
12794
|
if (!cleanInput) {
|
|
12776
12795
|
throw new RFC4512ParserError("Schema definition cannot be empty", "EMPTY_INPUT" /* EMPTY_INPUT */, schemaDefinition);
|
|
12777
12796
|
}
|
|
12797
|
+
if (!this._options.relaxedMode) {
|
|
12798
|
+
const openldapOidPattern = /\b(OLcfg(?:Ov|Db|Gl)(?:At|Oc)):([\d.]+)\b/;
|
|
12799
|
+
if (openldapOidPattern.test(cleanInput)) {
|
|
12800
|
+
throw new RFC4512ParserError("OpenLDAP configuration OIDs are not supported in strict RFC 4512 mode. Use relaxedMode: true to enable support.", "SYNTAX_ERROR" /* SYNTAX_ERROR */, schemaDefinition);
|
|
12801
|
+
}
|
|
12802
|
+
}
|
|
12778
12803
|
const parsed = this._parser.parse(cleanInput);
|
|
12779
12804
|
if (!parsed.oid) {
|
|
12780
12805
|
throw new RFC4512ParserError("Missing OID in schema definition", "MISSING_FIELD" /* MISSING_FIELD */, schemaDefinition, { context: "OID field is required for all LDAP schema definitions" });
|
|
@@ -12789,8 +12814,11 @@ class RFC4512Parser {
|
|
|
12789
12814
|
throw new RFC4512ParserError("ObjectClass must specify exactly one type: STRUCTURAL, AUXILIARY, or ABSTRACT", "OBJECTCLASS_ERROR" /* OBJECTCLASS_ERROR */, schemaDefinition, { context: "RFC 4512 Section 4.1.1 - ObjectClass type validation" });
|
|
12790
12815
|
}
|
|
12791
12816
|
const oidPattern = /^[0-9]+(\.[0-9]+)*$/;
|
|
12792
|
-
|
|
12793
|
-
|
|
12817
|
+
const openldapOidPattern = /^OLcfg(?:Ov|Db|Gl)(?:At|Oc):[0-9]+(\.[0-9]+)*$/;
|
|
12818
|
+
const isValidOid = this._options.relaxedMode ? oidPattern.test(objectClass.oid) || openldapOidPattern.test(objectClass.oid) : oidPattern.test(objectClass.oid);
|
|
12819
|
+
if (!isValidOid) {
|
|
12820
|
+
const validFormats = this._options.relaxedMode ? "dotted decimal notation (e.g., 2.5.6.6) or OpenLDAP configuration format (e.g., OLcfgOvAt:18.1)" : "dotted decimal notation (e.g., 2.5.6.6)";
|
|
12821
|
+
throw new RFC4512ParserError(`Invalid OID format: ${objectClass.oid}. Must follow ${validFormats}`, "INVALID_OID" /* INVALID_OID */, schemaDefinition, { context: `RFC 4512 - OID validation (relaxedMode: ${this._options.relaxedMode})` });
|
|
12794
12822
|
}
|
|
12795
12823
|
if (objectClass.sup && typeof objectClass.sup === "string") {
|
|
12796
12824
|
const reservedKeywords = ["STRUCTURAL", "AUXILIARY", "ABSTRACT", "MUST", "MAY", "DESC", "NAME", "OBSOLETE"];
|
|
@@ -12832,7 +12860,8 @@ class RFC4512Parser {
|
|
|
12832
12860
|
"sup",
|
|
12833
12861
|
"objectClassType",
|
|
12834
12862
|
"must",
|
|
12835
|
-
"may"
|
|
12863
|
+
"may",
|
|
12864
|
+
"extensions"
|
|
12836
12865
|
];
|
|
12837
12866
|
for (const key of Object.keys(objectClass)) {
|
|
12838
12867
|
if (!validObjectClassFields.includes(key)) {
|
|
@@ -12843,8 +12872,11 @@ class RFC4512Parser {
|
|
|
12843
12872
|
if (parsed.type === "attributeType") {
|
|
12844
12873
|
const attributeType = parsed;
|
|
12845
12874
|
const oidPattern = /^[0-9]+(\.[0-9]+)*$/;
|
|
12846
|
-
|
|
12847
|
-
|
|
12875
|
+
const openldapOidPattern = /^OLcfg(?:Ov|Db|Gl)(?:At|Oc):[0-9]+(\.[0-9]+)*$/;
|
|
12876
|
+
const isValidOid = this._options.relaxedMode ? oidPattern.test(attributeType.oid) || openldapOidPattern.test(attributeType.oid) : oidPattern.test(attributeType.oid);
|
|
12877
|
+
if (!isValidOid) {
|
|
12878
|
+
const validFormats = this._options.relaxedMode ? "dotted decimal notation (e.g., 2.5.4.3) or OpenLDAP configuration format (e.g., OLcfgOvAt:18.1)" : "dotted decimal notation (e.g., 2.5.4.3)";
|
|
12879
|
+
throw new RFC4512ParserError(`Invalid OID format: ${attributeType.oid}. Must follow ${validFormats}`, "INVALID_OID" /* INVALID_OID */, schemaDefinition, { context: `RFC 4512 - OID validation (relaxedMode: ${this._options.relaxedMode})` });
|
|
12848
12880
|
}
|
|
12849
12881
|
if (attributeType.sup && typeof attributeType.sup === "string") {
|
|
12850
12882
|
const reservedKeywords = ["EQUALITY", "ORDERING", "SUBSTR", "SYNTAX", "SINGLE-VALUE", "COLLECTIVE", "NO-USER-MODIFICATION", "USAGE"];
|
|
@@ -12855,6 +12887,13 @@ class RFC4512Parser {
|
|
|
12855
12887
|
if (!attributeType.sup && !attributeType.syntax) {
|
|
12856
12888
|
throw new RFC4512ParserError("AttributeType must have either SUP (superior type) or SYNTAX defined", "ATTRIBUTETYPE_ERROR" /* ATTRIBUTETYPE_ERROR */, schemaDefinition, { context: "RFC 4512 Section 4.1.2 - AttributeType must inherit from superior or define syntax" });
|
|
12857
12889
|
}
|
|
12890
|
+
if (attributeType.syntax && !this._options.relaxedMode) {
|
|
12891
|
+
const syntaxOid = attributeType.syntax.oid;
|
|
12892
|
+
const standardOidPattern = /^[0-9]+(\.[0-9]+)*$/;
|
|
12893
|
+
if (!standardOidPattern.test(syntaxOid)) {
|
|
12894
|
+
throw new RFC4512ParserError(`Invalid SYNTAX OID format: ${syntaxOid}. In strict mode, SYNTAX must use standard numeric OID format (e.g., '1.3.6.1.4.1.1466.115.121.1.15'). Use relaxedMode: true to support OpenLDAP syntax names.`, "INVALID_FIELD" /* INVALID_FIELD */, schemaDefinition, { context: `RFC 4512 - SYNTAX validation (relaxedMode: ${this._options.relaxedMode})` });
|
|
12895
|
+
}
|
|
12896
|
+
}
|
|
12858
12897
|
const validAttributeTypeFields = [
|
|
12859
12898
|
"type",
|
|
12860
12899
|
"oid",
|
|
@@ -12868,7 +12907,8 @@ class RFC4512Parser {
|
|
|
12868
12907
|
"singleValue",
|
|
12869
12908
|
"collective",
|
|
12870
12909
|
"noUserModification",
|
|
12871
|
-
"usage"
|
|
12910
|
+
"usage",
|
|
12911
|
+
"extensions"
|
|
12872
12912
|
];
|
|
12873
12913
|
for (const key of Object.keys(attributeType)) {
|
|
12874
12914
|
if (!validAttributeTypeFields.includes(key)) {
|
|
@@ -12917,12 +12957,15 @@ class RFC4512Parser {
|
|
|
12917
12957
|
return null;
|
|
12918
12958
|
}
|
|
12919
12959
|
}
|
|
12960
|
+
get options() {
|
|
12961
|
+
return { ...this._options };
|
|
12962
|
+
}
|
|
12920
12963
|
}
|
|
12921
12964
|
var rfc4512_parser_default = RFC4512Parser;
|
|
12922
12965
|
|
|
12923
12966
|
// src/functions/parse-schema.function.ts
|
|
12924
|
-
function parseSchema(schemaDefinition, options2) {
|
|
12925
|
-
const parser2 = new rfc4512_parser_default(options2);
|
|
12967
|
+
function parseSchema(schemaDefinition, options2, pegOptions) {
|
|
12968
|
+
const parser2 = new rfc4512_parser_default(options2, pegOptions);
|
|
12926
12969
|
return parser2.parseSchema(schemaDefinition);
|
|
12927
12970
|
}
|
|
12928
12971
|
// src/logger.ts
|
package/index.js
CHANGED
|
@@ -7916,21 +7916,46 @@ var __dirname = "/home/runner/work/parser_ldap_rfc4512/parser_ldap_rfc4512/src";
|
|
|
7916
7916
|
|
|
7917
7917
|
class RFC4512Parser {
|
|
7918
7918
|
_parser;
|
|
7919
|
-
|
|
7919
|
+
_options;
|
|
7920
|
+
constructor(options2, pegOptions) {
|
|
7921
|
+
this._options = {
|
|
7922
|
+
relaxedMode: false,
|
|
7923
|
+
...options2
|
|
7924
|
+
};
|
|
7920
7925
|
try {
|
|
7921
7926
|
const grammarPath = path.join(__dirname, "./_grammars/rfc4512.pegjs");
|
|
7922
7927
|
const grammar = readFileSync(grammarPath, "utf-8");
|
|
7923
|
-
this._parser = import_peggy.generate(grammar,
|
|
7928
|
+
this._parser = import_peggy.generate(grammar, pegOptions);
|
|
7924
7929
|
} catch (error) {
|
|
7925
7930
|
throw new RFC4512ParserError(`Error loading grammar: ${error instanceof Error ? error.message : "Unknown error"}`, "GRAMMAR_LOAD_ERROR" /* GRAMMAR_LOAD_ERROR */, "", { cause: error instanceof Error ? error : undefined });
|
|
7926
7931
|
}
|
|
7927
7932
|
}
|
|
7933
|
+
removeOpenLDAPPrefix(schemaDefinition) {
|
|
7934
|
+
const openLdapPrefixPattern = /^\s*\{\d+\}\s*/;
|
|
7935
|
+
return schemaDefinition.replace(openLdapPrefixPattern, "").trim();
|
|
7936
|
+
}
|
|
7937
|
+
transformOpenLDAPOids(schemaDefinition) {
|
|
7938
|
+
if (!this._options.relaxedMode) {
|
|
7939
|
+
return schemaDefinition;
|
|
7940
|
+
}
|
|
7941
|
+
const openldapOidPattern = /\b(OLcfg(?:Ov|Db|Gl)(?:At|Oc)):([\d.]+)\b/g;
|
|
7942
|
+
return schemaDefinition.replace(openldapOidPattern, (match, prefix, suffix) => {
|
|
7943
|
+
return match;
|
|
7944
|
+
});
|
|
7945
|
+
}
|
|
7928
7946
|
parseSchema(schemaDefinition) {
|
|
7929
7947
|
try {
|
|
7930
|
-
|
|
7948
|
+
let cleanInput = this.removeOpenLDAPPrefix(schemaDefinition).trim();
|
|
7949
|
+
cleanInput = this.transformOpenLDAPOids(cleanInput);
|
|
7931
7950
|
if (!cleanInput) {
|
|
7932
7951
|
throw new RFC4512ParserError("Schema definition cannot be empty", "EMPTY_INPUT" /* EMPTY_INPUT */, schemaDefinition);
|
|
7933
7952
|
}
|
|
7953
|
+
if (!this._options.relaxedMode) {
|
|
7954
|
+
const openldapOidPattern = /\b(OLcfg(?:Ov|Db|Gl)(?:At|Oc)):([\d.]+)\b/;
|
|
7955
|
+
if (openldapOidPattern.test(cleanInput)) {
|
|
7956
|
+
throw new RFC4512ParserError("OpenLDAP configuration OIDs are not supported in strict RFC 4512 mode. Use relaxedMode: true to enable support.", "SYNTAX_ERROR" /* SYNTAX_ERROR */, schemaDefinition);
|
|
7957
|
+
}
|
|
7958
|
+
}
|
|
7934
7959
|
const parsed = this._parser.parse(cleanInput);
|
|
7935
7960
|
if (!parsed.oid) {
|
|
7936
7961
|
throw new RFC4512ParserError("Missing OID in schema definition", "MISSING_FIELD" /* MISSING_FIELD */, schemaDefinition, { context: "OID field is required for all LDAP schema definitions" });
|
|
@@ -7945,8 +7970,11 @@ class RFC4512Parser {
|
|
|
7945
7970
|
throw new RFC4512ParserError("ObjectClass must specify exactly one type: STRUCTURAL, AUXILIARY, or ABSTRACT", "OBJECTCLASS_ERROR" /* OBJECTCLASS_ERROR */, schemaDefinition, { context: "RFC 4512 Section 4.1.1 - ObjectClass type validation" });
|
|
7946
7971
|
}
|
|
7947
7972
|
const oidPattern = /^[0-9]+(\.[0-9]+)*$/;
|
|
7948
|
-
|
|
7949
|
-
|
|
7973
|
+
const openldapOidPattern = /^OLcfg(?:Ov|Db|Gl)(?:At|Oc):[0-9]+(\.[0-9]+)*$/;
|
|
7974
|
+
const isValidOid = this._options.relaxedMode ? oidPattern.test(objectClass.oid) || openldapOidPattern.test(objectClass.oid) : oidPattern.test(objectClass.oid);
|
|
7975
|
+
if (!isValidOid) {
|
|
7976
|
+
const validFormats = this._options.relaxedMode ? "dotted decimal notation (e.g., 2.5.6.6) or OpenLDAP configuration format (e.g., OLcfgOvAt:18.1)" : "dotted decimal notation (e.g., 2.5.6.6)";
|
|
7977
|
+
throw new RFC4512ParserError(`Invalid OID format: ${objectClass.oid}. Must follow ${validFormats}`, "INVALID_OID" /* INVALID_OID */, schemaDefinition, { context: `RFC 4512 - OID validation (relaxedMode: ${this._options.relaxedMode})` });
|
|
7950
7978
|
}
|
|
7951
7979
|
if (objectClass.sup && typeof objectClass.sup === "string") {
|
|
7952
7980
|
const reservedKeywords = ["STRUCTURAL", "AUXILIARY", "ABSTRACT", "MUST", "MAY", "DESC", "NAME", "OBSOLETE"];
|
|
@@ -7988,7 +8016,8 @@ class RFC4512Parser {
|
|
|
7988
8016
|
"sup",
|
|
7989
8017
|
"objectClassType",
|
|
7990
8018
|
"must",
|
|
7991
|
-
"may"
|
|
8019
|
+
"may",
|
|
8020
|
+
"extensions"
|
|
7992
8021
|
];
|
|
7993
8022
|
for (const key of Object.keys(objectClass)) {
|
|
7994
8023
|
if (!validObjectClassFields.includes(key)) {
|
|
@@ -7999,8 +8028,11 @@ class RFC4512Parser {
|
|
|
7999
8028
|
if (parsed.type === "attributeType") {
|
|
8000
8029
|
const attributeType = parsed;
|
|
8001
8030
|
const oidPattern = /^[0-9]+(\.[0-9]+)*$/;
|
|
8002
|
-
|
|
8003
|
-
|
|
8031
|
+
const openldapOidPattern = /^OLcfg(?:Ov|Db|Gl)(?:At|Oc):[0-9]+(\.[0-9]+)*$/;
|
|
8032
|
+
const isValidOid = this._options.relaxedMode ? oidPattern.test(attributeType.oid) || openldapOidPattern.test(attributeType.oid) : oidPattern.test(attributeType.oid);
|
|
8033
|
+
if (!isValidOid) {
|
|
8034
|
+
const validFormats = this._options.relaxedMode ? "dotted decimal notation (e.g., 2.5.4.3) or OpenLDAP configuration format (e.g., OLcfgOvAt:18.1)" : "dotted decimal notation (e.g., 2.5.4.3)";
|
|
8035
|
+
throw new RFC4512ParserError(`Invalid OID format: ${attributeType.oid}. Must follow ${validFormats}`, "INVALID_OID" /* INVALID_OID */, schemaDefinition, { context: `RFC 4512 - OID validation (relaxedMode: ${this._options.relaxedMode})` });
|
|
8004
8036
|
}
|
|
8005
8037
|
if (attributeType.sup && typeof attributeType.sup === "string") {
|
|
8006
8038
|
const reservedKeywords = ["EQUALITY", "ORDERING", "SUBSTR", "SYNTAX", "SINGLE-VALUE", "COLLECTIVE", "NO-USER-MODIFICATION", "USAGE"];
|
|
@@ -8011,6 +8043,13 @@ class RFC4512Parser {
|
|
|
8011
8043
|
if (!attributeType.sup && !attributeType.syntax) {
|
|
8012
8044
|
throw new RFC4512ParserError("AttributeType must have either SUP (superior type) or SYNTAX defined", "ATTRIBUTETYPE_ERROR" /* ATTRIBUTETYPE_ERROR */, schemaDefinition, { context: "RFC 4512 Section 4.1.2 - AttributeType must inherit from superior or define syntax" });
|
|
8013
8045
|
}
|
|
8046
|
+
if (attributeType.syntax && !this._options.relaxedMode) {
|
|
8047
|
+
const syntaxOid = attributeType.syntax.oid;
|
|
8048
|
+
const standardOidPattern = /^[0-9]+(\.[0-9]+)*$/;
|
|
8049
|
+
if (!standardOidPattern.test(syntaxOid)) {
|
|
8050
|
+
throw new RFC4512ParserError(`Invalid SYNTAX OID format: ${syntaxOid}. In strict mode, SYNTAX must use standard numeric OID format (e.g., '1.3.6.1.4.1.1466.115.121.1.15'). Use relaxedMode: true to support OpenLDAP syntax names.`, "INVALID_FIELD" /* INVALID_FIELD */, schemaDefinition, { context: `RFC 4512 - SYNTAX validation (relaxedMode: ${this._options.relaxedMode})` });
|
|
8051
|
+
}
|
|
8052
|
+
}
|
|
8014
8053
|
const validAttributeTypeFields = [
|
|
8015
8054
|
"type",
|
|
8016
8055
|
"oid",
|
|
@@ -8024,7 +8063,8 @@ class RFC4512Parser {
|
|
|
8024
8063
|
"singleValue",
|
|
8025
8064
|
"collective",
|
|
8026
8065
|
"noUserModification",
|
|
8027
|
-
"usage"
|
|
8066
|
+
"usage",
|
|
8067
|
+
"extensions"
|
|
8028
8068
|
];
|
|
8029
8069
|
for (const key of Object.keys(attributeType)) {
|
|
8030
8070
|
if (!validAttributeTypeFields.includes(key)) {
|
|
@@ -8073,12 +8113,15 @@ class RFC4512Parser {
|
|
|
8073
8113
|
return null;
|
|
8074
8114
|
}
|
|
8075
8115
|
}
|
|
8116
|
+
get options() {
|
|
8117
|
+
return { ...this._options };
|
|
8118
|
+
}
|
|
8076
8119
|
}
|
|
8077
8120
|
var rfc4512_parser_default = RFC4512Parser;
|
|
8078
8121
|
|
|
8079
8122
|
// src/functions/parse-schema.function.ts
|
|
8080
|
-
function parseSchema(schemaDefinition, options2) {
|
|
8081
|
-
const parser = new rfc4512_parser_default(options2);
|
|
8123
|
+
function parseSchema(schemaDefinition, options2, pegOptions) {
|
|
8124
|
+
const parser = new rfc4512_parser_default(options2, pegOptions);
|
|
8082
8125
|
return parser.parseSchema(schemaDefinition);
|
|
8083
8126
|
}
|
|
8084
8127
|
export {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@the-software-compagny/parser_ldap_rfc4512",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "A TypeScript parser for LDAP schema definitions based on RFC 4512, using PEG.js grammar",
|
|
5
5
|
"repository": "https://github.com/The-Software-Compagny/parser_ldap_rfc4512.git",
|
|
6
6
|
"author": "tacxou <12997062+tacxou@users.noreply.github.com> (https://github.com/tacxou)",
|
|
@@ -26,9 +26,7 @@
|
|
|
26
26
|
"postbuild": "cpr README.md dist/README.md && cpr LICENSE dist/LICENSE && cpr package.json dist/package.json",
|
|
27
27
|
"test": "bun test",
|
|
28
28
|
"test:watch": "bun test --watch",
|
|
29
|
-
"test:cli": "bun test test/cli.test.ts"
|
|
30
|
-
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
|
|
31
|
-
"format:check": "prettier --check \"src/**/*.ts\" \"test/**/*.ts\""
|
|
29
|
+
"test:cli": "bun test test/cli.test.ts"
|
|
32
30
|
},
|
|
33
31
|
"devDependencies": {
|
|
34
32
|
"@types/bun": "latest",
|