-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Conversation
…Url as well as the connection
* fix: add getMostRecentServerUrl func * fix: add ts and tsx to editorconfig * fix: rename functions * fix: return type
let connection: DatabaseInstance; | ||
|
||
if (serverDatabase) { | ||
// This serverUrl has previously been registered on the app | ||
connection = serverDatabase.dbInstance; |
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.
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?
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 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[]; |
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: 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; |
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 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?
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.
A name like domain.com:1234/mattermost
is invalid. It will not be constructed/saved by the file system.
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'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[]; |
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.
Will the change to use lastActiveAt
be made 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.
Yes
@@ -428,4 +517,4 @@ if (!__DEV__) { | |||
logger.silence(); | |||
} | |||
|
|||
export default new DatabaseManager(); | |||
export default DatabaseManager; |
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.
Why is this change necessary?
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.
So as to use the DatabaseManager as a normal class rather than a Singleton.
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'll export this as a singleton.
app/database/operator/index.ts
Outdated
const DataOperator = new Operator(); | ||
constructor(database: Database) { | ||
super(); | ||
this.activeDatabase = database; |
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.
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
?
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.
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(); |
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: 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>
* 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 = { |
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.
for when we go through the naming task this should be something like
export type ServerDatabase = Database & {
displayName: string;
url: string;
}
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.
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; |
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'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, |
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 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, |
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.
this should be applied only in the wdb call
} | ||
|
||
if (setAsActiveDatabase) { | ||
await this.setActiveServerDatabase(serverUrl); |
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 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; |
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.
actionsEnabled does not need to be an argument
try { | ||
data = await Client4.getDataRetentionPolicy(); | ||
} catch (error) { | ||
forceLogoutIfNecessary(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.
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>(); |
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.
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) => { |
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.
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 |
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 use @ts-expect-error
instead
@@ -2,7 +2,7 @@ | |||
// See LICENSE.txt for license information. | |||
|
|||
export default { |
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 remove this file
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.
Pair-reviewed with Elias.
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