src/bll/credentialsstore/win32/win-credstore-api.ts (78 lines of code) (raw):
import {Credentials} from "../credentials";
import {Logger} from "../../utils/logger";
import {WinPersistentCredentialsStore} from "./win-credstore";
import {inject, injectable} from "inversify";
import {Constants, TYPES} from "../../utils/constants";
import {CredentialsStore} from "../credentialsstore";
@injectable()
export class WindowsCredentialStoreApi implements CredentialsStore {
public static separator: string = "|";
private winPersistentCredentialsStore: WinPersistentCredentialsStore;
constructor(@inject(TYPES.WinPersistentCredentialsStore) winPersistentCredentialsStore: WinPersistentCredentialsStore) {
this.winPersistentCredentialsStore = winPersistentCredentialsStore;
winPersistentCredentialsStore.setPrefix(Constants.SERVICE_PREFIX);
}
public async getCredentials(): Promise<Credentials> {
let credentials: Credentials;
const credentialsList: any[] = await this.listCredentials();
if (credentialsList.length > 0) {
credentials = WindowsCredentialStoreApi.createCredentials(credentialsList[0]);
}
if (credentialsList.length > 1) {
Logger.logWarning("[WindowsCredentialStoreApi::getCredential] there are more then one suitable credentials for the user! " +
"The first will be taken.");
}
return credentials;
}
public setCredentials(credentials: Credentials): Promise<void> {
const targetName: string = WindowsCredentialStoreApi.createTargetName(credentials.serverURL, credentials.user);
return this.winPersistentCredentialsStore.set(targetName, credentials.password);
}
public async removeCredentials(): Promise<void> {
const removeAllCredentialsWithPrefixMask: string = "*";
try {
await this.winPersistentCredentialsStore.remove(removeAllCredentialsWithPrefixMask);
} catch (err) {
if (!WindowsCredentialStoreApi.isCredentialsNotFoundCode(err)) {
throw err;
} else {
Logger.logError(`WindowsCredentialStoreApi#removeCredentials: ${err}`);
}
}
}
private static isCredentialsNotFoundCode(err: any): boolean {
const CREDENTIALS_ARE_NOT_FOUND_CODE: number = 1168;
return err.code !== undefined && err.code === CREDENTIALS_ARE_NOT_FOUND_CODE;
}
private static createCredentials(cred: any): Credentials {
const password: string = new Buffer(cred.credential, "hex").toString("utf8");
const segments: string[] = cred.targetName.split(WindowsCredentialStoreApi.separator);
const url: string = new Buffer(segments[0], "hex").toString("utf8");
const username: string = new Buffer(segments[1], "hex").toString("utf8");
return new Credentials(url, username, password, undefined, undefined);
}
private static createTargetName(url: string, username: string): string {
const encryptedUrl: string = new Buffer(url, "utf8").toString("hex");
const encryptedUsername: string = new Buffer(username, "utf8").toString("hex");
return encryptedUrl + WindowsCredentialStoreApi.separator + encryptedUsername;
}
private listCredentials(): Promise<Array<any>> {
const credentials: Array<any> = [];
return new Promise((resolve, reject) => {
const stream = this.winPersistentCredentialsStore.getCredentialsListStream();
stream.on("data", (cred) => {
credentials.push(cred);
});
stream.on("end", () => {
resolve(credentials);
});
stream.on("error", (error) => {
Logger.logError(error);
reject(error);
});
});
}
getCredentialsSilently(): Credentials {
throw new Error("Method not supported.");
}
}