tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

Attribute.ts (4414B)


      1 import * as asn1js from "asn1js";
      2 import * as pvutils from "pvutils";
      3 import { EMPTY_STRING } from "./constants";
      4 import { AsnError } from "./errors";
      5 import { PkiObject, PkiObjectParameters } from "./PkiObject";
      6 import * as Schema from "./Schema";
      7 
      8 const TYPE = "type";
      9 const VALUES = "values";
     10 const CLEAR_PROPS = [
     11  TYPE,
     12  VALUES
     13 ];
     14 
     15 export interface IAttribute {
     16  /**
     17   * Specifies type of attribute value
     18   */
     19  type: string;
     20  /**
     21   * List of attribute values
     22   */
     23  values: any[];
     24 }
     25 
     26 export type AttributeParameters = PkiObjectParameters & Partial<IAttribute>;
     27 
     28 export type AttributeSchema = Schema.SchemaParameters<{
     29  setName?: string;
     30  type?: string;
     31  values?: string;
     32 }>;
     33 
     34 export interface AttributeJson {
     35  type: string;
     36  values: any[];
     37 }
     38 
     39 /**
     40 * Represents the Attribute structure described in [RFC2986](https://datatracker.ietf.org/doc/html/rfc2986)
     41 */
     42 export class Attribute extends PkiObject implements IAttribute {
     43 
     44  public static override CLASS_NAME = "Attribute";
     45 
     46  public type!: string;
     47  public values!: any[];
     48 
     49  /**
     50   * Initializes a new instance of the {@link Attribute} class
     51   * @param parameters Initialization parameters
     52   */
     53  constructor(parameters: AttributeParameters = {}) {
     54    super();
     55 
     56    this.type = pvutils.getParametersValue(parameters, TYPE, Attribute.defaultValues(TYPE));
     57    this.values = pvutils.getParametersValue(parameters, VALUES, Attribute.defaultValues(VALUES));
     58 
     59    if (parameters.schema) {
     60      this.fromSchema(parameters.schema);
     61    }
     62  }
     63 
     64  /**
     65   * Returns default values for all class members
     66   * @param memberName String name for a class member
     67   * @returns Default value
     68   */
     69  public static override defaultValues(memberName: typeof TYPE): string;
     70  public static override defaultValues(memberName: typeof VALUES): any[];
     71  public static override defaultValues(memberName: string): any {
     72    switch (memberName) {
     73      case TYPE:
     74        return EMPTY_STRING;
     75      case VALUES:
     76        return [];
     77      default:
     78        return super.defaultValues(memberName);
     79    }
     80  }
     81 
     82  /**
     83   * Compares values with default values for all class members
     84   * @param memberName String name for a class member
     85   * @param memberValue Value to compare with default value
     86   */
     87  public static compareWithDefault(memberName: string, memberValue: any): boolean {
     88    switch (memberName) {
     89      case TYPE:
     90        return (memberValue === EMPTY_STRING);
     91      case VALUES:
     92        return (memberValue.length === 0);
     93      default:
     94        return super.defaultValues(memberName);
     95    }
     96  }
     97 
     98  /**
     99   * @inheritdoc
    100   * @asn ASN.1 schema
    101   * ```asn
    102   * Attribute { ATTRIBUTE:IOSet } ::= SEQUENCE {
    103   *    type   ATTRIBUTE.&id({IOSet}),
    104   *    values SET SIZE(1..MAX) OF ATTRIBUTE.&Type({IOSet}{@type})
    105   * }
    106   *```
    107   */
    108  public static override schema(parameters: AttributeSchema = {}) {
    109    const names = pvutils.getParametersValue<NonNullable<typeof parameters.names>>(parameters, "names", {});
    110 
    111    return (new asn1js.Sequence({
    112      name: (names.blockName || EMPTY_STRING),
    113      value: [
    114        new asn1js.ObjectIdentifier({ name: (names.type || EMPTY_STRING) }),
    115        new asn1js.Set({
    116          name: (names.setName || EMPTY_STRING),
    117          value: [
    118            new asn1js.Repeated({
    119              name: (names.values || EMPTY_STRING),
    120              value: new asn1js.Any()
    121            })
    122          ]
    123        })
    124      ]
    125    }));
    126  }
    127 
    128  public fromSchema(schema: Schema.SchemaType): void {
    129    // Clear input data first
    130    pvutils.clearProps(schema, CLEAR_PROPS);
    131 
    132    // Check the schema is valid
    133    const asn1 = asn1js.compareSchema(schema,
    134      schema,
    135      Attribute.schema({
    136        names: {
    137          type: TYPE,
    138          values: VALUES
    139        }
    140      })
    141    );
    142    AsnError.assertSchema(asn1, this.className);
    143 
    144    // Get internal properties from parsed schema
    145    this.type = asn1.result.type.valueBlock.toString();
    146    this.values = asn1.result.values;
    147  }
    148 
    149  public toSchema(): asn1js.Sequence {
    150    //#region Construct and return new ASN.1 schema for this object
    151    return (new asn1js.Sequence({
    152      value: [
    153        new asn1js.ObjectIdentifier({ value: this.type }),
    154        new asn1js.Set({
    155          value: this.values
    156        })
    157      ]
    158    }));
    159    //#endregion
    160  }
    161 
    162  public toJSON(): AttributeJson {
    163    return {
    164      type: this.type,
    165      values: Array.from(this.values, o => o.toJSON())
    166    };
    167  }
    168 
    169 }