AuditService (#2)
* Add AuditService. * Change sha1 to use Webcrypto. * Add interface for AuditService. * Move PwnedPasswodsApi constant outside class. * Change FromBufferToHex implementation to simpler code. * Use correct string to array function. * Change auditService interface to abstract class. Add missing type to utils.
This commit is contained in:
parent
ab00dfd399
commit
1aabb42e47
|
@ -0,0 +1,3 @@
|
|||
export abstract class AuditService {
|
||||
passwordLeaked: (password: string) => Promise<number>;
|
||||
}
|
|
@ -31,4 +31,5 @@ export abstract class CryptoService {
|
|||
decrypt: (cipherString: CipherString, key?: SymmetricCryptoKey, outputEncoding?: string) => Promise<string>;
|
||||
decryptFromBytes: (encBuf: ArrayBuffer, key: SymmetricCryptoKey) => Promise<ArrayBuffer>;
|
||||
rsaDecrypt: (encValue: string) => Promise<string>;
|
||||
sha1: (password: string) => Promise<string>;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
import { CryptoService } from '../abstractions/crypto.service';
|
||||
|
||||
const PwnedPasswordsApi = 'https://api.pwnedpasswords.com/range/';
|
||||
|
||||
export class AuditService {
|
||||
|
||||
constructor(private cryptoService: CryptoService) {
|
||||
}
|
||||
|
||||
async passwordLeaked(password: string): Promise<number> {
|
||||
const hash = (await this.cryptoService.sha1(password)).toUpperCase();
|
||||
|
||||
const response = await fetch(PwnedPasswordsApi + hash.substr(0, 5));
|
||||
const leakedHashes = await response.text();
|
||||
|
||||
const hashEnding = hash.substr(5);
|
||||
|
||||
const match = leakedHashes
|
||||
.split(/\r?\n/)
|
||||
.find((v) => {
|
||||
return v.split(':')[0] === hashEnding;
|
||||
});
|
||||
|
||||
return match ? parseInt(match.split(':')[1], 10) : 0;
|
||||
}
|
||||
}
|
|
@ -452,6 +452,17 @@ export class CryptoService implements CryptoServiceAbstraction {
|
|||
return b64DecValue;
|
||||
}
|
||||
|
||||
async sha1(password: string): Promise<string> {
|
||||
const hash = await Crypto.subtle.digest(
|
||||
{
|
||||
name: 'SHA-1',
|
||||
},
|
||||
UtilsService.fromUtf8ToArray(password),
|
||||
);
|
||||
|
||||
return UtilsService.fromBufferToHex(hash);
|
||||
}
|
||||
|
||||
// Helpers
|
||||
|
||||
private async aesEncrypt(plainValue: ArrayBuffer, key: SymmetricCryptoKey): Promise<EncryptedObject> {
|
||||
|
|
|
@ -125,6 +125,14 @@ export class UtilsService implements UtilsServiceAbstraction {
|
|||
return decodeURIComponent(escape(encodedString));
|
||||
}
|
||||
|
||||
// Source: Frxstrem, https://stackoverflow.com/questions/40031688/javascript-arraybuffer-to-hex
|
||||
static fromBufferToHex(buffer: ArrayBuffer): string {
|
||||
return Array.prototype.map.call(
|
||||
new Uint8Array(buffer),
|
||||
(x: number) => ('00' + x.toString(16)).slice(-2),
|
||||
).join('');
|
||||
}
|
||||
|
||||
static getHostname(uriString: string): string {
|
||||
if (uriString == null) {
|
||||
return null;
|
||||
|
|
Loading…
Reference in New Issue