Skip to content

[msal-node] Cache-1: Msal node cache entities #1444

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 109 commits into from
May 20, 2020
Merged
Show file tree
Hide file tree
Changes from 34 commits
Commits
Show all changes
109 commits
Select commit Hold shift + click to select a range
076ecb3
Adding knownAuthorities() and B2CAuthority
sameerag Mar 26, 2020
679425b
Merge branch 'msal-node-logging' into msal-node-authority
sameerag Mar 26, 2020
c4fe6c0
addressing feedback and in sync with PR #1416
sameerag Mar 26, 2020
4d31901
Merge branch 'sagonzal/device-code' into msal-node-authority
sameerag Mar 27, 2020
7a9cefc
Update package.json
sameerag Mar 27, 2020
b846ebc
Merge branch 'sagonzal/device-code' into msal-node-authority
sameerag Mar 31, 2020
ae43cea
addressing feedback
sameerag Mar 31, 2020
eb02ba3
Cache entities
sameerag Mar 31, 2020
b66e3dd
Add Account
sameerag Apr 1, 2020
fda585d
Add AccountCache
sameerag Apr 1, 2020
9868ae0
Cache helpers and Serialization Code
sameerag Apr 2, 2020
a66906f
Fix a bug in AuthorityFactory.ts
sameerag Apr 2, 2020
4a6fc0f
Merge branch 'msal-node-authority' into msal-node-cache-entities
sameerag Apr 2, 2020
33efd5d
Add tests and merge msal-node-tests
sameerag Apr 3, 2020
cb2cf62
Merge remote-tracking branch 'origin/sagonzal/msal-node-tests' into m…
sameerag Apr 3, 2020
5a680a6
merge msal-node-tests
sameerag Apr 3, 2020
80b2e1d
remove log stmt
sameerag Apr 3, 2020
2662d04
Merge branch 'msal-node-authority' into msal-node-cache-entities
sameerag Apr 3, 2020
890ed57
Merge branch 'msal-node-logging' into msal-node-authority
sameerag Apr 3, 2020
5228945
Merge branch 'msal-node-cache-entities' into msal-node-cache-utils
sameerag Apr 7, 2020
61569c9
More serialization code
sameerag Apr 7, 2020
735ace6
Merge branch 'msal-node-logging' into msal-node-authority
sameerag Apr 7, 2020
9001c8b
Merge branch 'msal-node-authority' into msal-node-cache-entities
sameerag Apr 7, 2020
8834420
Merge branch 'msal-node-cache-entities' into msal-node-cache-utils
sameerag Apr 7, 2020
75f5e8e
Serialize, Deserialize code, unit tests
sameerag Apr 9, 2020
ca9bc66
Merge branch 'msal-node-logging' into msal-node-authority
sameerag Apr 9, 2020
e93edb0
Add unit tests fpr authority changes
sameerag Apr 9, 2020
ea8cf9a
Merge branch 'msal-node-authority' into msal-node-cache-entities
sameerag Apr 9, 2020
85387c1
Merge branch 'msal-node-cache-entities' into msal-node-cache-utils
sameerag Apr 9, 2020
888c13c
Update UT for AccessTokenEntity
sameerag Apr 9, 2020
f0255ee
Initial changes
sameerag Apr 9, 2020
0512a01
Merge branch 'msal-node-cache-utils' into msal-node-cache-generator
sameerag Apr 9, 2020
2a23b57
Addressing feedback and fixing tests
sameerag Apr 9, 2020
fb4c5cf
Initiate knownAuthorities in msal-node
sameerag Apr 9, 2020
aed2a50
Merge branch 'msal-node-authority' into msal-node-cache-entities
sameerag Apr 9, 2020
6a59e1f
Merge branch 'msal-node-base' into msal-node-cache-entities
sameerag Apr 10, 2020
7bea70c
Merge branch 'msal-node-cache-entities' into msal-node-cache-utils
sameerag Apr 10, 2020
f58fa41
git merge msal-node-logging
sameerag Apr 11, 2020
0fdafe9
Merge branch 'msal-node-authority' into msal-node-cache-utils
sameerag Apr 12, 2020
67311ff
Add client_info for tokenResponse
sameerag Apr 12, 2020
60523ee
Merge branch 'msal-node-authority' into msal-node-cache-entities
sameerag Apr 12, 2020
ebf12b2
rename folder, address feedback
sameerag Apr 12, 2020
c004275
Merge branch 'msal-node-logging' into msal-node-authority
sameerag Apr 12, 2020
b0d8ad9
Merge branch 'msal-node-authority' into msal-node-cache-entities
sameerag Apr 12, 2020
6cee693
Merge branch 'msal-node-cache-entities' into msal-node-cache-utils
sameerag Apr 12, 2020
85e64c4
update cache folder name, move to generics
sameerag Apr 13, 2020
e90fda9
Address feedback
sameerag Apr 13, 2020
1124a56
Merge branch 'msal-node-cache-utils' into msal-node-cache-generator
sameerag Apr 13, 2020
8633ceb
add client_info in response
sameerag Apr 13, 2020
2dd9672
Adding ResponseHandler, AuthenticationResult generation and Credentia…
sameerag Apr 13, 2020
00d639e
All changes - will create separate PRs later
sameerag Apr 16, 2020
b974367
End-to-End cache read/write working
sameerag Apr 17, 2020
b9badaa
Optimization to serialization/deserialization
sameerag Apr 17, 2020
461a8c5
Merge branch 'msal-node-cache-utils' into msal-node-cache-generator
sameerag Apr 17, 2020
5bf084e
Address feedback in function names
sameerag Apr 17, 2020
3371ff5
More changes for the demo
sameerag Apr 19, 2020
516d004
Cache PR - Add Storage, token generation and rename response
sameerag Apr 20, 2020
185be7c
Response Initial changes
sameerag Apr 20, 2020
4f98589
Update node with result type
sameerag Apr 20, 2020
bf00ed5
Final changes for cache end-to-end Phase-I
sameerag Apr 20, 2020
29b4210
Update CacheTypes include
sameerag Apr 20, 2020
32b30b7
Updated tests
sameerag Apr 24, 2020
5c62e0d
Merge branch 'msal-node-cache-entities' into msal-node-cache-utils
sameerag Apr 24, 2020
813a341
Remove dup types
sameerag Apr 24, 2020
8169a5b
Added tests; Updated feedback response
sameerag Apr 24, 2020
f519782
Adding more tests
sameerag May 1, 2020
5cc8f0a
Merge branch 'msal-node-base' into msal-node-cache-entities
sameerag May 1, 2020
f61a4e8
Merge branch 'msal-node-cache-entities' into msal-node-cache-utils
sameerag May 1, 2020
62ba010
Merge branch 'msal-node-cache-utils' into msal-node-response-cacheTokens
sameerag May 1, 2020
4e32965
Addressing feedback
sameerag May 1, 2020
53d2200
Merge branch 'msal-node-response-cacheTokens' into msal-node-response
sameerag May 1, 2020
8f93841
addressing comments
sameerag May 1, 2020
75877aa
Merge branch 'msal-node-response' into msal-node-cache-final
sameerag May 1, 2020
e4c1316
Update Storage.ts
sameerag May 1, 2020
49908e6
Merge branch 'msal-node-response' into msal-node-cache-final
sameerag May 1, 2020
63f4e44
Fixing compiler issues
sameerag May 1, 2020
7b67e10
Merge branch 'dev' into msal-node-cache-entities
sameerag May 6, 2020
daef4b6
update as per dev
sameerag May 6, 2020
5b06d3e
Merge branch 'msal-node-cache-entities' into msal-node-cache-utils
sameerag May 6, 2020
a459a2f
Merge branch 'msal-node-cache-utils' into msal-node-response-cacheTokens
sameerag May 6, 2020
df671bb
Fixing compiler issues
sameerag May 6, 2020
cbf1105
Merge branch 'msal-node-response-cacheTokens' into msal-node-response
sameerag May 6, 2020
cfa4b6d
Merge branch 'msal-node-response' into msal-node-cache-final
sameerag May 6, 2020
36ac337
remove duplicate declaration in merge
sameerag May 6, 2020
4c77d1c
Merge pull request #1522 from AzureAD/msal-node-cache-final
sameerag May 6, 2020
5e4d601
Merge pull request #1520 from AzureAD/msal-node-response
sameerag May 8, 2020
cf6df64
Merge pull request #1519 from AzureAD/msal-node-response-cacheTokens
sameerag May 8, 2020
de5e99c
Merge pull request #1471 from AzureAD/msal-node-cache-utils
sameerag May 8, 2020
bbe3f84
Merge code, aync read/write
sameerag May 10, 2020
07df0a6
Update function names in default Config
sameerag May 10, 2020
e88e95d
Adding test support
sameerag May 10, 2020
2103928
Fix linter errors
sameerag May 11, 2020
d6baa29
remove unused type
sameerag May 11, 2020
19eb25a
fix linter issue in browser storage
sameerag May 11, 2020
b9d63a8
Merge branch 'dev' into msal-node-cache-fileops-async
sameerag May 11, 2020
9f88651
Add dev changes to SPAResponseHandler
sameerag May 11, 2020
18d5c1c
Update commented code
sameerag May 11, 2020
789fb45
Updateds for browser tests
sameerag May 11, 2020
e0a2422
Merge branch 'dev' into msal-node-cache-entities
sameerag May 11, 2020
7258a04
Merge branch 'msal-node-cache-entities' into msal-node-cache-fileops-…
sameerag May 11, 2020
000c646
Update sample with writeToDisk and mark file lock APIs
sameerag May 11, 2020
db845ff
merge dev into branch
DarylThayil May 12, 2020
98d4b65
remove file read and write from node lib
DarylThayil May 13, 2020
73ebd27
Merge pull request #1652 from AzureAD/removefile
DarylThayil May 19, 2020
daa1da9
Merge branch 'dev' into msal-node-cache-entities
sameerag May 20, 2020
adae586
Merge pull request #1622 from AzureAD/msal-node-cache-fileops-async
sameerag May 20, 2020
c03d8eb
Merge branch 'msal-node-cache-entities' of https://github.com/AzureAD…
sameerag May 20, 2020
93f0021
Update Storage
sameerag May 20, 2020
b6803ba
fix linter/tests to merge to dev
sameerag May 20, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -255,9 +255,6 @@ paket-files/
.DS_Store
.DS_Store?

