-
Notifications
You must be signed in to change notification settings - Fork 371
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
Starts defining multi-tenancy APIs. This includes: #526
Conversation
- Defining type definitions. - Adding tenantId to UserRecord and UserImportBuilder. - Adding new errors associated with tenant operations. - Defines the Tenant object. As the changes are quite large. This will be split into multiple PRs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't gone through the tests yet, but the implementation looks pretty good. Just a few suggestions to make the code more TypeScript idiomatic. In general:
- Reduce the use of
any
in method arguments, and use specific types/interfaces whenever possible. If you must useany
, see{[key: string]: any}
is a better alternative. - Double check that the exported things really need to be exported.
src/auth/auth-config.ts
Outdated
'INTERNAL ASSERT FAILED: Invalid email sign-in configuration response'); | ||
} | ||
utils.addReadonlyGetter(this, 'enabled', response.allowPasswordSignup); | ||
utils.addReadonlyGetter(this, 'passwordRequired', !response.enableEmailLinkSignin); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Assign to the attributes here.
this.enabled = response.allowPasswordSignup;
this.passwordRequired = !response.enableEmailLinkSignin;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
src/auth/auth-config.ts
Outdated
* EmailSignInConfig object. | ||
* @constructor | ||
*/ | ||
constructor(response: any) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use type {[key: string]: any}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
src/auth/auth-config.ts
Outdated
* | ||
* @param {any} options The options object to validate. | ||
*/ | ||
public static validate(options: any) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use type {[key: string]: any}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
src/auth/auth-config.ts
Outdated
* @param {any} options The options object to convert to a server request. | ||
* @return {EmailSignInConfigServerRequest} The resulting server request. | ||
*/ | ||
public static buildServerRequest(options: any): EmailSignInConfigServerRequest { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use type {[key: string]: any}
PS: Seeing how this get called, you can probably even annotate this with type EmailSignInProviderConfig
. We still need to do the validations due to type erasure at runtime.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed to EmailSignInProviderConfig
src/auth/auth-config.ts
Outdated
* | ||
* @param {any} options The options object to validate. | ||
*/ | ||
public static validate(options: any) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if this is getting called from elsewhere. If not lets make it private.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
src/auth/tenant.ts
Outdated
* @param {any} request The tenant options object to validate. | ||
* @param {boolean} createRequest Whether this is a create request. | ||
*/ | ||
public static validate(request: any, createRequest: boolean) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can be private?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
src/auth/tenant.ts
Outdated
'INTERNAL ASSERT FAILED: Invalid tenant response', | ||
); | ||
} | ||
utils.addReadonlyGetter(this, 'tenantId', tenantId); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Directly assign to the readonly attributed you have defined above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
src/auth/tenant.ts
Outdated
|
||
/** @return {object} The plain object representation of the tenant. */ | ||
public toJSON(): object { | ||
const json: any = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inline with return:
return {
...
};
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
@@ -187,6 +188,7 @@ export class UserRecord { | |||
validAfterTime = parseDate(response.validSince * 1000); | |||
} | |||
utils.addReadonlyGetter(this, 'tokensValidAfterTime', validAfterTime || undefined); | |||
utils.addReadonlyGetter(this, 'tenantId', response.tenantId); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can directly assign to this.tenantId
here, but since we've already used the utils method in this constructor, it's ok to leave it as is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's make the change in a separate PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks pretty good. Just a few nits.
try { | ||
this.emailSignInConfig = new EmailSignInConfig(response); | ||
} catch (e) { | ||
this.emailSignInConfig = undefined; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might want to put a comment here to indicate why it's ok to ignore the error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
src/auth/tenant.ts
Outdated
`"${label}.displayName" must be a valid non-empty string.`, | ||
); | ||
} | ||
// Validate type type if provided. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
extraneous type
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
src/auth/tenant.ts
Outdated
public readonly tenantId: string; | ||
public readonly type?: TenantType; | ||
public readonly displayName?: string; | ||
public readonly emailSignInConfig?: EmailSignInConfig | null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this ever assigned null?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It used to but not anymore. Removed it.
test/unit/auth/auth-config.spec.ts
Outdated
}); | ||
|
||
it('should set readonly property "enabled" to false on allowPasswordSignup disabled', () => { | ||
const validConfig2 = new EmailSignInConfig({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Give a more descriptive name to the variable that explains the context. Perhaps passwordSignupDisabledConfig
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
test/unit/auth/auth-config.spec.ts
Outdated
}); | ||
|
||
it('should set readonly property "passwordRequired" to true on email link sign in disabled', () => { | ||
const validConfig2 = new EmailSignInConfig({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const emailLinkSignInDisabledConfig
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Switched to passwordSignupEnabledConfig
.
test/unit/auth/tenant.spec.ts
Outdated
}).to.throw('"EmailSignInConfig.enabled" must be a boolean.'); | ||
}); | ||
|
||
it('should throw when type is specified', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should throw when type is specified in an update request
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
test/unit/auth/tenant.spec.ts
Outdated
it('should throw when type is specified', () => { | ||
const tenantOptionsClientRequest: TenantOptions = deepCopy(tenantOptions); | ||
tenantOptionsClientRequest.type = 'lightweight'; | ||
expect(() => Tenant.buildServerRequest(tenantOptionsClientRequest, false)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Calls like this can be made more readable if you define a constant somewhere for false
:
const createRequest = true;
Tenant.buildServerRequest(tenantOptionsClientRequest, !createRequest)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
test/unit/auth/tenant.spec.ts
Outdated
}); | ||
}); | ||
|
||
it('should throw on update with specified type', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like a duplicate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed
test/unit/auth/tenant.spec.ts
Outdated
.to.equal('TENANT_ID'); | ||
}); | ||
|
||
it('should return the expected tenant ID from resource name with multiple tenants substring', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only difference from the previous test case is that this seems to use a different project ID. Was that intentional?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I updated the description. I am testing when the projectId contains the "tenants" substring.
test/unit/auth/user-record.spec.ts
Outdated
* @return {object} A sample valid user response as returned from getAccountInfo | ||
* endpoint. | ||
*/ | ||
function getValidUserResponse(): object { | ||
return { | ||
function getValidUserResponse(tenantId?: string): any { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use {[key: string}: any}
instead of any
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 👍
I see one of the GCB triggers are stuck. Let me know if that's somehow preventing you from being able to merge this. |
Yeah I am unable to squash and merge due to that. |
As the changes are quite large. This will be split into multiple PRs.