Comparing version 1.0.2 to 1.1.0
@@ -1,12 +0,14 @@ | ||
{"/home/alexxgrib/Projects/otp/src/base32.ts": {"path":"/home/alexxgrib/Projects/otp/src/base32.ts","statementMap":{"0":{"start":{"line":3,"column":18},"end":{"line":3,"column":52}},"1":{"start":{"line":4,"column":18},"end":{"line":12,"column":2}},"2":{"start":{"line":21,"column":19},"end":{"line":21,"column":48}},"3":{"start":{"line":22,"column":2},"end":{"line":22,"column":59}},"4":{"start":{"line":33,"column":14},"end":{"line":33,"column":15}},"5":{"start":{"line":34,"column":15},"end":{"line":34,"column":16}},"6":{"start":{"line":35,"column":19},"end":{"line":35,"column":20}},"7":{"start":{"line":36,"column":14},"end":{"line":36,"column":15}},"8":{"start":{"line":37,"column":18},"end":{"line":37,"column":73}},"9":{"start":{"line":40,"column":2},"end":{"line":57,"column":null}},"10":{"start":{"line":41,"column":20},"end":{"line":41,"column":33}},"11":{"start":{"line":42,"column":4},"end":{"line":54,"column":null}},"12":{"start":{"line":43,"column":6},"end":{"line":43,"column":45}},"13":{"start":{"line":44,"column":6},"end":{"line":44,"column":40}},"14":{"start":{"line":45,"column":6},"end":{"line":48,"column":28}},"15":{"start":{"line":49,"column":6},"end":{"line":49,"column":14}},"16":{"start":{"line":51,"column":6},"end":{"line":51,"column":57}},"17":{"start":{"line":52,"column":6},"end":{"line":52,"column":40}},"18":{"start":{"line":53,"column":6},"end":{"line":53,"column":36}},"19":{"start":{"line":53,"column":28},"end":{"line":53,"column":36}},"20":{"start":{"line":55,"column":4},"end":{"line":55,"column":52}},"21":{"start":{"line":56,"column":4},"end":{"line":56,"column":13}},"22":{"start":{"line":58,"column":2},"end":{"line":60,"column":null}},"23":{"start":{"line":59,"column":4},"end":{"line":59,"column":26}},"24":{"start":{"line":62,"column":2},"end":{"line":62,"column":42}},"25":{"start":{"line":32,"column":0},"end":{"line":32,"column":16}},"26":{"start":{"line":73,"column":19},"end":{"line":73,"column":20}},"27":{"start":{"line":74,"column":19},"end":{"line":74,"column":20}},"28":{"start":{"line":75,"column":18},"end":{"line":75,"column":19}},"29":{"start":{"line":76,"column":17},"end":{"line":76,"column":18}},"30":{"start":{"line":78,"column":18},"end":{"line":78,"column":69}},"31":{"start":{"line":79,"column":16},"end":{"line":79,"column":68}},"32":{"start":{"line":79,"column":48},"end":{"line":79,"column":67}},"33":{"start":{"line":83,"column":2},"end":{"line":111,"column":null}},"34":{"start":{"line":83,"column":19},"end":{"line":83,"column":20}},"35":{"start":{"line":84,"column":4},"end":{"line":87,"column":null}},"36":{"start":{"line":86,"column":6},"end":{"line":86,"column":12}},"37":{"start":{"line":88,"column":24},"end":{"line":88,"column":44}},"38":{"start":{"line":89,"column":4},"end":{"line":110,"column":null}},"39":{"start":{"line":90,"column":6},"end":{"line":90,"column":43}},"40":{"start":{"line":91,"column":6},"end":{"line":107,"column":null}},"41":{"start":{"line":92,"column":8},"end":{"line":92,"column":42}},"42":{"start":{"line":93,"column":8},"end":{"line":100,"column":null}},"43":{"start":{"line":94,"column":10},"end":{"line":94,"column":34}},"44":{"start":{"line":95,"column":10},"end":{"line":95,"column":40}},"45":{"start":{"line":96,"column":10},"end":{"line":96,"column":21}},"46":{"start":{"line":97,"column":10},"end":{"line":97,"column":24}},"47":{"start":{"line":99,"column":10},"end":{"line":99,"column":63}},"48":{"start":{"line":102,"column":8},"end":{"line":102,"column":42}},"49":{"start":{"line":103,"column":8},"end":{"line":103,"column":56}},"50":{"start":{"line":104,"column":8},"end":{"line":104,"column":38}},"51":{"start":{"line":105,"column":8},"end":{"line":105,"column":19}},"52":{"start":{"line":106,"column":8},"end":{"line":106,"column":60}},"53":{"start":{"line":109,"column":6},"end":{"line":109,"column":73}},"54":{"start":{"line":112,"column":2},"end":{"line":112,"column":36}},"55":{"start":{"line":72,"column":0},"end":{"line":72,"column":16}}},"fnMap":{"0":{"name":"quintetCount","decl":{"start":{"line":20,"column":9},"end":{"line":20,"column":21}},"loc":{"start":{"line":20,"column":40},"end":{"line":23,"column":1}}},"1":{"name":"encode","decl":{"start":{"line":32,"column":16},"end":{"line":32,"column":22}},"loc":{"start":{"line":32,"column":40},"end":{"line":63,"column":1}}},"2":{"name":"decode","decl":{"start":{"line":72,"column":16},"end":{"line":72,"column":22}},"loc":{"start":{"line":72,"column":38},"end":{"line":113,"column":1}}},"3":{"name":"(anonymous_3)","decl":{"start":{"line":79,"column":38},"end":{"line":79,"column":39}},"loc":{"start":{"line":79,"column":48},"end":{"line":79,"column":67}}}},"branchMap":{"0":{"loc":{"start":{"line":22,"column":9},"end":{"line":22,"column":58}},"type":"cond-expr","locations":[{"start":{"line":22,"column":35},"end":{"line":22,"column":43}},{"start":{"line":22,"column":46},"end":{"line":22,"column":58}}]},"1":{"loc":{"start":{"line":42,"column":4},"end":{"line":54,"column":null}},"type":"if","locations":[{"start":{"line":42,"column":4},"end":{"line":54,"column":null}},{"start":{"line":50,"column":11},"end":{"line":54,"column":null}}]},"2":{"loc":{"start":{"line":47,"column":10},"end":{"line":47,"column":58}},"type":"cond-expr","locations":[{"start":{"line":47,"column":37},"end":{"line":47,"column":54}},{"start":{"line":47,"column":57},"end":{"line":47,"column":58}}]},"3":{"loc":{"start":{"line":53,"column":6},"end":{"line":53,"column":36}},"type":"if","locations":[{"start":{"line":53,"column":6},"end":{"line":53,"column":36}}]},"4":{"loc":{"start":{"line":84,"column":4},"end":{"line":87,"column":null}},"type":"if","locations":[{"start":{"line":84,"column":4},"end":{"line":87,"column":null}}]},"5":{"loc":{"start":{"line":89,"column":4},"end":{"line":110,"column":null}},"type":"if","locations":[{"start":{"line":89,"column":4},"end":{"line":110,"column":null}},{"start":{"line":108,"column":11},"end":{"line":110,"column":null}}]},"6":{"loc":{"start":{"line":91,"column":6},"end":{"line":107,"column":null}},"type":"if","locations":[{"start":{"line":91,"column":6},"end":{"line":107,"column":null}},{"start":{"line":101,"column":13},"end":{"line":107,"column":null}}]},"7":{"loc":{"start":{"line":93,"column":8},"end":{"line":100,"column":null}},"type":"if","locations":[{"start":{"line":93,"column":8},"end":{"line":100,"column":null}},{"start":{"line":98,"column":15},"end":{"line":100,"column":null}}]}},"s":{"0":4,"1":4,"2":4,"3":4,"4":4,"5":4,"6":4,"7":4,"8":4,"9":4,"10":80,"11":80,"12":40,"13":40,"14":40,"15":40,"16":40,"17":40,"18":40,"19":10,"20":80,"21":80,"22":4,"23":0,"24":4,"25":4,"26":1,"27":1,"28":1,"29":1,"30":1,"31":1,"32":32,"33":1,"34":1,"35":32,"36":0,"37":32,"38":32,"39":32,"40":32,"41":16,"42":16,"43":4,"44":4,"45":4,"46":4,"47":12,"48":16,"49":16,"50":16,"51":16,"52":16,"53":0,"54":1,"55":4},"f":{"0":4,"1":4,"2":1,"3":32},"b":{"0":[4,0],"1":[40,40],"2":[40,0],"3":[10],"4":[0],"5":[32,0],"6":[16,16],"7":[4,12]}} | ||
,"/home/alexxgrib/Projects/otp/src/crypto-node.ts": {"path":"/home/alexxgrib/Projects/otp/src/crypto-node.ts","statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":9}},"1":{"start":{"line":1,"column":9},"end":{"line":1,"column":15}},"2":{"start":{"line":1,"column":15},"end":{"line":1,"column":50}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":1,"column":9},"end":{"line":1,"column":13}},"loc":{"start":{"line":1,"column":9},"end":{"line":1,"column":15}}},"1":{"name":"(anonymous_1)","decl":{"start":{"line":1,"column":15},"end":{"line":1,"column":26}},"loc":{"start":{"line":1,"column":15},"end":{"line":1,"column":50}}}},"branchMap":{},"s":{"0":4,"1":20,"2":7},"f":{"0":16,"1":3},"b":{}} | ||
,"/home/alexxgrib/Projects/otp/src/hotp.options.ts": {"path":"/home/alexxgrib/Projects/otp/src/hotp.options.ts","statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":46}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":34}},"2":{"start":{"line":18,"column":2},"end":{"line":23,"column":4}},"3":{"start":{"line":17,"column":0},"end":{"line":17,"column":16}}},"fnMap":{"0":{"name":"getDefaultHOTPOptions","decl":{"start":{"line":17,"column":16},"end":{"line":17,"column":37}},"loc":{"start":{"line":17,"column":37},"end":{"line":24,"column":1}}}},"branchMap":{},"s":{"0":4,"1":4,"2":17,"3":4},"f":{"0":17},"b":{}} | ||
,"/home/alexxgrib/Projects/otp/src/hotp.ts": {"path":"/home/alexxgrib/Projects/otp/src/hotp.ts","statementMap":{"0":{"start":{"line":4,"column":0},"end":{"line":4,"column":68}},"1":{"start":{"line":13,"column":2},"end":{"line":15,"column":null}},"2":{"start":{"line":14,"column":4},"end":{"line":14,"column":49}},"3":{"start":{"line":17,"column":16},"end":{"line":17,"column":46}},"4":{"start":{"line":19,"column":2},"end":{"line":22,"column":null}},"5":{"start":{"line":19,"column":19},"end":{"line":19,"column":20}},"6":{"start":{"line":20,"column":19},"end":{"line":20,"column":54}},"7":{"start":{"line":21,"column":4},"end":{"line":21,"column":47}},"8":{"start":{"line":24,"column":2},"end":{"line":24,"column":15}},"9":{"start":{"line":36,"column":14},"end":{"line":36,"column":59}},"10":{"start":{"line":38,"column":21},"end":{"line":38,"column":66}},"11":{"start":{"line":39,"column":17},"end":{"line":42,"column":null}},"12":{"start":{"line":45,"column":17},"end":{"line":45,"column":49}},"13":{"start":{"line":47,"column":4},"end":{"line":50,"column":32}},"14":{"start":{"line":51,"column":16},"end":{"line":51,"column":44}},"15":{"start":{"line":52,"column":2},"end":{"line":52,"column":55}},"16":{"start":{"line":35,"column":0},"end":{"line":35,"column":7}}},"fnMap":{"0":{"name":"hexToBytes","decl":{"start":{"line":12,"column":9},"end":{"line":12,"column":19}},"loc":{"start":{"line":12,"column":31},"end":{"line":25,"column":1}}},"1":{"name":"hotp","decl":{"start":{"line":35,"column":22},"end":{"line":35,"column":26}},"loc":{"start":{"line":35,"column":59},"end":{"line":53,"column":1}}}},"branchMap":{"0":{"loc":{"start":{"line":13,"column":2},"end":{"line":15,"column":null}},"type":"if","locations":[{"start":{"line":13,"column":2},"end":{"line":15,"column":null}}]}},"s":{"0":4,"1":16,"2":0,"3":16,"4":16,"5":16,"6":128,"7":128,"8":16,"9":16,"10":16,"11":16,"12":16,"13":16,"14":16,"15":16,"16":4},"f":{"0":16,"1":16},"b":{"0":[0]}} | ||
,"/home/alexxgrib/Projects/otp/src/index.ts": {"path":"/home/alexxgrib/Projects/otp/src/index.ts","statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":9}},"1":{"start":{"line":1,"column":9},"end":{"line":1,"column":34}},"2":{"start":{"line":2,"column":0},"end":{"line":2,"column":9}},"3":{"start":{"line":2,"column":9},"end":{"line":2,"column":20}},"4":{"start":{"line":2,"column":20},"end":{"line":2,"column":33}},"5":{"start":{"line":2,"column":33},"end":{"line":2,"column":66}},"6":{"start":{"line":3,"column":0},"end":{"line":3,"column":52}},"7":{"start":{"line":4,"column":0},"end":{"line":4,"column":46}},"8":{"start":{"line":6,"column":0},"end":{"line":6,"column":9}},"9":{"start":{"line":6,"column":9},"end":{"line":6,"column":30}},"10":{"start":{"line":7,"column":0},"end":{"line":7,"column":22}},"11":{"start":{"line":7,"column":22},"end":{"line":7,"column":68}},"12":{"start":{"line":9,"column":0},"end":{"line":9,"column":9}},"13":{"start":{"line":9,"column":9},"end":{"line":9,"column":30}},"14":{"start":{"line":10,"column":0},"end":{"line":10,"column":22}},"15":{"start":{"line":10,"column":22},"end":{"line":10,"column":68}},"16":{"start":{"line":12,"column":0},"end":{"line":12,"column":9}},"17":{"start":{"line":12,"column":9},"end":{"line":12,"column":46}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":1,"column":9},"end":{"line":1,"column":18}},"loc":{"start":{"line":1,"column":9},"end":{"line":1,"column":34}}},"1":{"name":"(anonymous_1)","decl":{"start":{"line":2,"column":9},"end":{"line":2,"column":18}},"loc":{"start":{"line":2,"column":9},"end":{"line":2,"column":20}}},"2":{"name":"(anonymous_2)","decl":{"start":{"line":2,"column":20},"end":{"line":2,"column":31}},"loc":{"start":{"line":2,"column":20},"end":{"line":2,"column":33}}},"3":{"name":"(anonymous_3)","decl":{"start":{"line":2,"column":33},"end":{"line":2,"column":42}},"loc":{"start":{"line":2,"column":33},"end":{"line":2,"column":66}}},"4":{"name":"(anonymous_4)","decl":{"start":{"line":6,"column":9},"end":{"line":6,"column":13}},"loc":{"start":{"line":6,"column":9},"end":{"line":6,"column":30}}},"5":{"name":"(anonymous_5)","decl":{"start":{"line":7,"column":22},"end":{"line":7,"column":43}},"loc":{"start":{"line":7,"column":22},"end":{"line":7,"column":68}}},"6":{"name":"(anonymous_6)","decl":{"start":{"line":9,"column":9},"end":{"line":9,"column":13}},"loc":{"start":{"line":9,"column":9},"end":{"line":9,"column":30}}},"7":{"name":"(anonymous_7)","decl":{"start":{"line":10,"column":22},"end":{"line":10,"column":43}},"loc":{"start":{"line":10,"column":22},"end":{"line":10,"column":68}}},"8":{"name":"(anonymous_8)","decl":{"start":{"line":12,"column":9},"end":{"line":12,"column":18}},"loc":{"start":{"line":12,"column":9},"end":{"line":12,"column":46}}}},"branchMap":{},"s":{"0":4,"1":7,"2":4,"3":6,"4":7,"5":5,"6":4,"7":4,"8":4,"9":14,"10":4,"11":4,"12":4,"13":10,"14":4,"15":4,"16":4,"17":6},"f":{"0":3,"1":2,"2":3,"3":1,"4":10,"5":0,"6":6,"7":0,"8":2},"b":{}} | ||
,"/home/alexxgrib/Projects/otp/src/key.actions.ts": {"path":"/home/alexxgrib/Projects/otp/src/key.actions.ts","statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":42}},"1":{"start":{"line":3,"column":0},"end":{"line":3,"column":34}},"2":{"start":{"line":14,"column":2},"end":{"line":14,"column":43}},"3":{"start":{"line":13,"column":0},"end":{"line":13,"column":7}},"4":{"start":{"line":25,"column":2},"end":{"line":25,"column":43}},"5":{"start":{"line":24,"column":0},"end":{"line":24,"column":16}},"6":{"start":{"line":36,"column":2},"end":{"line":36,"column":27}},"7":{"start":{"line":35,"column":0},"end":{"line":35,"column":16}}},"fnMap":{"0":{"name":"generateKey","decl":{"start":{"line":13,"column":22},"end":{"line":13,"column":33}},"loc":{"start":{"line":13,"column":64},"end":{"line":15,"column":1}}},"1":{"name":"importKey","decl":{"start":{"line":24,"column":16},"end":{"line":24,"column":25}},"loc":{"start":{"line":24,"column":44},"end":{"line":26,"column":1}}},"2":{"name":"exportKey","decl":{"start":{"line":35,"column":16},"end":{"line":35,"column":25}},"loc":{"start":{"line":35,"column":40},"end":{"line":37,"column":1}}}},"branchMap":{"0":{"loc":{"start":{"line":13,"column":55},"end":{"line":13,"column":64}},"type":"default-arg","locations":[{"start":{"line":13,"column":62},"end":{"line":13,"column":64}}]}},"s":{"0":4,"1":4,"2":3,"3":4,"4":1,"5":4,"6":4,"7":4},"f":{"0":3,"1":1,"2":4},"b":{"0":[2]}} | ||
,"/home/alexxgrib/Projects/otp/src/key.ts": {"path":"/home/alexxgrib/Projects/otp/src/key.ts","statementMap":{"0":{"start":{"line":13,"column":30},"end":{"line":13,"column":47}},"1":{"start":{"line":7,"column":0},"end":{"line":7,"column":13}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":13,"column":2},"end":{"line":13,"column":30}},"loc":{"start":{"line":13,"column":47},"end":{"line":13,"column":51}}}},"branchMap":{},"s":{"0":36,"1":4},"f":{"0":36},"b":{}} | ||
,"/home/alexxgrib/Projects/otp/src/totp.options.ts": {"path":"/home/alexxgrib/Projects/otp/src/totp.options.ts","statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":46}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":34}},"2":{"start":{"line":19,"column":2},"end":{"line":25,"column":4}},"3":{"start":{"line":18,"column":0},"end":{"line":18,"column":16}}},"fnMap":{"0":{"name":"getDefaultTOTPOptions","decl":{"start":{"line":18,"column":16},"end":{"line":18,"column":37}},"loc":{"start":{"line":18,"column":37},"end":{"line":26,"column":1}}}},"branchMap":{},"s":{"0":4,"1":4,"2":7,"3":4},"f":{"0":7},"b":{}} | ||
,"/home/alexxgrib/Projects/otp/src/totp.ts": {"path":"/home/alexxgrib/Projects/otp/src/totp.ts","statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":52}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":30}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":34}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":68}},"4":{"start":{"line":15,"column":14},"end":{"line":15,"column":59}},"5":{"start":{"line":16,"column":18},"end":{"line":16,"column":78}},"6":{"start":{"line":20,"column":2},"end":{"line":37,"column":null}},"7":{"start":{"line":22,"column":6},"end":{"line":22,"column":21}},"8":{"start":{"line":23,"column":6},"end":{"line":23,"column":12}},"9":{"start":{"line":26,"column":6},"end":{"line":26,"column":21}},"10":{"start":{"line":27,"column":6},"end":{"line":27,"column":12}},"11":{"start":{"line":30,"column":6},"end":{"line":30,"column":21}},"12":{"start":{"line":31,"column":6},"end":{"line":31,"column":12}},"13":{"start":{"line":35,"column":6},"end":{"line":35,"column":71}},"14":{"start":{"line":39,"column":14},"end":{"line":39,"column":50}},"15":{"start":{"line":41,"column":2},"end":{"line":46,"column":null}},"16":{"start":{"line":42,"column":19},"end":{"line":42,"column":51}},"17":{"start":{"line":43,"column":4},"end":{"line":43,"column":25}},"18":{"start":{"line":44,"column":4},"end":{"line":44,"column":36}},"19":{"start":{"line":45,"column":4},"end":{"line":45,"column":39}},"20":{"start":{"line":48,"column":2},"end":{"line":53,"column":5}},"21":{"start":{"line":14,"column":0},"end":{"line":14,"column":7}}},"fnMap":{"0":{"name":"totp","decl":{"start":{"line":14,"column":22},"end":{"line":14,"column":26}},"loc":{"start":{"line":14,"column":59},"end":{"line":54,"column":1}}}},"branchMap":{"0":{"loc":{"start":{"line":20,"column":2},"end":{"line":37,"column":null}},"type":"switch","locations":[{"start":{"line":21,"column":4},"end":{"line":24,"column":null}},{"start":{"line":25,"column":4},"end":{"line":28,"column":null}},{"start":{"line":29,"column":4},"end":{"line":32,"column":null}},{"start":{"line":34,"column":4},"end":{"line":36,"column":null}}]}},"s":{"0":4,"1":4,"2":4,"3":4,"4":6,"5":6,"6":6,"7":2,"8":2,"9":2,"10":2,"11":2,"12":2,"13":0,"14":6,"15":6,"16":6,"17":6,"18":6,"19":6,"20":6,"21":4},"f":{"0":6},"b":{"0":[2,2,2,0]}} | ||
,"/home/alexxgrib/Projects/otp/src/uri.ts": {"path":"/home/alexxgrib/Projects/otp/src/uri.ts","statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":68}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":68}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":42}},"3":{"start":{"line":23,"column":16},"end":{"line":27,"column":38}},"4":{"start":{"line":29,"column":14},"end":{"line":29,"column":59}},"5":{"start":{"line":31,"column":2},"end":{"line":31,"column":60}},"6":{"start":{"line":33,"column":2},"end":{"line":35,"column":null}},"7":{"start":{"line":34,"column":4},"end":{"line":34,"column":51}},"8":{"start":{"line":40,"column":2},"end":{"line":60,"column":null}},"9":{"start":{"line":42,"column":18},"end":{"line":42,"column":63}},"10":{"start":{"line":43,"column":6},"end":{"line":43,"column":35}},"11":{"start":{"line":44,"column":6},"end":{"line":44,"column":29}},"12":{"start":{"line":45,"column":6},"end":{"line":45,"column":65}},"13":{"start":{"line":46,"column":6},"end":{"line":46,"column":12}},"14":{"start":{"line":50,"column":18},"end":{"line":50,"column":63}},"15":{"start":{"line":51,"column":6},"end":{"line":51,"column":35}},"16":{"start":{"line":52,"column":6},"end":{"line":52,"column":29}},"17":{"start":{"line":53,"column":6},"end":{"line":53,"column":68}},"18":{"start":{"line":54,"column":6},"end":{"line":54,"column":12}},"19":{"start":{"line":58,"column":6},"end":{"line":58,"column":80}},"20":{"start":{"line":62,"column":2},"end":{"line":62,"column":61}},"21":{"start":{"line":63,"column":2},"end":{"line":63,"column":52}},"22":{"start":{"line":65,"column":2},"end":{"line":65,"column":24}},"23":{"start":{"line":22,"column":0},"end":{"line":22,"column":16}}},"fnMap":{"0":{"name":"getKeyUri","decl":{"start":{"line":22,"column":16},"end":{"line":22,"column":25}},"loc":{"start":{"line":22,"column":45},"end":{"line":66,"column":1}}}},"branchMap":{"0":{"loc":{"start":{"line":23,"column":16},"end":{"line":27,"column":38}},"type":"cond-expr","locations":[{"start":{"line":24,"column":6},"end":{"line":26,"column":9}},{"start":{"line":27,"column":6},"end":{"line":27,"column":38}}]},"1":{"loc":{"start":{"line":33,"column":2},"end":{"line":35,"column":null}},"type":"if","locations":[{"start":{"line":33,"column":2},"end":{"line":35,"column":null}}]},"2":{"loc":{"start":{"line":40,"column":2},"end":{"line":60,"column":null}},"type":"switch","locations":[{"start":{"line":41,"column":4},"end":{"line":47,"column":null}},{"start":{"line":49,"column":4},"end":{"line":55,"column":null}},{"start":{"line":57,"column":4},"end":{"line":59,"column":null}}]}},"s":{"0":4,"1":4,"2":4,"3":2,"4":2,"5":2,"6":2,"7":2,"8":2,"9":1,"10":1,"11":1,"12":1,"13":1,"14":1,"15":1,"16":1,"17":1,"18":1,"19":0,"20":2,"21":2,"22":2,"23":4},"f":{"0":2},"b":{"0":[2,0],"1":[2],"2":[1,1,0]}} | ||
,"/home/alexxgrib/Projects/otp/src/crypto/node.ts": {"path":"/home/alexxgrib/Projects/otp/src/crypto/node.ts","statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":48}},"1":{"start":{"line":5,"column":26},"end":{"line":7,"column":1}},"2":{"start":{"line":6,"column":2},"end":{"line":6,"column":61}},"3":{"start":{"line":5,"column":13},"end":{"line":5,"column":26}},"4":{"start":{"line":9,"column":40},"end":{"line":19,"column":1}},"5":{"start":{"line":10,"column":2},"end":{"line":18,"column":5}},"6":{"start":{"line":11,"column":19},"end":{"line":11,"column":39}},"7":{"start":{"line":13,"column":4},"end":{"line":17,"column":7}},"8":{"start":{"line":14,"column":6},"end":{"line":14,"column":41}},"9":{"start":{"line":14,"column":18},"end":{"line":14,"column":41}},"10":{"start":{"line":16,"column":6},"end":{"line":16,"column":20}},"11":{"start":{"line":9,"column":13},"end":{"line":9,"column":40}}},"fnMap":{"0":{"name":"hmac","decl":{"start":{"line":5,"column":41},"end":{"line":5,"column":45}},"loc":{"start":{"line":5,"column":69},"end":{"line":7,"column":1}}},"1":{"name":"randomBytes","decl":{"start":{"line":9,"column":49},"end":{"line":9,"column":60}},"loc":{"start":{"line":9,"column":65},"end":{"line":19,"column":1}}},"2":{"name":"(anonymous_2)","decl":{"start":{"line":10,"column":21},"end":{"line":10,"column":22}},"loc":{"start":{"line":10,"column":41},"end":{"line":18,"column":3}}},"3":{"name":"(anonymous_3)","decl":{"start":{"line":13,"column":23},"end":{"line":13,"column":24}},"loc":{"start":{"line":13,"column":41},"end":{"line":17,"column":5}}}},"branchMap":{"0":{"loc":{"start":{"line":14,"column":6},"end":{"line":14,"column":41}},"type":"if","locations":[{"start":{"line":14,"column":6},"end":{"line":14,"column":41}}]}},"s":{"0":4,"1":4,"2":16,"3":4,"4":4,"5":3,"6":3,"7":3,"8":3,"9":3,"10":0,"11":4},"f":{"0":16,"1":3,"2":3,"3":3},"b":{"0":[3]}} | ||
{"/home/alexxgrib/Projects/otp/src/base32.ts": {"path":"/home/alexxgrib/Projects/otp/src/base32.ts","statementMap":{"0":{"start":{"line":2,"column":18},"end":{"line":2,"column":52}},"1":{"start":{"line":3,"column":18},"end":{"line":11,"column":2}},"2":{"start":{"line":22,"column":2},"end":{"line":22,"column":38}},"3":{"start":{"line":33,"column":14},"end":{"line":33,"column":15}},"4":{"start":{"line":34,"column":21},"end":{"line":34,"column":22}},"5":{"start":{"line":35,"column":19},"end":{"line":35,"column":20}},"6":{"start":{"line":36,"column":14},"end":{"line":36,"column":15}},"7":{"start":{"line":37,"column":18},"end":{"line":37,"column":73}},"8":{"start":{"line":40,"column":2},"end":{"line":56,"column":null}},"9":{"start":{"line":41,"column":20},"end":{"line":41,"column":33}},"10":{"start":{"line":42,"column":4},"end":{"line":53,"column":null}},"11":{"start":{"line":43,"column":6},"end":{"line":43,"column":45}},"12":{"start":{"line":44,"column":6},"end":{"line":44,"column":40}},"13":{"start":{"line":45,"column":6},"end":{"line":47,"column":80}},"14":{"start":{"line":48,"column":6},"end":{"line":48,"column":14}},"15":{"start":{"line":50,"column":6},"end":{"line":50,"column":57}},"16":{"start":{"line":51,"column":6},"end":{"line":51,"column":40}},"17":{"start":{"line":52,"column":6},"end":{"line":52,"column":36}},"18":{"start":{"line":52,"column":28},"end":{"line":52,"column":36}},"19":{"start":{"line":54,"column":4},"end":{"line":54,"column":68}},"20":{"start":{"line":55,"column":4},"end":{"line":55,"column":19}},"21":{"start":{"line":59,"column":2},"end":{"line":65,"column":null}},"22":{"start":{"line":64,"column":4},"end":{"line":64,"column":33}},"23":{"start":{"line":67,"column":2},"end":{"line":67,"column":41}},"24":{"start":{"line":32,"column":0},"end":{"line":32,"column":16}},"25":{"start":{"line":78,"column":19},"end":{"line":78,"column":20}},"26":{"start":{"line":79,"column":19},"end":{"line":79,"column":20}},"27":{"start":{"line":80,"column":18},"end":{"line":80,"column":19}},"28":{"start":{"line":81,"column":17},"end":{"line":81,"column":18}},"29":{"start":{"line":83,"column":18},"end":{"line":83,"column":69}},"30":{"start":{"line":84,"column":16},"end":{"line":84,"column":67}},"31":{"start":{"line":84,"column":48},"end":{"line":84,"column":66}},"32":{"start":{"line":88,"column":2},"end":{"line":119,"column":null}},"33":{"start":{"line":88,"column":19},"end":{"line":88,"column":20}},"34":{"start":{"line":90,"column":4},"end":{"line":93,"column":null}},"35":{"start":{"line":94,"column":24},"end":{"line":94,"column":44}},"36":{"start":{"line":97,"column":4},"end":{"line":118,"column":null}},"37":{"start":{"line":98,"column":6},"end":{"line":98,"column":43}},"38":{"start":{"line":99,"column":6},"end":{"line":115,"column":null}},"39":{"start":{"line":100,"column":8},"end":{"line":100,"column":42}},"40":{"start":{"line":101,"column":8},"end":{"line":108,"column":null}},"41":{"start":{"line":102,"column":10},"end":{"line":102,"column":34}},"42":{"start":{"line":103,"column":10},"end":{"line":103,"column":41}},"43":{"start":{"line":104,"column":10},"end":{"line":104,"column":21}},"44":{"start":{"line":105,"column":10},"end":{"line":105,"column":24}},"45":{"start":{"line":107,"column":10},"end":{"line":107,"column":63}},"46":{"start":{"line":110,"column":8},"end":{"line":110,"column":42}},"47":{"start":{"line":111,"column":8},"end":{"line":111,"column":56}},"48":{"start":{"line":112,"column":8},"end":{"line":112,"column":39}},"49":{"start":{"line":113,"column":8},"end":{"line":113,"column":19}},"50":{"start":{"line":114,"column":8},"end":{"line":114,"column":60}},"51":{"start":{"line":120,"column":2},"end":{"line":120,"column":36}},"52":{"start":{"line":77,"column":0},"end":{"line":77,"column":16}}},"fnMap":{"0":{"name":"quintetCount","decl":{"start":{"line":19,"column":9},"end":{"line":19,"column":21}},"loc":{"start":{"line":19,"column":40},"end":{"line":23,"column":1}}},"1":{"name":"encode","decl":{"start":{"line":32,"column":16},"end":{"line":32,"column":22}},"loc":{"start":{"line":32,"column":61},"end":{"line":68,"column":1}}},"2":{"name":"decode","decl":{"start":{"line":77,"column":16},"end":{"line":77,"column":22}},"loc":{"start":{"line":77,"column":38},"end":{"line":121,"column":1}}},"3":{"name":"(anonymous_3)","decl":{"start":{"line":84,"column":38},"end":{"line":84,"column":39}},"loc":{"start":{"line":84,"column":48},"end":{"line":84,"column":66}}}},"branchMap":{"0":{"loc":{"start":{"line":32,"column":42},"end":{"line":32,"column":61}},"type":"default-arg","locations":[{"start":{"line":32,"column":59},"end":{"line":32,"column":61}}]},"1":{"loc":{"start":{"line":32,"column":44},"end":{"line":32,"column":54}},"type":"default-arg","locations":[{"start":{"line":32,"column":50},"end":{"line":32,"column":54}}]},"2":{"loc":{"start":{"line":42,"column":4},"end":{"line":53,"column":null}},"type":"if","locations":[{"start":{"line":42,"column":4},"end":{"line":53,"column":null}},{"start":{"line":49,"column":11},"end":{"line":53,"column":null}}]},"3":{"loc":{"start":{"line":47,"column":10},"end":{"line":47,"column":57}},"type":"cond-expr","locations":[{"start":{"line":47,"column":37},"end":{"line":47,"column":53}},{"start":{"line":47,"column":56},"end":{"line":47,"column":57}}]},"4":{"loc":{"start":{"line":52,"column":6},"end":{"line":52,"column":36}},"type":"if","locations":[{"start":{"line":52,"column":6},"end":{"line":52,"column":36}}]},"5":{"loc":{"start":{"line":59,"column":2},"end":{"line":65,"column":null}},"type":"if","locations":[{"start":{"line":63,"column":9},"end":{"line":65,"column":null}}]},"6":{"loc":{"start":{"line":97,"column":4},"end":{"line":118,"column":null}},"type":"if","locations":[{"start":{"line":97,"column":4},"end":{"line":118,"column":null}}]},"7":{"loc":{"start":{"line":99,"column":6},"end":{"line":115,"column":null}},"type":"if","locations":[{"start":{"line":99,"column":6},"end":{"line":115,"column":null}},{"start":{"line":109,"column":13},"end":{"line":115,"column":null}}]},"8":{"loc":{"start":{"line":101,"column":8},"end":{"line":108,"column":null}},"type":"if","locations":[{"start":{"line":101,"column":8},"end":{"line":108,"column":null}},{"start":{"line":106,"column":15},"end":{"line":108,"column":null}}]}},"s":{"0":5,"1":5,"2":6,"3":6,"4":6,"5":6,"6":6,"7":6,"8":6,"9":112,"10":112,"11":56,"12":56,"13":56,"14":56,"15":56,"16":56,"17":56,"18":14,"19":112,"20":112,"21":6,"22":6,"23":6,"24":5,"25":3,"26":3,"27":3,"28":3,"29":3,"30":3,"31":80,"32":3,"33":3,"34":80,"35":80,"36":80,"37":80,"38":80,"39":40,"40":40,"41":10,"42":10,"43":10,"44":10,"45":30,"46":40,"47":40,"48":40,"49":40,"50":40,"51":3,"52":5},"f":{"0":6,"1":6,"2":3,"3":80},"b":{"0":[0],"1":[0],"2":[56,56],"3":[56,0],"4":[14],"5":[6],"6":[80],"7":[40,40],"8":[10,30]}} | ||
,"/home/alexxgrib/Projects/otp/src/crypto-node.ts": {"path":"/home/alexxgrib/Projects/otp/src/crypto-node.ts","statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":9}},"1":{"start":{"line":1,"column":9},"end":{"line":1,"column":15}},"2":{"start":{"line":1,"column":15},"end":{"line":1,"column":50}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":1,"column":9},"end":{"line":1,"column":13}},"loc":{"start":{"line":1,"column":9},"end":{"line":1,"column":15}}},"1":{"name":"(anonymous_1)","decl":{"start":{"line":1,"column":15},"end":{"line":1,"column":26}},"loc":{"start":{"line":1,"column":15},"end":{"line":1,"column":50}}}},"branchMap":{},"s":{"0":5,"1":16,"2":8},"f":{"0":11,"1":3},"b":{}} | ||
,"/home/alexxgrib/Projects/otp/src/hotp.class.ts": {"path":"/home/alexxgrib/Projects/otp/src/hotp.class.ts","statementMap":{"0":{"start":{"line":2,"column":0},"end":{"line":2,"column":30}},"1":{"start":{"line":4,"column":0},"end":{"line":4,"column":34}},"2":{"start":{"line":19,"column":31},"end":{"line":19,"column":42}},"3":{"start":{"line":19,"column":51},"end":{"line":19,"column":71}},"4":{"start":{"line":30,"column":4},"end":{"line":30,"column":70}},"5":{"start":{"line":45,"column":4},"end":{"line":45,"column":57}},"6":{"start":{"line":55,"column":4},"end":{"line":55,"column":69}},"7":{"start":{"line":65,"column":4},"end":{"line":65,"column":34}},"8":{"start":{"line":12,"column":0},"end":{"line":12,"column":13}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":19,"column":2},"end":{"line":19,"column":31}},"loc":{"start":{"line":19,"column":71},"end":{"line":19,"column":75}}},"1":{"name":"(anonymous_1)","decl":{"start":{"line":29,"column":2},"end":{"line":29,"column":8}},"loc":{"start":{"line":29,"column":37},"end":{"line":31,"column":3}}},"2":{"name":"(anonymous_2)","decl":{"start":{"line":41,"column":2},"end":{"line":41,"column":7}},"loc":{"start":{"line":43,"column":36},"end":{"line":46,"column":3}}},"3":{"name":"(anonymous_3)","decl":{"start":{"line":54,"column":2},"end":{"line":54,"column":7}},"loc":{"start":{"line":54,"column":57},"end":{"line":56,"column":3}}},"4":{"name":"(anonymous_4)","decl":{"start":{"line":64,"column":2},"end":{"line":64,"column":11}},"loc":{"start":{"line":64,"column":11},"end":{"line":66,"column":3}}}},"branchMap":{"0":{"loc":{"start":{"line":54,"column":21},"end":{"line":54,"column":57}},"type":"default-arg","locations":[{"start":{"line":54,"column":55},"end":{"line":54,"column":57}}]}},"s":{"0":4,"1":4,"2":2,"3":2,"4":1,"5":10,"6":10,"7":1,"8":4},"f":{"0":2,"1":1,"2":10,"3":10,"4":1},"b":{"0":[0]}} | ||
,"/home/alexxgrib/Projects/otp/src/hotp.options.ts": {"path":"/home/alexxgrib/Projects/otp/src/hotp.options.ts","statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":46}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":34}},"2":{"start":{"line":37,"column":2},"end":{"line":42,"column":4}},"3":{"start":{"line":36,"column":0},"end":{"line":36,"column":16}}},"fnMap":{"0":{"name":"getDefaultHOTPOptions","decl":{"start":{"line":36,"column":16},"end":{"line":36,"column":37}},"loc":{"start":{"line":36,"column":37},"end":{"line":43,"column":1}}}},"branchMap":{},"s":{"0":5,"1":5,"2":20,"3":5},"f":{"0":20},"b":{}} | ||
,"/home/alexxgrib/Projects/otp/src/hotp.ts": {"path":"/home/alexxgrib/Projects/otp/src/hotp.ts","statementMap":{"0":{"start":{"line":2,"column":0},"end":{"line":2,"column":41}},"1":{"start":{"line":4,"column":0},"end":{"line":4,"column":68}},"2":{"start":{"line":15,"column":14},"end":{"line":15,"column":59}},"3":{"start":{"line":17,"column":17},"end":{"line":20,"column":null}},"4":{"start":{"line":24,"column":17},"end":{"line":24,"column":48}},"5":{"start":{"line":25,"column":15},"end":{"line":25,"column":42}},"6":{"start":{"line":29,"column":17},"end":{"line":29,"column":55}},"7":{"start":{"line":30,"column":2},"end":{"line":30,"column":49}},"8":{"start":{"line":14,"column":0},"end":{"line":14,"column":7}}},"fnMap":{"0":{"name":"hotp","decl":{"start":{"line":14,"column":22},"end":{"line":14,"column":26}},"loc":{"start":{"line":14,"column":59},"end":{"line":31,"column":1}}}},"branchMap":{},"s":{"0":5,"1":5,"2":18,"3":18,"4":18,"5":18,"6":18,"7":18,"8":5},"f":{"0":18},"b":{}} | ||
,"/home/alexxgrib/Projects/otp/src/index.ts": {"path":"/home/alexxgrib/Projects/otp/src/index.ts","statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":9}},"1":{"start":{"line":1,"column":9},"end":{"line":1,"column":34}},"2":{"start":{"line":2,"column":0},"end":{"line":2,"column":9}},"3":{"start":{"line":2,"column":9},"end":{"line":2,"column":20}},"4":{"start":{"line":2,"column":20},"end":{"line":2,"column":33}},"5":{"start":{"line":2,"column":33},"end":{"line":2,"column":66}},"6":{"start":{"line":3,"column":0},"end":{"line":3,"column":52}},"7":{"start":{"line":4,"column":0},"end":{"line":4,"column":46}},"8":{"start":{"line":6,"column":0},"end":{"line":6,"column":9}},"9":{"start":{"line":6,"column":9},"end":{"line":6,"column":30}},"10":{"start":{"line":7,"column":0},"end":{"line":7,"column":9}},"11":{"start":{"line":7,"column":9},"end":{"line":7,"column":36}},"12":{"start":{"line":8,"column":0},"end":{"line":8,"column":22}},"13":{"start":{"line":8,"column":22},"end":{"line":8,"column":68}},"14":{"start":{"line":10,"column":0},"end":{"line":10,"column":9}},"15":{"start":{"line":10,"column":9},"end":{"line":10,"column":30}},"16":{"start":{"line":11,"column":0},"end":{"line":11,"column":9}},"17":{"start":{"line":11,"column":9},"end":{"line":11,"column":36}},"18":{"start":{"line":12,"column":0},"end":{"line":12,"column":22}},"19":{"start":{"line":12,"column":22},"end":{"line":12,"column":68}},"20":{"start":{"line":14,"column":0},"end":{"line":14,"column":9}},"21":{"start":{"line":14,"column":9},"end":{"line":14,"column":46}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":1,"column":9},"end":{"line":1,"column":18}},"loc":{"start":{"line":1,"column":9},"end":{"line":1,"column":34}}},"1":{"name":"(anonymous_1)","decl":{"start":{"line":2,"column":9},"end":{"line":2,"column":18}},"loc":{"start":{"line":2,"column":9},"end":{"line":2,"column":20}}},"2":{"name":"(anonymous_2)","decl":{"start":{"line":2,"column":20},"end":{"line":2,"column":31}},"loc":{"start":{"line":2,"column":20},"end":{"line":2,"column":33}}},"3":{"name":"(anonymous_3)","decl":{"start":{"line":2,"column":33},"end":{"line":2,"column":42}},"loc":{"start":{"line":2,"column":33},"end":{"line":2,"column":66}}},"4":{"name":"(anonymous_4)","decl":{"start":{"line":6,"column":9},"end":{"line":6,"column":13}},"loc":{"start":{"line":6,"column":9},"end":{"line":6,"column":30}}},"5":{"name":"(anonymous_5)","decl":{"start":{"line":7,"column":9},"end":{"line":7,"column":13}},"loc":{"start":{"line":7,"column":9},"end":{"line":7,"column":36}}},"6":{"name":"(anonymous_6)","decl":{"start":{"line":8,"column":22},"end":{"line":8,"column":43}},"loc":{"start":{"line":8,"column":22},"end":{"line":8,"column":68}}},"7":{"name":"(anonymous_7)","decl":{"start":{"line":10,"column":9},"end":{"line":10,"column":13}},"loc":{"start":{"line":10,"column":9},"end":{"line":10,"column":30}}},"8":{"name":"(anonymous_8)","decl":{"start":{"line":11,"column":9},"end":{"line":11,"column":13}},"loc":{"start":{"line":11,"column":9},"end":{"line":11,"column":36}}},"9":{"name":"(anonymous_9)","decl":{"start":{"line":12,"column":22},"end":{"line":12,"column":43}},"loc":{"start":{"line":12,"column":22},"end":{"line":12,"column":68}}},"10":{"name":"(anonymous_10)","decl":{"start":{"line":14,"column":9},"end":{"line":14,"column":18}},"loc":{"start":{"line":14,"column":9},"end":{"line":14,"column":46}}}},"branchMap":{},"s":{"0":4,"1":7,"2":4,"3":6,"4":7,"5":5,"6":4,"7":4,"8":4,"9":4,"10":4,"11":6,"12":4,"13":4,"14":4,"15":10,"16":4,"17":5,"18":4,"19":4,"20":4,"21":6},"f":{"0":3,"1":2,"2":3,"3":1,"4":0,"5":2,"6":0,"7":6,"8":1,"9":0,"10":2},"b":{}} | ||
,"/home/alexxgrib/Projects/otp/src/key.actions.ts": {"path":"/home/alexxgrib/Projects/otp/src/key.actions.ts","statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":42}},"1":{"start":{"line":3,"column":0},"end":{"line":3,"column":34}},"2":{"start":{"line":14,"column":2},"end":{"line":14,"column":37}},"3":{"start":{"line":13,"column":0},"end":{"line":13,"column":16}},"4":{"start":{"line":25,"column":2},"end":{"line":25,"column":43}},"5":{"start":{"line":24,"column":0},"end":{"line":24,"column":16}},"6":{"start":{"line":36,"column":2},"end":{"line":36,"column":43}},"7":{"start":{"line":35,"column":0},"end":{"line":35,"column":16}}},"fnMap":{"0":{"name":"generateKey","decl":{"start":{"line":13,"column":16},"end":{"line":13,"column":27}},"loc":{"start":{"line":13,"column":58},"end":{"line":15,"column":1}}},"1":{"name":"importKey","decl":{"start":{"line":24,"column":16},"end":{"line":24,"column":25}},"loc":{"start":{"line":24,"column":44},"end":{"line":26,"column":1}}},"2":{"name":"exportKey","decl":{"start":{"line":35,"column":16},"end":{"line":35,"column":25}},"loc":{"start":{"line":35,"column":40},"end":{"line":37,"column":1}}}},"branchMap":{"0":{"loc":{"start":{"line":13,"column":49},"end":{"line":13,"column":58}},"type":"default-arg","locations":[{"start":{"line":13,"column":56},"end":{"line":13,"column":58}}]}},"s":{"0":5,"1":5,"2":3,"3":5,"4":3,"5":5,"6":6,"7":5},"f":{"0":3,"1":3,"2":6},"b":{"0":[2]}} | ||
,"/home/alexxgrib/Projects/otp/src/key.ts": {"path":"/home/alexxgrib/Projects/otp/src/key.ts","statementMap":{"0":{"start":{"line":13,"column":30},"end":{"line":13,"column":47}},"1":{"start":{"line":7,"column":0},"end":{"line":7,"column":13}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":13,"column":2},"end":{"line":13,"column":30}},"loc":{"start":{"line":13,"column":47},"end":{"line":13,"column":51}}}},"branchMap":{},"s":{"0":46,"1":5},"f":{"0":46},"b":{}} | ||
,"/home/alexxgrib/Projects/otp/src/totp.class.ts": {"path":"/home/alexxgrib/Projects/otp/src/totp.class.ts","statementMap":{"0":{"start":{"line":2,"column":0},"end":{"line":2,"column":30}},"1":{"start":{"line":4,"column":0},"end":{"line":4,"column":34}},"2":{"start":{"line":19,"column":31},"end":{"line":19,"column":42}},"3":{"start":{"line":19,"column":51},"end":{"line":19,"column":71}},"4":{"start":{"line":30,"column":4},"end":{"line":30,"column":70}},"5":{"start":{"line":45,"column":4},"end":{"line":45,"column":57}},"6":{"start":{"line":55,"column":4},"end":{"line":55,"column":69}},"7":{"start":{"line":12,"column":0},"end":{"line":12,"column":13}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":19,"column":2},"end":{"line":19,"column":31}},"loc":{"start":{"line":19,"column":71},"end":{"line":19,"column":75}}},"1":{"name":"(anonymous_1)","decl":{"start":{"line":29,"column":2},"end":{"line":29,"column":8}},"loc":{"start":{"line":29,"column":37},"end":{"line":31,"column":3}}},"2":{"name":"(anonymous_2)","decl":{"start":{"line":41,"column":2},"end":{"line":41,"column":7}},"loc":{"start":{"line":43,"column":36},"end":{"line":46,"column":3}}},"3":{"name":"(anonymous_3)","decl":{"start":{"line":54,"column":2},"end":{"line":54,"column":7}},"loc":{"start":{"line":54,"column":57},"end":{"line":56,"column":3}}}},"branchMap":{"0":{"loc":{"start":{"line":54,"column":21},"end":{"line":54,"column":57}},"type":"default-arg","locations":[{"start":{"line":54,"column":55},"end":{"line":54,"column":57}}]}},"s":{"0":5,"1":5,"2":3,"3":3,"4":1,"5":1,"6":2,"7":5},"f":{"0":3,"1":1,"2":1,"3":2},"b":{"0":[2]}} | ||
,"/home/alexxgrib/Projects/otp/src/totp.options.ts": {"path":"/home/alexxgrib/Projects/otp/src/totp.options.ts","statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":46}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":34}},"2":{"start":{"line":54,"column":2},"end":{"line":61,"column":4}},"3":{"start":{"line":53,"column":0},"end":{"line":53,"column":16}}},"fnMap":{"0":{"name":"getDefaultTOTPOptions","decl":{"start":{"line":53,"column":16},"end":{"line":53,"column":37}},"loc":{"start":{"line":53,"column":37},"end":{"line":62,"column":1}}}},"branchMap":{},"s":{"0":5,"1":5,"2":10,"3":5},"f":{"0":10},"b":{}} | ||
,"/home/alexxgrib/Projects/otp/src/totp.ts": {"path":"/home/alexxgrib/Projects/otp/src/totp.ts","statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":52}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":30}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":34}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":68}},"4":{"start":{"line":6,"column":19},"end":{"line":10,"column":2}},"5":{"start":{"line":20,"column":17},"end":{"line":20,"column":50}},"6":{"start":{"line":21,"column":17},"end":{"line":21,"column":55}},"7":{"start":{"line":23,"column":2},"end":{"line":25,"column":null}},"8":{"start":{"line":23,"column":19},"end":{"line":23,"column":20}},"9":{"start":{"line":24,"column":4},"end":{"line":24,"column":46}},"10":{"start":{"line":27,"column":2},"end":{"line":27,"column":33}},"11":{"start":{"line":40,"column":14},"end":{"line":40,"column":59}},"12":{"start":{"line":41,"column":18},"end":{"line":41,"column":78}},"13":{"start":{"line":43,"column":14},"end":{"line":43,"column":50}},"14":{"start":{"line":45,"column":2},"end":{"line":56,"column":null}},"15":{"start":{"line":46,"column":19},"end":{"line":46,"column":51}},"16":{"start":{"line":49,"column":4},"end":{"line":51,"column":null}},"17":{"start":{"line":53,"column":4},"end":{"line":55,"column":null}},"18":{"start":{"line":54,"column":6},"end":{"line":54,"column":33}},"19":{"start":{"line":58,"column":2},"end":{"line":63,"column":5}},"20":{"start":{"line":39,"column":0},"end":{"line":39,"column":7}}},"fnMap":{"0":{"name":"pad","decl":{"start":{"line":19,"column":9},"end":{"line":19,"column":12}},"loc":{"start":{"line":19,"column":47},"end":{"line":28,"column":1}}},"1":{"name":"totp","decl":{"start":{"line":39,"column":22},"end":{"line":39,"column":26}},"loc":{"start":{"line":39,"column":59},"end":{"line":64,"column":1}}}},"branchMap":{"0":{"loc":{"start":{"line":45,"column":2},"end":{"line":56,"column":null}},"type":"if","locations":[{"start":{"line":45,"column":2},"end":{"line":56,"column":null}}]},"1":{"loc":{"start":{"line":53,"column":4},"end":{"line":55,"column":null}},"type":"if","locations":[{"start":{"line":53,"column":4},"end":{"line":55,"column":null}}]}},"s":{"0":5,"1":5,"2":5,"3":5,"4":5,"5":4,"6":4,"7":4,"8":4,"9":12,"10":4,"11":8,"12":8,"13":8,"14":8,"15":6,"16":6,"17":6,"18":4,"19":8,"20":5},"f":{"0":4,"1":8},"b":{"0":[6],"1":[4]}} | ||
,"/home/alexxgrib/Projects/otp/src/uri.ts": {"path":"/home/alexxgrib/Projects/otp/src/uri.ts","statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":68}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":68}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":42}},"3":{"start":{"line":23,"column":16},"end":{"line":27,"column":38}},"4":{"start":{"line":29,"column":14},"end":{"line":29,"column":59}},"5":{"start":{"line":31,"column":2},"end":{"line":31,"column":60}},"6":{"start":{"line":33,"column":2},"end":{"line":35,"column":null}},"7":{"start":{"line":34,"column":4},"end":{"line":34,"column":51}},"8":{"start":{"line":40,"column":2},"end":{"line":61,"column":null}},"9":{"start":{"line":42,"column":18},"end":{"line":42,"column":63}},"10":{"start":{"line":43,"column":6},"end":{"line":43,"column":35}},"11":{"start":{"line":44,"column":6},"end":{"line":44,"column":29}},"12":{"start":{"line":45,"column":6},"end":{"line":45,"column":65}},"13":{"start":{"line":46,"column":6},"end":{"line":46,"column":12}},"14":{"start":{"line":50,"column":18},"end":{"line":50,"column":63}},"15":{"start":{"line":51,"column":6},"end":{"line":51,"column":35}},"16":{"start":{"line":52,"column":6},"end":{"line":52,"column":29}},"17":{"start":{"line":53,"column":6},"end":{"line":53,"column":68}},"18":{"start":{"line":54,"column":6},"end":{"line":54,"column":12}},"19":{"start":{"line":63,"column":2},"end":{"line":63,"column":61}},"20":{"start":{"line":64,"column":2},"end":{"line":64,"column":52}},"21":{"start":{"line":66,"column":2},"end":{"line":66,"column":24}},"22":{"start":{"line":22,"column":0},"end":{"line":22,"column":16}}},"fnMap":{"0":{"name":"getKeyUri","decl":{"start":{"line":22,"column":16},"end":{"line":22,"column":25}},"loc":{"start":{"line":22,"column":45},"end":{"line":67,"column":1}}}},"branchMap":{"0":{"loc":{"start":{"line":23,"column":16},"end":{"line":27,"column":38}},"type":"cond-expr","locations":[{"start":{"line":24,"column":6},"end":{"line":26,"column":9}},{"start":{"line":27,"column":6},"end":{"line":27,"column":38}}]},"1":{"loc":{"start":{"line":33,"column":2},"end":{"line":35,"column":null}},"type":"if","locations":[{"start":{"line":33,"column":2},"end":{"line":35,"column":null}}]},"2":{"loc":{"start":{"line":40,"column":2},"end":{"line":61,"column":null}},"type":"switch","locations":[{"start":{"line":41,"column":4},"end":{"line":47,"column":null}},{"start":{"line":49,"column":4},"end":{"line":55,"column":null}}]}},"s":{"0":5,"1":5,"2":5,"3":4,"4":4,"5":4,"6":4,"7":4,"8":4,"9":2,"10":2,"11":2,"12":2,"13":2,"14":2,"15":2,"16":2,"17":2,"18":2,"19":4,"20":4,"21":4,"22":5},"f":{"0":4},"b":{"0":[4,0],"1":[4],"2":[2,2]}} | ||
,"/home/alexxgrib/Projects/otp/src/crypto/node.ts": {"path":"/home/alexxgrib/Projects/otp/src/crypto/node.ts","statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":52}},"1":{"start":{"line":5,"column":26},"end":{"line":7,"column":1}},"2":{"start":{"line":6,"column":2},"end":{"line":6,"column":61}},"3":{"start":{"line":5,"column":13},"end":{"line":5,"column":26}},"4":{"start":{"line":9,"column":40},"end":{"line":11,"column":1}},"5":{"start":{"line":10,"column":2},"end":{"line":10,"column":46}},"6":{"start":{"line":9,"column":13},"end":{"line":9,"column":40}}},"fnMap":{"0":{"name":"hmac","decl":{"start":{"line":5,"column":41},"end":{"line":5,"column":45}},"loc":{"start":{"line":5,"column":69},"end":{"line":7,"column":1}}},"1":{"name":"randomBytes","decl":{"start":{"line":9,"column":49},"end":{"line":9,"column":60}},"loc":{"start":{"line":9,"column":65},"end":{"line":11,"column":1}}}},"branchMap":{},"s":{"0":5,"1":5,"2":18,"3":5,"4":5,"5":3,"6":5},"f":{"0":18,"1":3},"b":{}} | ||
} |
@@ -8,3 +8,5 @@ /** | ||
*/ | ||
export declare function encode(plain: Uint8Array): string; | ||
export declare function encode(plain: Uint8Array, { pad }?: { | ||
pad?: boolean | undefined; | ||
}): string; | ||
/** | ||
@@ -11,0 +13,0 @@ * |
"use strict"; | ||
const charTable = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"; | ||
const byteTable = [ | ||
const byteTable = new Uint8Array([ | ||
0xff, 0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
@@ -11,3 +11,3 @@ 0xff, 0xff, 0xff, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, | ||
0xff, 0xff | ||
]; | ||
]); | ||
/** | ||
@@ -20,4 +20,3 @@ * | ||
function quintetCount(buffer) { | ||
const quintets = Math.floor(buffer.length / 5); | ||
return buffer.length % 5 === 0 ? quintets : quintets + 1; | ||
return Math.ceil(buffer.length / 5); | ||
} | ||
@@ -31,5 +30,5 @@ /** | ||
*/ | ||
function encode(plain) { | ||
function encode(plain, { pad = true } = {}) { | ||
let index = 0; | ||
let index2 = 0; | ||
let encodedIndex = 0; | ||
let shiftIndex = 0; | ||
@@ -39,3 +38,3 @@ let digit = 0; | ||
while (index < plain.length) { | ||
const current = plain[index]; | ||
const current = plain[+index]; | ||
if (shiftIndex > 3) { | ||
@@ -53,9 +52,13 @@ digit = current & (0xff >> shiftIndex); | ||
} | ||
encoded[index2] = charTable.codePointAt(digit); | ||
index2++; | ||
encoded[+encodedIndex] = charTable.codePointAt(digit); | ||
encodedIndex++; | ||
} | ||
for (index = index2; index < encoded.length; index++) { | ||
encoded[index] = 0x3d; | ||
if (pad) { | ||
for (index = encodedIndex; index < encoded.length; index++) { | ||
encoded[+index] = 0x3d; | ||
} | ||
} else { | ||
encoded.splice(encodedIndex); | ||
} | ||
return String.fromCodePoint(...encoded); | ||
return String.fromCharCode(...encoded); | ||
} | ||
@@ -75,10 +78,10 @@ /** | ||
const decoded = new Uint8Array(Math.ceil((encoded.length * 5) / 8)); | ||
const chars = encoded.split("").map((char) => char.codePointAt(0)); | ||
const chars = encoded.split("").map((char) => char.charCodeAt(0)); | ||
for (let index = 0; index < encoded.length; index++) { | ||
if (chars[index] === 0x3d) { | ||
if (chars[+index] === 0x3d) { | ||
break; | ||
} | ||
const encodedByte = chars[index] - 0x30; | ||
const encodedByte = chars[+index] - 0x30; | ||
if (encodedByte < byteTable.length) { | ||
plainDigit = byteTable[encodedByte]; | ||
plainDigit = byteTable[+encodedByte]; | ||
if (shiftIndex <= 3) { | ||
@@ -88,3 +91,3 @@ shiftIndex = (shiftIndex + 5) % 8; | ||
plainChar |= plainDigit; | ||
decoded[plainPos] = plainChar; | ||
decoded[+plainPos] = plainChar; | ||
plainPos++; | ||
@@ -98,3 +101,3 @@ plainChar = 0; | ||
plainChar |= 0xff & (plainDigit >>> shiftIndex); | ||
decoded[plainPos] = plainChar; | ||
decoded[+plainPos] = plainChar; | ||
plainPos++; | ||
@@ -101,0 +104,0 @@ plainChar = 0xff & (plainDigit << (8 - shiftIndex)); |
@@ -7,11 +7,5 @@ "use strict"; | ||
const randomBytes = function randomBytes(size) { | ||
return new Promise((resolve, reject) => { | ||
const buffer = new Uint8Array(size); | ||
crypto.randomFill(buffer, (error, buffer) => { | ||
if (buffer) return resolve(buffer); | ||
reject(error); | ||
}); | ||
}); | ||
return crypto.randomFillSync(new Uint8Array(size)); | ||
}; | ||
exports.hmac = hmac; | ||
exports.randomBytes = randomBytes; |
@@ -1,1 +0,1 @@ | ||
export type RandomBytes = (size: number) => Promise<Uint8Array>; | ||
export type RandomBytes = (size: number) => Uint8Array; |
import type { Hmac } from "./crypto/hmac"; | ||
import { HOTPOptions } from "./hotp.options"; | ||
/** | ||
* Generates HOTP code from secret key, counter and options | ||
* | ||
* | ||
* @export | ||
@@ -7,0 +7,0 @@ * @param {Hmac} hmac |
"use strict"; | ||
const hotp_options = require("./hotp.options.js"); | ||
const bytes = require("./bytes.js"), | ||
hotp_options = require("./hotp.options.js"); | ||
/** | ||
* Generates HOTP code from secret key, counter and options | ||
* | ||
* | ||
* @param {string} hex | ||
* @return {*} {Uint8Array} | ||
*/ | ||
function hexToBytes(hex) { | ||
const bytes = new Uint8Array(hex.length / 2); | ||
for (let index = 0; index < bytes.length; index++) { | ||
const string = hex.slice(index * 2, index * 2 + 2); | ||
bytes[index] = Number.parseInt(string, 16); | ||
} | ||
return bytes; | ||
} | ||
/** | ||
* | ||
* | ||
* @export | ||
@@ -30,17 +17,12 @@ * @param {Hmac} hmac | ||
); | ||
const hexCounter = merged.counter.toString(16).padStart(16, "0"); | ||
const digest = await hmac( | ||
merged.algorithm, | ||
merged.secret.bytes, | ||
hexToBytes(hexCounter) | ||
bytes.getBigIntBytes(merged.counter) | ||
); | ||
const offset = digest[digest.length - 1] & 0xf; | ||
const binary = | ||
((digest[offset] & 0x7f) << 24) | | ||
((digest[offset + 1] & 0xff) << 16) | | ||
((digest[offset + 2] & 0xff) << 8) | | ||
(digest[offset + 3] & 0xff); | ||
const token = binary % 10 ** merged.digits; | ||
return token.toString().padStart(merged.digits, "0"); | ||
const view = new DataView(digest.buffer); | ||
const binary = view.getUint32(offset) & 2147483647; | ||
return binary.toString().slice(-merged.digits); | ||
} | ||
exports.hotp = hotp; |
import { HmacAlgorithm } from "./crypto/hmac"; | ||
import { SecretKey } from "./key"; | ||
export type HOTPOptions = { | ||
/** | ||
* Secret key | ||
*/ | ||
secret: SecretKey; | ||
/** | ||
* Incrementing counter. From 0 to Number.MAX_SAFE_INTEGER (53 bits) | ||
*/ | ||
counter: number; | ||
/** | ||
* Count of digits. | ||
* - Any other than `6` is not supported by Google Authenticator | ||
* @default 6 | ||
*/ | ||
digits?: number; | ||
/** | ||
* Hash algorithms for generating new codes. | ||
* - Any other than `sha1` is not supported by Google Authenticator | ||
* @default "sha1" | ||
*/ | ||
algorithm?: HmacAlgorithm; | ||
@@ -8,0 +24,0 @@ }; |
@@ -6,5 +6,7 @@ export { SecretKey } from "./key"; | ||
export { hotp } from "./hotp"; | ||
export { HOTP } from "./hotp.class"; | ||
export { HOTPOptions, getDefaultHOTPOptions } from "./hotp.options"; | ||
export { totp } from "./totp"; | ||
export { TOTP } from "./totp.class"; | ||
export { TOTPOptions, getDefaultTOTPOptions } from "./totp.options"; | ||
export { getKeyUri, UriOptions } from "./uri"; |
@@ -5,4 +5,6 @@ "use strict"; | ||
hotp = require("./hotp.js"), | ||
hotp_class = require("./hotp.class.js"), | ||
hotp_options = require("./hotp.options.js"), | ||
totp = require("./totp.js"), | ||
totp_class = require("./totp.class.js"), | ||
totp_options = require("./totp.options.js"), | ||
@@ -15,5 +17,7 @@ uri = require("./uri.js"); | ||
exports.hotp = hotp.hotp; | ||
exports.HOTP = hotp_class.HOTP; | ||
exports.getDefaultHOTPOptions = hotp_options.getDefaultHOTPOptions; | ||
exports.totp = totp.totp; | ||
exports.TOTP = totp_class.TOTP; | ||
exports.getDefaultTOTPOptions = totp_options.getDefaultTOTPOptions; | ||
exports.getKeyUri = uri.getKeyUri; |
@@ -11,3 +11,3 @@ import type { RandomBytes } from "./crypto/random"; | ||
*/ | ||
export declare function generateKey(random: RandomBytes, size?: number): Promise<SecretKey>; | ||
export declare function generateKey(random: RandomBytes, size?: number): SecretKey; | ||
/** | ||
@@ -14,0 +14,0 @@ * |
@@ -12,4 +12,4 @@ "use strict"; | ||
*/ | ||
async function generateKey(random, size = 10) { | ||
return new key.SecretKey(await random(size)); | ||
function generateKey(random, size = 10) { | ||
return new key.SecretKey(random(size)); | ||
} | ||
@@ -34,3 +34,3 @@ /** | ||
function exportKey(key) { | ||
return base32.encode(key.bytes); | ||
return base32.encode(key.bytes, { pad: false }); | ||
} | ||
@@ -37,0 +37,0 @@ exports.exportKey = exportKey; |
import { Hmac } from "./crypto/hmac"; | ||
import { TOTPOptions } from "./totp.options"; | ||
/** | ||
* Generates TOTP code from secret key and options | ||
* | ||
* | ||
* @export | ||
@@ -10,3 +10,4 @@ * @param {Hmac} hmac | ||
* @return {Promise<string>} | ||
* @throws {Error} if HMAC algorithm is invalid. Use {@link HmacAlgorithm} to avoid this | ||
*/ | ||
export declare function totp(hmac: Hmac, options: TOTPOptions): Promise<string>; |
@@ -5,5 +5,25 @@ "use strict"; | ||
totp_options = require("./totp.options.js"); | ||
const keyLengths = new Map([ | ||
["sha1", 20], | ||
["sha256", 32], | ||
["sha512", 64] | ||
]); | ||
/** | ||
* | ||
* | ||
* @param {Uint8Array} buffer | ||
* @param {number} length | ||
* @return {Uint8Array} | ||
*/ | ||
function pad(buffer, length) { | ||
const factor = Math.ceil(length / buffer.length); | ||
const double = new Uint8Array(buffer.length * factor); | ||
for (let index = 0; index < factor; index++) { | ||
double.set(buffer, buffer.length * index); | ||
} | ||
return double.slice(0, length); | ||
} | ||
/** | ||
* Generates TOTP code from secret key and options | ||
* | ||
* @export | ||
@@ -13,2 +33,3 @@ * @param {Hmac} hmac | ||
* @return {Promise<string>} | ||
* @throws {Error} if HMAC algorithm is invalid. Use {@link HmacAlgorithm} to avoid this | ||
*/ | ||
@@ -23,25 +44,8 @@ async function totp(hmac, options) { | ||
if (merged.pad) { | ||
let minLength; | ||
switch (merged.algorithm) { | ||
case "sha1": { | ||
minLength = 20; | ||
break; | ||
} | ||
case "sha256": { | ||
minLength = 32; | ||
break; | ||
} | ||
case "sha512": { | ||
minLength = 64; | ||
break; | ||
} | ||
default: { | ||
throw new Error(`Invalid hmac algorithm: "${merged.algorithm}"`); | ||
} | ||
const length = keyLengths.get(merged.algorithm); | ||
if (length === undefined) { | ||
throw new Error(`Invalid hmac algorithm: "${merged.algorithm}"`); | ||
} | ||
while (bytes.length < minLength) { | ||
const double = new Uint8Array(bytes.length * 2); | ||
double.set(bytes, 0); | ||
double.set(bytes, bytes.length); | ||
bytes = double.slice(0, minLength); | ||
if (bytes.length < length) { | ||
bytes = pad(bytes, length); | ||
} | ||
@@ -48,0 +52,0 @@ } |
import { HmacAlgorithm } from "./crypto/hmac"; | ||
import { SecretKey } from "./key"; | ||
export type TOTPOptions = { | ||
/** | ||
* Secret key | ||
*/ | ||
secret: SecretKey; | ||
/** | ||
* Interval in seconds between code generation | ||
* - Any other than `30` is not supported by Google Authenticator | ||
* @default 30 | ||
*/ | ||
stepSeconds?: number; | ||
/** | ||
* Current date | ||
* @default Date() | ||
*/ | ||
now?: Date; | ||
/** | ||
* Count of digits. | ||
* - Any other than `6` is not supported by Google Authenticator | ||
* @default 6 | ||
*/ | ||
digits?: number; | ||
/** | ||
* Hash algorithms for generating new codes. | ||
* - Any other than `sha1` is not supported by Google Authenticator | ||
* @default "sha1" | ||
*/ | ||
algorithm?: HmacAlgorithm; | ||
/** | ||
* Enables padding of secret key. | ||
* - `true` - compatible with [RFC6238](https://www.ietf.org/rfc/rfc6238.txt) | ||
* - `false` - compatible with Google Authenticator | ||
* | ||
* @default false | ||
*/ | ||
pad?: boolean; | ||
@@ -10,0 +39,0 @@ }; |
@@ -24,4 +24,27 @@ QIWI SDK / [Modules](modules.md) | ||
- **Small.** Tree-shakable, 0 dependencies | ||
- **Tested.** Compatibility with Google Authenticator and with [RFC4226 (HOTP)](https://www.ietf.org/rfc/rfc4226.txt) and [RFC6238 (TOTP)](https://www.ietf.org/rfc/rfc6238.txt) | ||
- **Tested.** Compatibility with [Google Authenticator](https://github.com/google/google-authenticator/wiki/Key-Uri-Format) and with [RFC4226 (HOTP)](https://www.ietf.org/rfc/rfc4226.txt) and [RFC6238 (TOTP)](https://www.ietf.org/rfc/rfc6238.txt) | ||
## Install | ||
- `npm` | ||
```bash | ||
npm i otp-io | ||
``` | ||
- `Yarn` | ||
```bash | ||
yarn add otp-io | ||
``` | ||
## What is this? | ||
- `HOTP` - HMAC-based One Time Password generation method. Uses incrementing with each login `counter` and `secret` to generate unique 6-8 digit codes. | ||
- `TOTP` - Time-based, uses `current time` modulo `period` (seconds) as counter in `HOTP`, | ||
- `Google Authenticator` - uses simplified version of `TOTP` to generate codes. Differences: | ||
- Only `SHA-1` hash support | ||
- Only 6 digit codes | ||
- Keys should not be padded | ||
- TOTP period is 30 seconds | ||
Google Authenticator limits are defaults for this library. | ||
## How it works? | ||
@@ -32,7 +55,7 @@ | ||
import { totp, generateKey, getKeyUri } from "otp-io"; | ||
// 2. Import crypto adapter. Either `crypto-node` or `crypto-browser` - API is identical | ||
// 2. Import crypto adapter. Either `crypto-node` or `crypto-web` - API is identical | ||
import { hmac, randomBytes } from "otp-io/crypto-node"; | ||
// 3. Get key from somewhere. Or generate it | ||
const key = await generateKey(randomBytes, /* bytes: */ 20); // 5-20 good for Google Authenticator | ||
const key = generateKey(randomBytes, /* bytes: */ 20); // 5-20 good for Google Authenticator | ||
@@ -39,0 +62,0 @@ // 4. Get key import url |
{ | ||
"name": "otp-io", | ||
"version": "1.0.2", | ||
"version": "1.1.0", | ||
"description": "🕖 Typed library to work 2fa via Google Authenticator/Time-based TOTP/Hmac-based HOTP", | ||
@@ -32,6 +32,11 @@ "scripts": { | ||
}, | ||
"./crypto-web": { | ||
"require": "./crypto-web.js", | ||
"import": "./crypto-web.mjs", | ||
"types": "./crypto-web.d.ts" | ||
}, | ||
"./crypto-browser": { | ||
"require": "./crypto-browser.js", | ||
"import": "./crypto-browser.mjs", | ||
"types": "./crypto-browser.d.ts" | ||
"require": "./crypto-web.js", | ||
"import": "./crypto-web.mjs", | ||
"types": "./crypto-web.d.ts" | ||
} | ||
@@ -38,0 +43,0 @@ }, |
@@ -22,4 +22,27 @@ # OTP io | ||
- **Small.** Tree-shakable, 0 dependencies | ||
- **Tested.** Compatibility with Google Authenticator and with [RFC4226 (HOTP)](https://www.ietf.org/rfc/rfc4226.txt) and [RFC6238 (TOTP)](https://www.ietf.org/rfc/rfc6238.txt) | ||
- **Tested.** Compatibility with [Google Authenticator](https://github.com/google/google-authenticator/wiki/Key-Uri-Format) and with [RFC4226 (HOTP)](https://www.ietf.org/rfc/rfc4226.txt) and [RFC6238 (TOTP)](https://www.ietf.org/rfc/rfc6238.txt) | ||
## Install | ||
- `npm` | ||
```bash | ||
npm i otp-io | ||
``` | ||
- `Yarn` | ||
```bash | ||
yarn add otp-io | ||
``` | ||
## What is this? | ||
- `HOTP` - HMAC-based One Time Password generation method. Uses incrementing with each login `counter` and `secret` to generate unique 6-8 digit codes. | ||
- `TOTP` - Time-based, uses `current time` modulo `period` (seconds) as counter in `HOTP`, | ||
- `Google Authenticator` - uses simplified version of `TOTP` to generate codes. Differences: | ||
- Only `SHA-1` hash support | ||
- Only 6 digit codes | ||
- Keys should not be padded | ||
- TOTP period is 30 seconds | ||
Google Authenticator limits are defaults for this library. | ||
## How it works? | ||
@@ -30,7 +53,7 @@ | ||
import { totp, generateKey, getKeyUri } from "otp-io"; | ||
// 2. Import crypto adapter. Either `crypto-node` or `crypto-browser` - API is identical | ||
// 2. Import crypto adapter. Either `crypto-node` or `crypto-web` - API is identical | ||
import { hmac, randomBytes } from "otp-io/crypto-node"; | ||
// 3. Get key from somewhere. Or generate it | ||
const key = await generateKey(randomBytes, /* bytes: */ 20); // 5-20 good for Google Authenticator | ||
const key = generateKey(randomBytes, /* bytes: */ 20); // 5-20 good for Google Authenticator | ||
@@ -37,0 +60,0 @@ // 4. Get key import url |
import { hmac } from "../crypto-node"; | ||
import { importKey } from "../key.actions"; | ||
import { totp } from "../totp"; | ||
import { TOTP } from "../totp.class"; | ||
@@ -9,4 +9,5 @@ describe("Google Authenticator Compatability", () => { | ||
const secret = importKey("2XHHO3OW7NZZO5WX"); | ||
const totp = new TOTP(hmac, { secret, now }); | ||
const code = await totp(hmac, { secret, now }); | ||
const code = await totp.generateCode(); | ||
expect(code).toBe("434004"); | ||
@@ -18,6 +19,7 @@ }); | ||
const secret = importKey("NTMCQKWW4DJ2WD2SJAVFLOACB6MTLGR6"); | ||
const totp = new TOTP(hmac, { secret, now }); | ||
const code = await totp(hmac, { secret, now }); | ||
expect(code).toBe("351221"); | ||
const isValid = await totp.checkCode("351221"); | ||
expect(isValid).toBeTruthy(); | ||
}); | ||
}); |
@@ -1,2 +0,2 @@ | ||
import { HmacAlgorithm, SecretKey, hotp } from "../index"; | ||
import { HmacAlgorithm, SecretKey, HOTP } from "../index"; | ||
import { hmac } from "../crypto-node"; | ||
@@ -8,12 +8,14 @@ import { Buffer } from "buffer"; | ||
const secret = new SecretKey(Buffer.from("12345678901234567890", "ascii")); | ||
const hotp = new HOTP(hmac, { | ||
secret, | ||
algorithm: HmacAlgorithm.SHA1, | ||
digits: 6, | ||
counter: 0 | ||
}); | ||
function reference(counter: number, code: string) { | ||
test(`Counter: ${counter}`, async () => { | ||
const result = await hotp(hmac, { | ||
secret, | ||
algorithm: HmacAlgorithm.SHA1, | ||
digits: 6, | ||
counter | ||
}); | ||
const isValid = await hotp.checkCode(code, { counter }); | ||
expect(result).toBe(code); | ||
expect(isValid).toBeTruthy(); | ||
}); | ||
@@ -38,2 +40,8 @@ } | ||
} | ||
test("Increment", () => { | ||
expect(hotp.options.counter).toBe(0); | ||
expect(hotp.increment()).toBe(1); | ||
expect(hotp.options.counter).toBe(1); | ||
}); | ||
}); |
@@ -5,4 +5,4 @@ import { SecretKey, importKey, exportKey, generateKey } from ".."; | ||
describe(SecretKey.name, () => { | ||
test("Key", async () => { | ||
const key = await generateKey(randomBytes, 20); | ||
test("Key", () => { | ||
const key = generateKey(randomBytes, 20); | ||
expect(key.bytes.length).toBe(20); | ||
@@ -9,0 +9,0 @@ |
@@ -1,15 +0,31 @@ | ||
import { exportKey, generateKey, getKeyUri, HmacAlgorithm } from ".."; | ||
import { randomBytes } from "../crypto-node"; | ||
import { | ||
exportKey, | ||
generateKey, | ||
getKeyUri, | ||
HmacAlgorithm, | ||
HOTP, | ||
TOTP | ||
} from ".."; | ||
import { hmac, randomBytes } from "../crypto-node"; | ||
describe("URI generator", () => { | ||
test("totp", async () => { | ||
const secret = await generateKey(randomBytes); | ||
const name = "Account"; | ||
const issuer = "Test"; | ||
test("totp", () => { | ||
const secret = generateKey(randomBytes); | ||
const totp = new TOTP(hmac, { | ||
secret, | ||
algorithm: HmacAlgorithm.SHA256 | ||
}); | ||
const uri = getKeyUri({ | ||
secret, | ||
type: "totp", | ||
name: "Account", | ||
issuer: "Test", | ||
name, | ||
issuer, | ||
algorithm: HmacAlgorithm.SHA256 | ||
}); | ||
expect(totp.getUri(name, issuer)).toBe(uri); | ||
expect(uri).toContain("issuer=Test"); | ||
@@ -24,13 +40,14 @@ expect(uri).toContain("Test:Account"); | ||
test("hotp", async () => { | ||
const secret = await generateKey(randomBytes); | ||
test("hotp", () => { | ||
const secret = generateKey(randomBytes); | ||
const hotp = new HOTP(hmac, { secret, counter: 11, digits: 8 }); | ||
const uri = getKeyUri({ | ||
secret, | ||
...hotp.options, | ||
type: "hotp", | ||
counter: 11, | ||
name: "Account", | ||
issuer: "Test", | ||
digits: 8 | ||
name, | ||
issuer | ||
}); | ||
expect(uri).toBe(hotp.getUri(name, issuer)); | ||
expect(uri).toContain("counter=11"); | ||
@@ -37,0 +54,0 @@ expect(uri).toContain("digits=8"); |
@@ -1,5 +0,4 @@ | ||
/* eslint-disable security/detect-object-injection */ | ||
/* eslint-disable @typescript-eslint/no-non-null-assertion */ | ||
/* eslint-disable unicorn/prefer-code-point */ | ||
const charTable = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"; | ||
const byteTable = [ | ||
const byteTable = new Uint8Array([ | ||
0xff, 0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
@@ -12,3 +11,3 @@ 0xff, 0xff, 0xff, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, | ||
0xff, 0xff | ||
]; | ||
]); | ||
@@ -22,4 +21,5 @@ /** | ||
function quintetCount(buffer: Uint8Array) { | ||
const quintets = Math.floor(buffer.length / 5); | ||
return buffer.length % 5 === 0 ? quintets : quintets + 1; | ||
// const quintets = Math.floor(buffer.length / 5); | ||
// return buffer.length % 5 === 0 ? quintets : quintets + 1; | ||
return Math.ceil(buffer.length / 5); | ||
} | ||
@@ -34,5 +34,5 @@ | ||
*/ | ||
export function encode(plain: Uint8Array): string { | ||
export function encode(plain: Uint8Array, { pad = true } = {}): string { | ||
let index = 0; | ||
let index2 = 0; | ||
let encodedIndex = 0; | ||
let shiftIndex = 0; | ||
@@ -44,3 +44,3 @@ let digit = 0; | ||
while (index < plain.length) { | ||
const current = plain[index]!; | ||
const current = plain[+index]; | ||
if (shiftIndex > 3) { | ||
@@ -51,4 +51,3 @@ digit = current & (0xff >> shiftIndex); | ||
(digit << shiftIndex) | | ||
((index + 1 < plain.length ? plain[index + 1]! : 0) >> | ||
(8 - shiftIndex)); | ||
((index + 1 < plain.length ? plain[index + 1] : 0) >> (8 - shiftIndex)); | ||
index++; | ||
@@ -60,10 +59,16 @@ } else { | ||
} | ||
encoded[index2] = charTable.codePointAt(digit)!; | ||
index2++; | ||
encoded[+encodedIndex] = charTable.codePointAt(digit) as number; | ||
encodedIndex++; | ||
} | ||
for (index = index2; index < encoded.length; index++) { | ||
encoded[index] = 0x3d; // '='.charCodeAt(0) | ||
/* istanbul ignore if: padding not used in tests */ | ||
if (pad) { | ||
for (index = encodedIndex; index < encoded.length; index++) { | ||
encoded[+index] = 0x3d; // '='.charCodeAt(0) | ||
} | ||
} else { | ||
encoded.splice(encodedIndex); | ||
} | ||
return String.fromCodePoint(...encoded); | ||
return String.fromCharCode(...encoded); | ||
} | ||
@@ -85,3 +90,3 @@ | ||
const decoded = new Uint8Array(Math.ceil((encoded.length * 5) / 8)); | ||
const chars = encoded.split("").map((char) => char.codePointAt(0)); | ||
const chars = encoded.split("").map((char) => char.charCodeAt(0)); | ||
@@ -91,9 +96,12 @@ /* byte by byte isn't as pretty as octet by octet but tests a bit | ||
for (let index = 0; index < encoded.length; index++) { | ||
if (chars[index] === 0x3d) { | ||
/* istanbul ignore if: padding not used in tests */ | ||
if (chars[+index] === 0x3d) { | ||
// '=' | ||
break; | ||
} | ||
const encodedByte = chars[index]! - 0x30; | ||
const encodedByte = chars[+index] - 0x30; | ||
/* istanbul ignore else: invalid input not used in tests */ | ||
if (encodedByte < byteTable.length) { | ||
plainDigit = byteTable[encodedByte]!; | ||
plainDigit = byteTable[+encodedByte]; | ||
if (shiftIndex <= 3) { | ||
@@ -103,3 +111,3 @@ shiftIndex = (shiftIndex + 5) % 8; | ||
plainChar |= plainDigit; | ||
decoded[plainPos] = plainChar; | ||
decoded[+plainPos] = plainChar; | ||
plainPos++; | ||
@@ -113,3 +121,3 @@ plainChar = 0; | ||
plainChar |= 0xff & (plainDigit >>> shiftIndex); | ||
decoded[plainPos] = plainChar; | ||
decoded[+plainPos] = plainChar; | ||
plainPos++; | ||
@@ -116,0 +124,0 @@ plainChar = 0xff & (plainDigit << (8 - shiftIndex)); |
import { Hmac, HmacAlgorithm } from "./hmac"; | ||
import type { RandomBytes } from "./random"; | ||
const algorithmMap = new Map<HmacAlgorithm, string>([ | ||
[HmacAlgorithm.SHA1, "SHA-1"], | ||
[HmacAlgorithm.SHA256, "SHA-256"], | ||
[HmacAlgorithm.SHA512, "SHA-512"] | ||
]); | ||
export const hmac: Hmac = async function hmac(algorithm, key, message) { | ||
let name: string; | ||
const name = algorithmMap.get(algorithm); | ||
switch (algorithm) { | ||
case HmacAlgorithm.SHA1: { | ||
name = "SHA-1"; | ||
break; | ||
} | ||
case HmacAlgorithm.SHA256: { | ||
name = "SHA-256"; | ||
break; | ||
} | ||
case HmacAlgorithm.SHA512: { | ||
name = "SHA-512"; | ||
break; | ||
} | ||
default: { | ||
throw new Error(`Invalid hmac algorithm: "${algorithm}"`); | ||
} | ||
if (!name) { | ||
throw new Error(`Invalid algorithm: "${algorithm}"`); | ||
} | ||
@@ -29,6 +20,3 @@ | ||
key, | ||
{ | ||
name: "HMAC", | ||
hash: { name } | ||
}, | ||
{ name: "HMAC", hash: { name } }, | ||
false, | ||
@@ -42,3 +30,3 @@ ["sign", "verify"] | ||
export const randomBytes: RandomBytes = async function randomBytes(size) { | ||
export const randomBytes: RandomBytes = function randomBytes(size) { | ||
const buffer = new Uint8Array(size); | ||
@@ -45,0 +33,0 @@ |
@@ -1,2 +0,2 @@ | ||
import { createHmac, randomFill } from "crypto"; | ||
import { createHmac, randomFillSync } from "crypto"; | ||
import type { Hmac } from "./hmac"; | ||
@@ -10,11 +10,3 @@ import type { RandomBytes } from "./random"; | ||
export const randomBytes: RandomBytes = function randomBytes(size) { | ||
return new Promise((resolve, reject) => { | ||
const buffer = new Uint8Array(size); | ||
randomFill(buffer, (error, buffer) => { | ||
if (buffer) return resolve(buffer); | ||
reject(error); | ||
}); | ||
}); | ||
return randomFillSync(new Uint8Array(size)); | ||
}; |
@@ -1,1 +0,1 @@ | ||
export type RandomBytes = (size: number) => Promise<Uint8Array>; | ||
export type RandomBytes = (size: number) => Uint8Array; |
@@ -5,5 +5,24 @@ import { HmacAlgorithm } from "./crypto/hmac"; | ||
export type HOTPOptions = { | ||
/** | ||
* Secret key | ||
*/ | ||
secret: SecretKey; | ||
/** | ||
* Incrementing counter. From 0 to Number.MAX_SAFE_INTEGER (53 bits) | ||
*/ | ||
counter: number; | ||
/** | ||
* Count of digits. | ||
* - Any other than `6` is not supported by Google Authenticator | ||
* @default 6 | ||
*/ | ||
digits?: number; | ||
/** | ||
* Hash algorithms for generating new codes. | ||
* - Any other than `sha1` is not supported by Google Authenticator | ||
* @default "sha1" | ||
*/ | ||
algorithm?: HmacAlgorithm; | ||
@@ -10,0 +29,0 @@ }; |
@@ -1,3 +0,3 @@ | ||
/* eslint-disable security/detect-object-injection */ | ||
/* eslint-disable @typescript-eslint/no-non-null-assertion */ | ||
/* istanbul ignore */ | ||
import { getBigIntBytes } from "./bytes"; | ||
import type { Hmac } from "./crypto/hmac"; | ||
@@ -7,21 +7,4 @@ import { HOTPOptions, getDefaultHOTPOptions } from "./hotp.options"; | ||
/** | ||
* Generates HOTP code from secret key, counter and options | ||
* | ||
* | ||
* @param {string} hex | ||
* @return {*} {Uint8Array} | ||
*/ | ||
function hexToBytes(hex: string): Uint8Array { | ||
const bytes = new Uint8Array(hex.length / 2); | ||
for (let index = 0; index < bytes.length; index++) { | ||
const string = hex.slice(index * 2, index * 2 + 2); | ||
bytes[index] = Number.parseInt(string, 16); | ||
} | ||
return bytes; | ||
} | ||
/** | ||
* | ||
* | ||
* @export | ||
@@ -32,20 +15,19 @@ * @param {Hmac} hmac | ||
*/ | ||
export async function hotp(hmac: Hmac, options: HOTPOptions) { | ||
export async function hotp(hmac: Hmac, options: HOTPOptions): Promise<string> { | ||
const merged = { ...getDefaultHOTPOptions(), ...options }; | ||
const hexCounter = merged.counter.toString(16).padStart(16, "0"); | ||
const digest = await hmac( | ||
merged.algorithm, | ||
merged.secret.bytes, | ||
hexToBytes(hexCounter) | ||
getBigIntBytes(merged.counter) | ||
); | ||
const offset = digest[digest.length - 1]! & 0xf; | ||
const binary = | ||
((digest[offset]! & 0x7f) << 24) | | ||
((digest[offset + 1]! & 0xff) << 16) | | ||
((digest[offset + 2]! & 0xff) << 8) | | ||
(digest[offset + 3]! & 0xff); | ||
const token = binary % 10 ** merged.digits; | ||
return token.toString().padStart(merged.digits, "0"); | ||
// Truncates offset to 0-15 | ||
const offset = digest[digest.length - 1] & 0xf; | ||
const view = new DataView(digest.buffer); | ||
// Truncates unsigned int 32 to signed int 32 | ||
// 0x7fffffff - is max int32 value | ||
const binary = view.getUint32(offset) & 0x7f_ff_ff_ff; | ||
return binary.toString().slice(-merged.digits); | ||
} |
@@ -7,7 +7,9 @@ export { SecretKey } from "./key"; | ||
export { hotp } from "./hotp"; | ||
export { HOTP } from "./hotp.class"; | ||
export { HOTPOptions, getDefaultHOTPOptions } from "./hotp.options"; | ||
export { totp } from "./totp"; | ||
export { TOTP } from "./totp.class"; | ||
export { TOTPOptions, getDefaultTOTPOptions } from "./totp.options"; | ||
export { getKeyUri, UriOptions } from "./uri"; |
@@ -13,4 +13,4 @@ import { encode, decode } from "./base32"; | ||
*/ | ||
export async function generateKey(random: RandomBytes, size = 10) { | ||
return new SecretKey(await random(size)); | ||
export function generateKey(random: RandomBytes, size = 10): SecretKey { | ||
return new SecretKey(random(size)); | ||
} | ||
@@ -25,3 +25,3 @@ | ||
*/ | ||
export function importKey(base32text: string) { | ||
export function importKey(base32text: string): SecretKey { | ||
return new SecretKey(decode(base32text)); | ||
@@ -37,4 +37,4 @@ } | ||
*/ | ||
export function exportKey(key: SecretKey) { | ||
return encode(key.bytes); | ||
export function exportKey(key: SecretKey): string { | ||
return encode(key.bytes, { pad: false }); | ||
} |
@@ -5,7 +5,41 @@ import { HmacAlgorithm } from "./crypto/hmac"; | ||
export type TOTPOptions = { | ||
/** | ||
* Secret key | ||
*/ | ||
secret: SecretKey; | ||
/** | ||
* Interval in seconds between code generation | ||
* - Any other than `30` is not supported by Google Authenticator | ||
* @default 30 | ||
*/ | ||
stepSeconds?: number; | ||
/** | ||
* Current date | ||
* @default Date() | ||
*/ | ||
now?: Date; | ||
/** | ||
* Count of digits. | ||
* - Any other than `6` is not supported by Google Authenticator | ||
* @default 6 | ||
*/ | ||
digits?: number; | ||
/** | ||
* Hash algorithms for generating new codes. | ||
* - Any other than `sha1` is not supported by Google Authenticator | ||
* @default "sha1" | ||
*/ | ||
algorithm?: HmacAlgorithm; | ||
/** | ||
* Enables padding of secret key. | ||
* - `true` - compatible with [RFC6238](https://www.ietf.org/rfc/rfc6238.txt) | ||
* - `false` - compatible with Google Authenticator | ||
* | ||
* @default false | ||
*/ | ||
pad?: boolean; | ||
@@ -12,0 +46,0 @@ }; |
@@ -6,5 +6,29 @@ import { Hmac, HmacAlgorithm } from "./crypto/hmac"; | ||
const keyLengths = new Map<HmacAlgorithm, number>([ | ||
[HmacAlgorithm.SHA1, 20], | ||
[HmacAlgorithm.SHA256, 32], | ||
[HmacAlgorithm.SHA512, 64] | ||
]); | ||
/** | ||
* | ||
* | ||
* @param {Uint8Array} buffer | ||
* @param {number} length | ||
* @return {Uint8Array} | ||
*/ | ||
function pad(buffer: Uint8Array, length: number): Uint8Array { | ||
const factor = Math.ceil(length / buffer.length); | ||
const double = new Uint8Array(buffer.length * factor); | ||
for (let index = 0; index < factor; index++) { | ||
double.set(buffer, buffer.length * index); | ||
} | ||
return double.slice(0, length); | ||
} | ||
/** | ||
* Generates TOTP code from secret key and options | ||
* | ||
* @export | ||
@@ -14,4 +38,5 @@ * @param {Hmac} hmac | ||
* @return {Promise<string>} | ||
* @throws {Error} if HMAC algorithm is invalid. Use {@link HmacAlgorithm} to avoid this | ||
*/ | ||
export async function totp(hmac: Hmac, options: TOTPOptions) { | ||
export async function totp(hmac: Hmac, options: TOTPOptions): Promise<string> { | ||
const merged = { ...getDefaultTOTPOptions(), ...options }; | ||
@@ -23,28 +48,11 @@ const counter = Math.floor(merged.now.getTime() / 1000 / merged.stepSeconds); | ||
if (merged.pad) { | ||
let minLength: number; | ||
const length = keyLengths.get(merged.algorithm); | ||
switch (merged.algorithm) { | ||
case HmacAlgorithm.SHA1: { | ||
minLength = 20; | ||
break; | ||
} | ||
case HmacAlgorithm.SHA256: { | ||
minLength = 32; | ||
break; | ||
} | ||
case HmacAlgorithm.SHA512: { | ||
minLength = 64; | ||
break; | ||
} | ||
default: { | ||
throw new Error(`Invalid hmac algorithm: "${merged.algorithm}"`); | ||
} | ||
/* istanbul ignore if: invalid algorithms are not used in tests */ | ||
if (length === undefined) { | ||
throw new Error(`Invalid hmac algorithm: "${merged.algorithm}"`); | ||
} | ||
while (bytes.length < minLength) { | ||
const double = new Uint8Array(bytes.length * 2); | ||
double.set(bytes, 0); | ||
double.set(bytes, bytes.length); | ||
bytes = double.slice(0, minLength); | ||
if (bytes.length < length) { | ||
bytes = pad(bytes, length); | ||
} | ||
@@ -51,0 +59,0 @@ } |
@@ -57,2 +57,3 @@ import { HOTPOptions, getDefaultHOTPOptions } from "./hotp.options"; | ||
/* istanbul ignore next: invalid types are not used in tests */ | ||
default: { | ||
@@ -59,0 +60,0 @@ throw new Error(`Invalid method type: "${(options as UriOptions).type}"`); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
284135
110
2720
81