Skip to content
This repository was archived by the owner on Dec 12, 2022. It is now read-only.

Commit e1de6bb

Browse files
authored
Merge pull request #143 from NativeScript/tnikolov/kinvey-auth
Allow Kinvey Studio users to perform cloud builds
2 parents dd58518 + 9e526f7 commit e1de6bb

12 files changed

+183
-62
lines changed

lib/bootstrap.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ $injector.require("nsCloudOptionsProvider", path.join(__dirname, "cloud-options-
99
$injector.require("nsCloudBuildHelper", path.join(__dirname, "cloud-build-helper"));
1010
$injector.require("nsCloudBuildCommandHelper", path.join(__dirname, "commands", "build-command-helper"));
1111
$injector.require("nsCloudEulaCommandHelper", path.join(__dirname, "commands", "eula-command-helper"));
12+
$injector.require("nsCloudKinveyUserService", path.join(__dirname, "services", "kinvey-user-service"));
13+
$injector.require("nsCloudTelerikUserService", path.join(__dirname, "services", "telerik-user-service"));
1214

1315
// Mobile.
1416
$injector.require("nsCloudEmulatorDeviceDiscovery", path.join(__dirname, "mobile", "mobile-core", "cloud-emulator-device-discovery"));

lib/cloud-options-provider.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export class CloudOptionsProvider implements ICloudOptionsProvider {
77
apiVersion: { type: OptionType.String },
88
local: { type: OptionType.Boolean },
99
serverProto: { type: OptionType.String },
10+
namespace: { type: OptionType.String },
1011
sharedCloud: { type: OptionType.Boolean },
1112
workflow: { type: OptionType.Object },
1213
vmTemplateName: { type: OptionType.String },

lib/commands/config/config-apply.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export class ConfigApplyCommand implements ICommand {
1212

1313
public async execute(args: string[]): Promise<void> {
1414
const configurationName = args[0];
15-
const globalServerConfig: IServerConfigBase = { apiVersion: this.$options.apiVersion, serverProto: this.$options.serverProto };
15+
const globalServerConfig: IServerConfigBase = { apiVersion: this.$options.apiVersion, serverProto: this.$options.serverProto, namespace: this.$options.namespace };
1616
this.$nsCloudServerConfigManager.applyConfig(configurationName, null, globalServerConfig);
1717
this.$nsCloudServerConfigManager.printConfigData();
1818
}

lib/constants.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@ export const HTTP_HEADERS = {
7676
AUTHORIZATION: "Authorization",
7777
CONNECTION: "Connection",
7878
CONTENT_TYPE: "Content-Type",
79-
LOCATION: "Location"
79+
LOCATION: "Location",
80+
X_NS_NAMESPACE: "X-NS-Namespace"
8081
};
8182

8283
export const HTTP_STATUS_CODES = {

lib/definitions/authentication-service.d.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,3 +83,17 @@ interface IUserInfo {
8383
isProfilePublic: boolean;
8484
twitterName: String;
8585
}
86+
87+
interface IKinveyUserData {
88+
email: string;
89+
firstName: string;
90+
lastName: string
91+
lastLoginTime?: Date;
92+
name?: string;
93+
token: string;
94+
twoFactorAuth?: IKinveyTwoFactorAuth
95+
}
96+
97+
interface IKinveyTwoFactorAuth {
98+
enabled: boolean;
99+
}

lib/definitions/cloud-options.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ interface ICloudOptions extends IOptions, ISharedCloud {
66
apiVersion: string;
77
local: boolean;
88
serverProto: string;
9+
namespace: string;
910
track: string;
1011
workflow: IWorkflowPropertyOptions;
1112
vmTemplateName: string;

lib/definitions/server-config-manager.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ interface IServerConfigManager {
2323
interface IServerConfigBase {
2424
apiVersion?: string;
2525
serverProto?: string;
26+
namespace?: string;
2627
}
2728

2829
interface IServerConfig extends IServerConfigBase {

lib/services/kinvey-user-service.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { join } from "path";
2+
import { home } from "osenv";
3+
4+
import { UserServiceBase } from "./user-service-base";
5+
6+
export class KinveyUserService extends UserServiceBase implements IUserService {
7+
constructor(private $hostInfo: IHostInfo,
8+
$injector: IInjector,
9+
$logger: ILogger,
10+
$fs: IFileSystem,
11+
$errors: IErrors) {
12+
super($injector, $logger, $fs, $errors);
13+
this.userFilePath = this.getUserFilePath();
14+
}
15+
16+
public getUserData(): IUserData {
17+
const userData: IKinveyUserData = super.getUserData();
18+
return {
19+
accessToken: userData.token,
20+
refreshToken: "",
21+
userInfo: {
22+
email: userData.email,
23+
firstName: userData.firstName,
24+
lastName: userData.lastName
25+
}
26+
};
27+
}
28+
29+
public setUserData(userData: IUserData): void {
30+
const kinveyUserData: IKinveyUserData = {
31+
email: userData.userInfo.email,
32+
firstName: userData.userInfo.firstName,
33+
lastName: userData.userInfo.lastName,
34+
token: userData.accessToken
35+
};
36+
37+
super.setUserData(kinveyUserData);
38+
}
39+
40+
private getUserFilePath(): string {
41+
return join(this.$hostInfo.isWindows ? join(process.env.AppData) : join(home(), ".local", "share"),
42+
"KinveyStudio",
43+
"kinveyUser.json");
44+
}
45+
}
46+
47+
$injector.register("nsCloudKinveyUserService", KinveyUserService);

lib/services/server/server-services-proxy.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ export class ServerServicesProxy implements IServerServicesProxy {
2222
headers[HTTP_HEADERS.AUTHORIZATION] = `${authScheme} ${this.$nsCloudUserService.getUserData().accessToken}`;
2323
}
2424

25+
const namespace = this.getServiceValueOrDefault(options.serviceName, "namespace");
26+
if (namespace) {
27+
headers[HTTP_HEADERS.X_NS_NAMESPACE] = namespace;
28+
}
29+
2530
if (options.accept) {
2631
headers[HTTP_HEADERS.ACCEPT] = options.accept;
2732
}

lib/services/telerik-user-service.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { join } from "path";
2+
import { home } from "osenv";
3+
4+
import { UserServiceBase } from "./user-service-base";
5+
6+
export class TelerikUserService extends UserServiceBase implements IUserService {
7+
constructor(private $hostInfo: IHostInfo,
8+
$injector: IInjector,
9+
$logger: ILogger,
10+
$fs: IFileSystem,
11+
$errors: IErrors) {
12+
super($injector, $logger, $fs, $errors);
13+
this.userFilePath = this.getUserFilePath();
14+
}
15+
16+
private getUserFilePath(): string {
17+
return join(this.$hostInfo.isWindows ? process.env.LocalAppData : join(home(), ".local", "share"),
18+
"Telerik",
19+
"NativeScript",
20+
".nativescript-user");
21+
}
22+
}
23+
24+
$injector.register("nsCloudTelerikUserService", TelerikUserService);

lib/services/user-service-base.ts

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
export abstract class UserServiceBase {
2+
protected userFilePath: string;
3+
4+
private get $nsCloudServerAccountsService(): IServerAccountsService {
5+
return this.$injector.resolve<IServerAccountsService>("nsCloudServerAccountsService");
6+
}
7+
8+
constructor(private $injector: IInjector,
9+
private $logger: ILogger,
10+
private $fs: IFileSystem,
11+
private $errors: IErrors) { }
12+
13+
public hasUser(): boolean {
14+
try {
15+
const user = this.getUser();
16+
return !!user;
17+
} catch (err) {
18+
return false;
19+
}
20+
}
21+
22+
public getUser(): IUser {
23+
const userData = this.getUserData();
24+
25+
return userData.userInfo;
26+
}
27+
28+
public getUserData(): any {
29+
try {
30+
return this.$fs.readJson(this.userFilePath);
31+
} catch (err) {
32+
this.$logger.trace("Error while getting current user info:");
33+
this.$logger.trace(err);
34+
this.$errors.failWithoutHelp("Not logged in.");
35+
}
36+
}
37+
38+
public setToken(token: ITokenData): void {
39+
if (token) {
40+
const newUserData = _.extend(this.getUserData(), token);
41+
this.setUserData(newUserData);
42+
} else {
43+
this.clearUserData();
44+
}
45+
}
46+
47+
public setUserData(userData: any): void {
48+
if (userData) {
49+
this.$fs.writeJson(this.userFilePath, userData);
50+
} else {
51+
this.$fs.deleteFile(this.userFilePath);
52+
}
53+
}
54+
55+
public clearUserData(): void {
56+
this.$fs.deleteFile(this.userFilePath);
57+
}
58+
59+
public async getUserAvatar(): Promise<string> {
60+
if (!this.hasUser()) {
61+
return null;
62+
}
63+
64+
const userInfo = await this.$nsCloudServerAccountsService.getUserInfo();
65+
return userInfo.externalAvatarUrl;
66+
}
67+
}

lib/services/user-service.ts

Lines changed: 18 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,89 +1,47 @@
1-
import { join } from "path";
2-
import { home } from "osenv";
3-
41
export class UserService implements IUserService {
5-
private userData: IUserData;
6-
private userInfoDirectory: string;
7-
8-
private get $nsCloudServerAccountsService(): IServerAccountsService {
9-
return this.$injector.resolve("nsCloudServerAccountsService");
10-
}
2+
private userService: IUserService;
113

124
constructor(private $injector: IInjector,
13-
private $errors: IErrors,
14-
private $fs: IFileSystem,
15-
private $hostInfo: IHostInfo,
16-
private $logger: ILogger) {
17-
this.userInfoDirectory = join(this.$hostInfo.isWindows ? process.env.LocalAppData : join(home(), ".local", "share"),
18-
"Telerik",
19-
"NativeScript");
5+
private $nsCloudServerConfigManager: IServerConfigManager) {
6+
this.userService = this.determineUserService();
207
}
218

229
public hasUser(): boolean {
23-
try {
24-
const user = this.getUser();
25-
return !!user;
26-
} catch (err) {
27-
return false;
28-
}
10+
return this.userService.hasUser();
2911
}
3012

3113
public getUser(): IUser {
32-
const userData = this.getUserData();
33-
34-
return userData.userInfo;
14+
return this.userService.getUser();
3515
}
3616

3717
public getUserData(): IUserData {
38-
const filePath = this.getUserFilePath();
39-
let data: IUserData;
40-
41-
try {
42-
data = this.$fs.readJson(filePath);
43-
} catch (err) {
44-
this.$logger.trace("Error while getting current user info:");
45-
this.$logger.trace(err);
46-
this.$errors.failWithoutHelp("Not logged in.");
47-
}
48-
49-
return data;
18+
return this.userService.getUserData();
5019
}
5120

5221
public setToken(token: ITokenData): void {
53-
if (token) {
54-
const newUserData = _.extend(this.getUserData(), token);
55-
this.setUserData(newUserData);
56-
} else {
57-
this.clearUserData();
58-
}
22+
return this.userService.setToken(token);
5923
}
6024

6125
public setUserData(userData: IUserData): void {
62-
if (userData) {
63-
this.userData = userData;
64-
this.$fs.writeJson(this.getUserFilePath(), userData);
65-
} else {
66-
this.userData = null;
67-
this.$fs.deleteFile(this.getUserFilePath());
68-
}
26+
return this.userService.setUserData(userData);
6927
}
7028

7129
public clearUserData(): void {
72-
this.userData = null;
73-
this.$fs.deleteFile(this.getUserFilePath());
30+
this.userService.clearUserData();
7431
}
7532

7633
public async getUserAvatar(): Promise<string> {
77-
if (!this.hasUser()) {
78-
return null;
79-
}
80-
81-
const userInfo = await this.$nsCloudServerAccountsService.getUserInfo();
82-
return userInfo.externalAvatarUrl;
34+
return this.userService.getUserAvatar();
8335
}
8436

85-
private getUserFilePath(): string {
86-
return join(this.userInfoDirectory, ".nativescript-user");
37+
private determineUserService(): IUserService {
38+
const serverConfig = this.$nsCloudServerConfigManager.getCurrentConfigData();
39+
const namespace: string = serverConfig["namespace"];
40+
if (namespace && namespace.toLowerCase() === "kinvey") {
41+
return this.$injector.resolve<IUserService>("nsCloudKinveyUserService");
42+
}
43+
44+
return this.$injector.resolve<IUserService>("nsCloudTelerikUserService");
8745
}
8846
}
8947

0 commit comments

Comments
 (0)