# Visual Studio code
.vscode/

# MSAL specific ignore files
node_modules/
.nyc_output/
Expand Down
6 changes: 6 additions & 0 deletions lib/msal-common/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion lib/msal-common/src/authority/Authority.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ export abstract class Authority {
* @param urlString
*/
private replaceTenant(urlString: string): string {
return urlString.replace("{tenant}", this.tenant);
return urlString.replace(/{tenant}|{tenantid}/g, this.tenant);
}

/**
Expand Down
35 changes: 27 additions & 8 deletions lib/msal-common/src/authority/AuthorityFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,19 @@ import { ClientAuthError } from "./../error/ClientAuthError";
import { INetworkModule } from "./../network/INetworkModule";
import { StringUtils } from "./../utils/StringUtils";
import { UrlString } from "./../url/UrlString";
import { B2cAuthority, B2CTrustedHostList } from "./B2cAuthority";

export class AuthorityFactory {
/**
* Use when Authority is B2C to provide list of trusted/allowed domains.
*/
public static setKnownAuthorities(knownAuthorities: Array<string>): void {
if (!B2CTrustedHostList.length) {
knownAuthorities.forEach(function(authority){
B2CTrustedHostList.push(authority);
});
}
}

/**
* Parse the url and determine the type of authority
Expand All @@ -20,14 +31,16 @@ export class AuthorityFactory {
const authorityUrl = new UrlString(authorityString);
const components = authorityUrl.getUrlComponents();
const pathSegments = components.PathSegments;
switch (pathSegments[0]) {
case "tfp":
// tfp denotes a b2c url
return AuthorityType.B2C;
default:
// default authority is always AAD
return AuthorityType.Aad;

if (pathSegments[0] === "adfs") {
return AuthorityType.Adfs;
}
else if (B2CTrustedHostList.length) {
return AuthorityType.B2C;
}

// defaults to Aad
return AuthorityType.Aad;
}

/**
Expand All @@ -41,12 +54,18 @@ export class AuthorityFactory {
}

const type = AuthorityFactory.detectAuthorityFromUrl(authorityUrl);

// Depending on above detection, create the right type.
switch (type) {
case AuthorityType.Aad:
return new AadAuthority(authorityUrl, networkInterface);
case AuthorityType.B2C:
return new B2cAuthority(authorityUrl, networkInterface);
// TODO: Support ADFS here in a later PR
default:
throw ClientAuthError.createInvalidAuthorityTypeError(`Given Url: ${authorityUrl}`);
throw ClientAuthError.createInvalidAuthorityTypeError(
`${authorityUrl}`
);
}
}
}
44 changes: 44 additions & 0 deletions lib/msal-common/src/authority/B2cAuthority.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
import { Authority } from "./Authority";
import { AuthorityType } from "./AuthorityType";
import { ClientConfigurationError } from "../error/ClientConfigurationError";
import { INetworkModule } from "../network/INetworkModule";

export const B2CTrustedHostList: string[] = [];

/**
* The AadAuthority class extends the Authority class and adds functionality specific to the Azure AD OAuth Authority.
*/
export class B2cAuthority extends Authority {
// Set authority type to AAD
public get authorityType(): AuthorityType {
return AuthorityType.B2C;
}

public constructor(authority: string, networkInterface: INetworkModule) {
super(authority, networkInterface);
}

/**
* Returns a promise which resolves to the OIDC endpoint
* Only responds with the endpoint
*/
public async getOpenIdConfigurationEndpointAsync(): Promise<string> {
if (this.isInTrustedHostList(this.canonicalAuthorityUrlComponents.HostNameAndPort)) {
return this.defaultOpenIdConfigurationEndpoint;
}

throw ClientConfigurationError.createUntrustedAuthorityError();
}

/**
* Checks to see if the host is in a list of trusted hosts
* @param {string} The host to look up
*/
private isInTrustedHostList(host: string): boolean {
return B2CTrustedHostList.includes(host);
}
}
6 changes: 3 additions & 3 deletions lib/msal-common/src/client/AuthorizationCodeClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ import { RequestParameterBuilder } from "../server/RequestParameterBuilder";
import { RequestValidator } from "../request/RequestValidator";
import { GrantType } from "../utils/Constants";
import { Configuration } from "../config/Configuration";
import {ServerAuthorizationTokenResponse} from "../server/ServerAuthorizationTokenResponse";
import {NetworkResponse} from "../network/NetworkManager";
import {ScopeSet} from "../request/ScopeSet";
import { ServerAuthorizationTokenResponse } from "../server/ServerAuthorizationTokenResponse";
import { NetworkResponse } from "../network/NetworkManager";
import { ScopeSet } from "../request/ScopeSet";

/**
* Oauth2.0 Authorization Code client
Expand Down
3 changes: 3 additions & 0 deletions lib/msal-common/src/client/BaseClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ export abstract class BaseClient {
this.networkClient = this.config.networkInterface;

// Default authority instance.
AuthorityFactory.setKnownAuthorities(
this.config.authOptions.knownAuthorities
);
this.defaultAuthorityInstance = AuthorityFactory.createInstance(
this.config.authOptions.authority || Constants.DEFAULT_AUTHORITY,
this.networkClient
Expand Down
8 changes: 6 additions & 2 deletions lib/msal-common/src/config/Configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export type Configuration = {
export type AuthOptions = {
clientId: string;
authority?: string;
knownAuthorities?: Array<string>
};

/**
Expand Down Expand Up @@ -74,7 +75,8 @@ export type LoggerOptions = {

const DEFAULT_AUTH_OPTIONS: AuthOptions = {
clientId: "",
authority: null
authority: null,
knownAuthorities: []
};

// Default module system options
Expand All @@ -85,7 +87,9 @@ const DEFAULT_SYSTEM_OPTIONS: SystemOptions = {

// Default logger implementation
const DEFAULT_LOGGER_IMPLEMENTATION: LoggerOptions = {
loggerCallback: () => {},
loggerCallback: () => {
// allows users to not pass loggerCallback implementation
},
piiLoggingEnabled: false,
logLevel: LogLevel.Info
};
Expand Down
2 changes: 2 additions & 0 deletions lib/msal-common/src/config/SPAConfiguration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { Configuration, buildConfiguration } from "./Configuration";
export type SPAAuthOptions = {
clientId: string;
authority?: string;
knownAuthorities?: Array<string>;
redirectUri?: string | (() => string);
postLogoutRedirectUri?: string | (() => string);
};
Expand All @@ -32,6 +33,7 @@ export type SPAConfiguration = Configuration & {
const DEFAULT_AUTH_OPTIONS: SPAAuthOptions = {
clientId: "",
authority: null,
knownAuthorities: [],
redirectUri: "",
postLogoutRedirectUri: ""
};
Expand Down
24 changes: 24 additions & 0 deletions lib/msal-common/src/error/ClientConfigurationError.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,14 @@ export const ClientConfigurationErrorMessage = {
invalidCodeChallengeParams: {
code: "one_of_code_challenge_code_challenge_method_params_missing",
desc: "Both params: code_challenge and code_challenge_method are to be passed if to be sent in the request"
},
b2cKnownAuthoritiesNotSet: {
code: "b2c_known_authorities_not_set",
desc: "Must set known authorities when validateAuthority is set to True and using B2C"
},
untrustedAuthority: {
code: "untrusted_authority",
desc: "The provided authority is not a trusted authority. If using B2C, please include this authority in the knownAuthorities config parameter."
}
};

Expand Down Expand Up @@ -189,4 +197,20 @@ export class ClientConfigurationError extends ClientAuthError {
ClientConfigurationErrorMessage.invalidCodeChallengeParams.desc
);
}

/**
* Throws an error when the user passes B2C authority and does not set knownAuthorities
*/
static createKnownAuthoritiesNotSetError(): ClientConfigurationError {
return new ClientConfigurationError(ClientConfigurationErrorMessage.b2cKnownAuthoritiesNotSet.code,
ClientConfigurationErrorMessage.b2cKnownAuthoritiesNotSet.desc);
}

/**
* Throws error when provided authority is not a member of the trusted host list
*/
static createUntrustedAuthorityError(): ClientConfigurationError {
return new ClientConfigurationError(ClientConfigurationErrorMessage.untrustedAuthority.code,
ClientConfigurationErrorMessage.untrustedAuthority.desc);
}
}
37 changes: 37 additions & 0 deletions lib/msal-common/src/uCache/entities/AccessTokenEntity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/

import { Credential } from "./Credential";
import { Separators } from "../../utils/Constants";

/**
* ACCESS_TOKEN Credential Type
*/
export class AccessTokenEntity extends Credential {
realm: string;
target: string;
cachedAt: string;
expiresOn: string;
extendedExpiresOn?: string;
refreshOn?: string;
keyId?: string; // for POP and SSH tokenTypes
tokenType?: string;

/**
* Generate Account Cache Key as per the schema: <home_account_id>-<environment>-<realm*>
*/
public generateAccessTokenEntityKey(): string {
const accessTokenKeyArray: Array<string> = [
this.homeAccountId,
this.environment,
this.credentialType,
this.clientId,
this.realm,
this.target
];

return accessTokenKeyArray.join(Separators.CACHE_KEY_SEPARATOR).toLowerCase();
}
}
95 changes: 95 additions & 0 deletions lib/msal-common/src/uCache/entities/AccountEntity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/

import { Separators, CacheAccountType } from "../../utils/Constants";
import { Authority } from "../../authority/Authority";
import { IdToken } from "../../account/IdToken";
import { ICrypto } from "../../crypto/ICrypto";
import { buildClientInfo } from "../../account/ClientInfo";
import { StringUtils } from "../../utils/StringUtils";

/**
* Type that defines required and optional parameters for an Account field (based on universal cache schema implemented by all MSALs)
*/
export class AccountEntity {
homeAccountId: string;
environment: string;
realm: string;
localAccountId: string;
username: string;
authorityType: string;
name?: string;
clientInfo?: string;
lastModificationTime?: string;
lastModificationApp?: string;

/**
* Generate Account Cache Key as per the schema: <home_account_id>-<environment>-<realm*>
*/
public generateAccountEntityKey(): string {
const accountCacheKeyArray: Array<string> = [
this.homeAccountId,
this.environment,
this.realm
];

return accountCacheKeyArray.join(Separators.CACHE_KEY_SEPARATOR).toLowerCase();
}

/**
* Build Account cache from IdToken, clientInfo and authority/policy
* @param clientInfo
* @param authority
* @param idToken
* @param policy
*/
static createAccount(clientInfo: string, authority: Authority, idToken: IdToken, policy: string, crypto: ICrypto): AccountEntity {
let account: AccountEntity;

account.authorityType = CacheAccountType.MSSTS_ACCOUNT_TYPE;
account.clientInfo = clientInfo;
// TBD: Clarify "policy" addition
const clientInfoObj = buildClientInfo(clientInfo, crypto);
const homeAccountId = `${clientInfoObj.uid}${Separators.CLIENT_INFO_SEPARATOR}${clientInfoObj.utid}`;
account.homeAccountId =
policy != null
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

!==

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And does this need to check specifically for null? Or can it be this:

account.homeAccountId = policy ? `${homeAccountId}${Separators.CACHE_KEY_SEPARATOR}${policy} : homeAccountId

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure about this as we do not track "policy" for B2C, this code is mostly for compliance with java. I will get back to this once I clarify the requirement.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will handle this over a different PR once the requirement is clear.

? homeAccountId + Separators.CACHE_KEY_SEPARATOR + policy
: homeAccountId;
account.environment =
authority.canonicalAuthorityUrlComponents.HostNameAndPort;
account.realm = authority.tenant;

if (idToken) {
// How do you account for MSA CID here?
const localAccountId = !StringUtils.isEmpty(idToken.claims.oid)
? idToken.claims.oid
: idToken.claims.sid;
account.localAccountId = localAccountId;
account.username = idToken.claims.preferred_username;
account.name = idToken.claims.name;
}

return account;
}

/**
* Build ADFS account type
* @param authority
* @param idToken
*/
static createADFSAccount(authority: Authority, idToken: IdToken): AccountEntity {
let account: AccountEntity;

account.authorityType = CacheAccountType.ADFS_ACCOUNT_TYPE;
account.homeAccountId = idToken.claims.sub;
account.environment =
authority.canonicalAuthorityUrlComponents.HostNameAndPort;
account.username = idToken.claims.upn;
// add uniqueName to claims
// account.name = idToken.claims.uniqueName;

return account;
}
}
Loading