appcenter-cli
Version:
Command line tool for Visual Studio App Center
151 lines (150 loc) • 5.76 kB
JavaScript
;
// Information storage and retrieval about the current user
//
// Right now we only support a single logged in user
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.deleteUser = exports.saveUser = exports.getUser = exports.toDefaultApp = void 0;
const fs = require("fs");
const path = require("path");
const mkdirp = require("mkdirp");
const environments_1 = require("./environments");
const misc_1 = require("../misc");
const token_store_1 = require("../token-store");
const debug = require("debug")("appcenter-cli:util:profile:profile");
class ProfileImpl {
constructor(fileContents) {
// This is slightly convoluted since file and API use different field names
// TODO: Normalize to match them up?
this.userId = fileContents.userId || fileContents.id;
this.userName = fileContents.userName || fileContents.name;
this.displayName = fileContents.displayName;
this.email = fileContents.email;
this.environment = fileContents.environment;
this.defaultApp = fileContents.defaultApp;
this.tokenSuppliedByUser = fileContents.tokenSuppliedByUser || false;
}
get accessTokenId() {
return token_store_1.tokenStore
.get(this.userName)
.then((entry) => entry.accessToken.id)
.catch((err) => {
debug(`Failed to get token id from profile, error: ${err.message}`);
throw err;
});
}
get accessToken() {
const getter = token_store_1.tokenStore.get(this.userName).catch((err) => {
debug(`Can't get token from tokenStore: ${err.message}`);
if (!err.message.includes("could not be found")) {
throw err;
}
debug(`Fallback to the old name in the keychain.`);
return token_store_1.tokenStore.get(this.userName, true);
});
return getter
.then((entry) => entry.accessToken.token)
.catch((err) => {
debug(`Failed to get token from profile, error: ${err.message}`);
throw err;
});
}
get endpoint() {
return environments_1.environments(this.environment).endpoint;
}
save() {
const profile = {
userId: this.userId,
userName: this.userName,
displayName: this.displayName,
email: this.email,
environment: this.environment,
defaultApp: this.defaultApp,
tokenSuppliedByUser: this.tokenSuppliedByUser,
};
mkdirp.sync(misc_1.getProfileDir());
fs.writeFileSync(getProfileFilename(), JSON.stringify(profile), { encoding: "utf8" });
return this;
}
setAccessToken(token) {
return token_store_1.tokenStore.set(this.userName, token).then(() => this);
}
logout() {
return __awaiter(this, void 0, void 0, function* () {
yield token_store_1.tokenStore.remove(this.userName);
try {
fs.unlinkSync(getProfileFilename());
}
catch (err) {
if (err.code !== "ENOENT") {
// File not found is fine, anything else pass on the error
throw err;
}
}
});
}
}
const validApp = /^([a-zA-Z0-9-_.]{1,100})\/([a-zA-Z0-9-_.]{1,100})$/;
function toDefaultApp(app) {
const matches = app.match(validApp);
if (matches !== null) {
return {
ownerName: matches[1],
appName: matches[2],
identifier: `${matches[1]}/${matches[2]}`,
};
}
return null;
}
exports.toDefaultApp = toDefaultApp;
let currentProfile = null;
function getProfileFilename() {
const profileDir = misc_1.getProfileDir();
return path.join(profileDir, misc_1.profileFile);
}
function loadProfile() {
const profilePath = getProfileFilename();
debug(`Loading profile from ${profilePath}`);
if (!misc_1.fileExistsSync(profilePath)) {
debug("No profile file exists");
return null;
}
debug("Profile file loaded");
const profileContents = fs.readFileSync(profilePath, "utf8");
const profile = JSON.parse(profileContents);
return new ProfileImpl(profile);
}
function getUser() {
debug("Getting current user from profile");
if (!currentProfile) {
debug("No current user, loading from file");
currentProfile = loadProfile();
}
return currentProfile;
}
exports.getUser = getUser;
function saveUser(user, token, environment, tokenSuppliedByUser) {
return token_store_1.tokenStore.set(user.name, token).then(() => {
const profile = new ProfileImpl(Object.assign({}, user, { environment, tokenSuppliedByUser }));
profile.save();
return profile;
});
}
exports.saveUser = saveUser;
function deleteUser() {
return __awaiter(this, void 0, void 0, function* () {
const profile = getUser();
if (profile) {
return profile.logout();
}
});
}
exports.deleteUser = deleteUser;