Skip to content

Conversation

@TamaraFinogina
Copy link
Contributor

@TamaraFinogina TamaraFinogina commented Oct 14, 2025

Description

This PR is for the PoC for opaque login (just to agree on the API).

During login, we call is2FAorOpaqueNeeded, which tells us if login should be with Opaque or not. The draft implementation for opaque auth is in src/app/auth/services/auth.opaque.ts.

Related Issues

Proof of Concept for PB-4610

Related Pull Requests

Checklist

  • Changes have been tested locally.
  • Unit tests have been written or updated as necessary.
  • The code adheres to the repository's coding standards.
  • Relevant documentation has been added or updated.
  • No new warnings or errors have been introduced.
  • SonarCloud issues have been reviewed and addressed.
  • QA Passed

Testing Process

No tests are added yet.

Additional Notes

To build, you need to link the SDK from the opaque PoC PR.

@TamaraFinogina TamaraFinogina self-assigned this Oct 14, 2025
@vercel
Copy link

vercel bot commented Oct 14, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
drive-web Ready Ready Preview Comment Oct 17, 2025 7:29am

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Oct 15, 2025

Deploying drive-web with  Cloudflare Pages  Cloudflare Pages

Latest commit: 435b604
Status: ✅  Deploy successful!
Preview URL: https://c7c06882.drive-web.pages.dev
Branch Preview URL: https://opaque-poc.drive-web.pages.dev

View logs

@TamaraFinogina TamaraFinogina marked this pull request as ready for review October 24, 2025 10:24
@TamaraFinogina TamaraFinogina requested a review from sg-gs October 24, 2025 10:24
import { AuthMethodTypes } from 'app/payment/types';
import vpnAuthService from 'app/auth/services/vpnAuth.service';
import envService from 'app/core/services/env.service';
import { logInOpaque, is2FAorOpaqueNeeded } from '../../services/auth.opaque';
Copy link
Member

Choose a reason for hiding this comment

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

This should be in the auth service, let's not create 'helper' files

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done


try {
const isTfaEnabled = await is2FANeeded(email);
const { tfaEnabled: isTfaEnabled, opaqueLogin } = await is2FAorOpaqueNeeded(email);
Copy link
Member

Choose a reason for hiding this comment

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

Could we hide these things under the same functions? Otherwise we mix component-related logic with authentication low-level details, which is far from ideal in terms of maintenance and testability. Let's hide these things under the auth layer.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

};

const { token, user, mnemonic } = await authenticateUser(authParams);
const { token, user, mnemonic } = await (opaqueLogin ? logInOpaque(authParams) : authenticateUser(authParams));
Copy link
Member

Choose a reason for hiding this comment

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

Same here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

import { generateUserSecrets, encryptUserKeysAndMnemonic, decryptUserKeysAndMnemonic } from './auth.crypto';

describe('Test auth crypto functions', () => {
it('test enc/dec of user sercrets', async () => {
Copy link
Member

Choose a reason for hiding this comment

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

Use When-then legends and define clearly what each case is doing / testing

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done


const { encMnemonic, encKeys } = await encryptUserKeysAndMnemonic(keys, mnemonic, exportKey);

const { keys: dec_keys, mnemonic: dec_mnemonic } = await decryptUserKeysAndMnemonic(
Copy link
Member

Choose a reason for hiding this comment

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

Avoid using snake_case, the convention is camelCase

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

@TamaraFinogina TamaraFinogina requested a review from sg-gs October 29, 2025 08:43
Copy link
Collaborator

@CandelR CandelR left a comment

Choose a reason for hiding this comment

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

When the PRs related to the SDK are merged, I will check this one again :)
internxt/sdk#335

Copy link
Contributor

@larryrider larryrider left a comment

Choose a reason for hiding this comment

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

check the build action, it seems to be failing right now

@TamaraFinogina
Copy link
Contributor Author

@larryrider, hash library is not working with node less than 20, so tests on 18 fail due to failed build
Screenshot 2025-11-24 at 18 05 09

@larryrider
Copy link
Contributor

@larryrider, hash library is not working with node less than 20, so tests on 18 fail due to failed build Screenshot 2025-11-24 at 18 05 09

@TamaraFinogina We should then update those actions to use node 20 or 22

password: string,
twoFactorCode: string,
): Promise<{ token: string; user: UserSettings; mnemonic: string; newToken: string }> => {
const { sessionID, user: encUser, sessionKey, exportKey } = await loginOpaque(email, password, twoFactorCode);
Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure if calling that encUser is the best option since since the user isn't actually encrypted. What about loggedUser or smth like that?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

localStorageService.set('xNewToken', sessionID);
await setSessionKey(password, sessionKey);

Sentry.setUser({
Copy link
Contributor

Choose a reason for hiding this comment

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

I think Sentry can be safely removed. We do not use it anymore.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

Comment on lines 140 to 146
localStorageService.set('sessionKey', sessionKeyEnc);
localStorageService.set('sessionKeySalt', salt);
};

export const getSessionKey = async (password: string): Promise<Uint8Array> => {
const sessionKeyEnc = localStorageService.get('sessionKey') || '';
const salt = localStorageService.get('sessionKeySalt') || '';
Copy link
Contributor

Choose a reason for hiding this comment

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

Perhaps you could create a function in localStorageService called setSessionKey and getSessionKey and manage there the keys/values instead? WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

password,
});
if (!loginResult) {
throw new Error('Login failed');
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggestion: Consider creating a custom error (e.g., LoginFailedError) so it’s clear that the error originates from our code. This makes debugging easier. You can use something like this as a reference.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

@TamaraFinogina TamaraFinogina requested a review from a team as a code owner December 5, 2025 11:36
@sonarqubecloud
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants