Skip to content
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

MM-35115 [Gekidou] Login flow - Email and Password #5402

Merged
merged 89 commits into from
Jun 18, 2021

Conversation

avinashlng1080
Copy link
Contributor

@avinashlng1080 avinashlng1080 commented May 24, 2021

Summary

We are porting components from the current mobile app onto Gekidou.

This PR contains updated code for the first screen, login options screen and then a temporary placeholder for the channel screen.

Ticket Link

https://mattermost.atlassian.net/browse/MM-35115

NONE

Avinash Lingaloo and others added 30 commits April 29, 2021 18:33
@avinashlng1080 avinashlng1080 added 2: Dev Review Requires review by a core commiter 3: QA Review Requires review by a QA tester labels Jun 14, 2021
Comment on lines +128 to +132
let connection: DatabaseInstance;

if (serverDatabase) {
// This serverUrl has previously been registered on the app
connection = serverDatabase.dbInstance;
Copy link
Contributor

Choose a reason for hiding this comment

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

Overall I'm confused with the various ways in which db related things are referred to. For example, the above retrieveDatabaseInstances doesn't really return database instances, but objects that have a property dbInstance which is the db instance. But then we call this property value a connection?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We are using different terms but each refer to the same thing. A databaseInstance is of type Database or undefined in case WDB was not able to create a connection to the *.db file. A connection is a valid pointer to a database file.

The retrieveDatabaseInstances method returns return {dbInstance, displayName, url}; if a matching url has been found under the Servers entity in the default database.

Imagine we have multi-server support. The user opens the side-bar to perform a server switch. Instead of returning an array of object, we were returning only the connections. I find it easier to identify connections using their url/displayName rather than retrieving it from inside the dbInstance object.

*/
getDatabaseConnection = async ({serverUrl, setAsActiveDatabase, connectionName}: GetDatabaseConnectionArgs) => {
// We potentially already have this server registered; so we'll try to retrieve it if it is present under DEFAULT_DATABASE/GLOBAL entity
const existingServers = await this.retrieveDatabaseInstances([serverUrl]) as RetrievedDatabase[];
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: existingDatabases or existingServerDatabases (to be explicity about the default database not being included).

connection = serverDatabase.dbInstance;
} else {
// Or, it might be that the user has this server on the web-app but not mobile-app; so we'll need to create a new entry for this new serverUrl
const databaseName = connectionName ?? urlParse(serverUrl).hostname;
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we be using urlParse(serverUrl).host + urlParse(serverUrl).path to ensure we get the port number and subdirectory, if any? For example, if we have serverUrl https://domain.com:1234/mattermost then we'd want the db name to be domain.com:1234/mattermost, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

A name like domain.com:1234/mattermost is invalid. It will not be constructed/saved by the file system.

Copy link
Contributor

Choose a reason for hiding this comment

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

We'll be doing some work around this to normalize the name and hash the file name

const defaultDatabase = await this.getDefaultDatabase();
if (defaultDatabase) {
// retrieve recentlyViewedServers from Global entity
const recentlyViewedServers = await defaultDatabase.collections.get(GLOBAL).query(Q.where('name', RECENTLY_VIEWED_SERVERS)).fetch() as IGlobal[];
Copy link
Contributor

Choose a reason for hiding this comment

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

Will the change to use lastActiveAt be made in a separate PR?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes

@@ -428,4 +517,4 @@ if (!__DEV__) {
logger.silence();
}

export default new DatabaseManager();
export default DatabaseManager;
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is this change necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So as to use the DatabaseManager as a normal class rather than a Singleton.

Copy link
Contributor

Choose a reason for hiding this comment

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

we'll export this as a singleton.

const DataOperator = new Operator();
constructor(database: Database) {
super();
this.activeDatabase = database;
Copy link
Contributor

Choose a reason for hiding this comment

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

Could we call this class DatabaseOperator? And also, since we'll have an instance of this class for each database, can we rename this.activeDatabase to this.database?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Could we call this class DatabaseOperator?

The purpose of this class is to treat data getting inside our database. It was initially called DataOperator and then we agreed to use the term Operator. I would prefer if we leave it as such. @enahum your thoughts on this ?

And also, since we'll have an instance of this class for each database, can we rename this.activeDatabase to this.database?

We are not using Singletons anymore. The Operator treats/manages data getting inside a server database. It is the Operator that relies on the DatabaseManager...not the other way around.

An instance of an operator needs an instance of a database connection for the activeDatabase but every Operator instances will point to the same Default database.

@@ -71,7 +71,8 @@ describe('DataOperator: Utils tests', () => {
it('=> sanitizeReactions: should triage between reactions that needs creation/deletion and emojis to be created', async () => {
const dbName = 'server_schema_connection';
const serverUrl = 'https://appv2.mattermost.com';
const database = await DatabaseManager.createDatabaseConnection({
const databaseManagerClient = new DatabaseManager();
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: I don't think we should append Client to these variables.

* MM_35115: Starting LoginOptions SSO

* MM_36205: SSO [IN PROGRESS]

* MM_36205 : SSO [ IN PROGRESS ]

* Update sso_with_redirect_url.tsx

* MM_36205 : SSO Tests [ IN PROGRESS ]

* MM_36205 : Passing serverUrl to SSO screen

* Update sso.test.tsx

* Fix ViewTypes imports and keyMirror method

* MM_36205 : Code clean up

* Fix : Clean up imports

* Update: Aligning with PR 5452

* Fix: AndroidManifest file to include redirection ofr scheme mmauthbeta

* refactor: SSO Login method via Gitlab now navigates to Channel screen

* refactor: SSO Login without redirectURL is also working

* feat: SSO - main test completed

* feat: ADDED test for sso_with_redirect_url

* fix : eslint correction

* fix: Updated Loading component name

* fix : code clean up from reviews

* fix: reviews check

* fix: Added mmauthbeta into info.plist

* Revert "fix: Added mmauthbeta into info.plist"

This reverts commit d87cc23.

* Update Info.plist

* Update AppDelegate.m

* feat: ADDED Forgot Password - Test [ IN PROGRESS ]

* feat: Forgot Password - Completed & Tested

* fix: Including MFA screen [ IN PROGRESS ]

* MFA - Properly tested

* Properly testing forgot_password screen

* Fix login.test.tsx

* Fix SSO method calls chain

* Update index.tsx

* Sort imports for sceen/navigation

* fix: Reviews

* Update signing + act in test

* Removed todo comment on MFA

* feedback review

* fix login tests

Co-authored-by: Avinash Lingaloo <>
Co-authored-by: Elias Nahum <nahumhbl@gmail.com>
enahum and others added 2 commits June 17, 2021 21:29
* fix: initial init refactor

* fix: await isServerPresent

* fix: more refactor

* fix: move out launch functions

* fix: remove comment

* fix: update credential functions

* fix: refactor launch functions

* fix: deep link parsing

* fix: lint change

* fix: update deeplink and notification handlers

* fix: indentation

* fix: add relaunchApp

* fix eslint

* refactor launchProps and autoconnect server for deeplink

* fix: use undefined

* fix: define OptionalLaunchProps

* fix: Android - handle server URL in push notification

* fix: rename func

* fix: use boolean launchError instead

* fix: use DatabaseModule

* fix: use DatabaseHelper instead

* fix: remove unnecessary null check

* fix: iOS - support for serverUrl

* fix: iOS - extract serverUrl in reply action

* fix: iOS - expose objc specific func

* fix: remove unnecessary deviceToken param

* fix: return if device is untrusted

Co-authored-by: Elias Nahum <nahumhbl@gmail.com>

* fix: bye bye modulePaths

* fix: ios build

* chore: remove unused aliases from babel.config

* chore: fix dependency format in package-lock.json

* chore: remove transparent window background color for android AppTheme

* chore: remove mattermost.js and use index.ts as app entry

* fix: login flow screens theme

* fix: Launch types

* chore: remove OptionalLaunchProps type

* fix: url utils unit tests

* chore: update en.json

Co-authored-by: Elias Nahum <nahumhbl@gmail.com>
serverUrl: string;
};

export type RetrievedDatabase = {
Copy link
Contributor

Choose a reason for hiding this comment

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

for when we go through the naming task this should be something like

export type ServerDatabase = Database & {
    displayName: string;
    url: string;
}

Copy link
Contributor

@enahum enahum left a comment

Choose a reason for hiding this comment

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

yay!! let's merge this thing and go over all the comments for the next set of PR's

connection = serverDatabase.dbInstance;
} else {
// Or, it might be that the user has this server on the web-app but not mobile-app; so we'll need to create a new entry for this new serverUrl
const databaseName = connectionName ?? urlParse(serverUrl).hostname;
Copy link
Contributor

Choose a reason for hiding this comment

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

We'll be doing some work around this to normalize the name and hash the file name

// Or, it might be that the user has this server on the web-app but not mobile-app; so we'll need to create a new entry for this new serverUrl
const databaseName = connectionName ?? urlParse(serverUrl).hostname;
connection = await this.createDatabaseConnection({
shouldAddToDefaultDatabase: true,
Copy link
Contributor

Choose a reason for hiding this comment

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

should we separate concerns here? have the function just create the database and then we have another function to add the record into the default database?

If this function only applies to server databases then maybe we just rename the function to createServerDatabase

connection = await this.createDatabaseConnection({
shouldAddToDefaultDatabase: true,
configs: {
actionsEnabled: true,
Copy link
Contributor

Choose a reason for hiding this comment

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

this should be applied only in the wdb call

}

if (setAsActiveDatabase) {
await this.setActiveServerDatabase(serverUrl);
Copy link
Contributor

Choose a reason for hiding this comment

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

we don't really need to await for this and setActiveServerDatabase all that is should do is update the default database server table to set the last_active_at field.

dbType = DatabaseType.DEFAULT,
serverUrl = undefined,
} = configs;
const {actionsEnabled = true, dbName = DEFAULT_DATABASE, dbType = DatabaseType.DEFAULT, serverUrl = undefined} = configs;
Copy link
Contributor

Choose a reason for hiding this comment

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

actionsEnabled does not need to be an argument

try {
data = await Client4.getDataRetentionPolicy();
} catch (error) {
forceLogoutIfNecessary(error);
Copy link
Contributor

Choose a reason for hiding this comment

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

for network client.. we need to handle this differently.. @migbot FYI

// so that they are eventually accessible in the Channel screen.

const intl = useIntl();
const managedConfig = useManagedConfig<ManagedConfig>();
Copy link
Contributor

Choose a reason for hiding this comment

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

for the screen components, this could just be using the prop for managedConfig instead of using the hook. Both of the solutions would work just fine

displayName?: string;
};

export const createAndSetActiveDatabase = async ({serverUrl, displayName}: SetActiveDatabaseArgs) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

do we need any of this? I believe this is already achievable with the DBManager Instance

const oldRender = Text.render;
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
Copy link
Contributor

Choose a reason for hiding this comment

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

let's use @ts-expect-error instead

@@ -2,7 +2,7 @@
// See LICENSE.txt for license information.

export default {
Copy link
Contributor

Choose a reason for hiding this comment

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

we can remove this file

@enahum enahum removed 2: Dev Review Requires review by a core commiter Work In Progress Not yet ready for review labels Jun 18, 2021
@migbot migbot self-requested a review June 18, 2021 04:57
Copy link
Contributor

@migbot migbot left a comment

Choose a reason for hiding this comment

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

Pair-reviewed with Elias.

@enahum enahum merged commit 3ee6e67 into gekidou Jun 18, 2021
@enahum enahum deleted the MM_35115_gekidou_login_flow branch June 18, 2021 04:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3: QA Review Requires review by a QA tester release-note-none
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants