diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7f0323dadb..a26f971a52 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -3,6 +3,8 @@ name: Publish releases on: # Triggers the workflow on push when pushing to a version tag push: + branches: + - jigar/auth-enable tags: - '*lantern-*' workflow_dispatch: @@ -285,20 +287,20 @@ jobs: shasum -a 256 ${{ env.prefix }}.ipa | cut -d " " -f 1 > ${{ env.prefix }}.ipa.sha256 fi - - name: Commit - run: | - mv lantern-installer* ./lantern-binaries/ - cd lantern-binaries - git config user.email "admin@getlantern.org" - git config user.name "Lantern Bot" - git add . - git commit -m "Lantern binaries for version ${{ env.version }}" - git push origin main - - create-release: - uses: ./.github/workflows/prerelease-notification.yml - secrets: inherit - needs: [ determine-platform,set-version, build, push-binaries ] - with: - version: ${{ needs.set-version.outputs.prefix }}-${{ needs.set-version.outputs.version }} - platform: ${{ needs.determine-platform.outputs.platform }} \ No newline at end of file +# - name: Commit +# run: | +# mv lantern-installer* ./lantern-binaries/ +# cd lantern-binaries +# git config user.email "admin@getlantern.org" +# git config user.name "Lantern Bot" +# git add . +# git commit -m "Lantern binaries for version ${{ env.version }}" +# git push origin main +# +# create-release: +# uses: ./.github/workflows/prerelease-notification.yml +# secrets: inherit +# needs: [ determine-platform,set-version, build, push-binaries ] +# with: +# version: ${{ needs.set-version.outputs.prefix }}-${{ needs.set-version.outputs.version }} +# platform: ${{ needs.determine-platform.outputs.platform }} \ No newline at end of file diff --git a/assets/locales/en-us.po b/assets/locales/en-us.po index b2e470734f..a87b36170b 100644 --- a/assets/locales/en-us.po +++ b/assets/locales/en-us.po @@ -87,6 +87,9 @@ msgstr "Create Password" msgid "by_creating_an_account" msgstr "By Creating an Account, you agree to our" +msgid "by_clicking_continue" +msgstr "By clicking Continue, you agree to our" + msgid "confirm_email" msgstr "Confirm Email" diff --git a/desktop/app/app.go b/desktop/app/app.go index b0d3d2739b..b6356c8d24 100644 --- a/desktop/app/app.go +++ b/desktop/app/app.go @@ -356,6 +356,7 @@ func (app *App) SendMessageToUI(service string, message interface{}) { func (app *App) SendUpdateUserDataToUI() { user, found := app.GetUserData(app.Settings().GetUserID()) if !found { + log.Debugf("User not found") return } if user.UserLevel == "" { @@ -581,10 +582,19 @@ func (app *App) fetchOrCreateUser(ctx context.Context) { ss.SetUserFirstVisit(true) app.proClient.RetryCreateUser(ctx, app, 5*time.Minute) } else { - app.proClient.UpdateUserData(ctx, app) + app.FetchOrUpdateUserData(ctx) } } +func (app *App) FetchOrUpdateUserData(ctx context.Context) { + user, err := app.proClient.UpdateUserData(ctx, app) + if err != nil { + log.Errorf("Error updating user data: %v", err) + return + } + app.SetUserData(ctx, user.UserId, user) +} + func (app *App) fetchDeviceLinkingCode(ctx context.Context) (string, error) { deviceName := func() string { deviceName, _ := osversion.GetHumanReadable() diff --git a/desktop/app/config.go b/desktop/app/config.go index 2e36a66a57..7be0899be3 100644 --- a/desktop/app/config.go +++ b/desktop/app/config.go @@ -3,12 +3,9 @@ package app import ( "context" "encoding/json" - "os" - "strconv" "sync" fcommon "github.com/getlantern/flashlight/v7/common" - "github.com/getlantern/flashlight/v7/config" "github.com/getlantern/lantern-client/desktop/ws" "github.com/getlantern/lantern-client/internalsdk/common" "github.com/getlantern/lantern-client/internalsdk/protos" @@ -72,14 +69,6 @@ func (s *configService) AddListener(f func(ConfigOptions)) { } func (app *App) sendConfigOptions() { - authEnabled := func(a *App) bool { - authEnabled := a.IsFeatureEnabled(config.FeatureAuth) - if ok, err := strconv.ParseBool(os.Getenv("ENABLE_AUTH_FEATURE")); err == nil && ok { - authEnabled = true - } - log.Debugf("DEBUG: Auth enabled: %v", authEnabled) - return authEnabled - } ctx := context.Background() plans, _ := app.proClient.Plans(ctx) paymentMethods, _ := app.proClient.DesktopPaymentMethods(ctx) @@ -93,7 +82,7 @@ func (app *App) sendConfigOptions() { ReplicaAddr: "", HttpProxyAddr: app.settings.GetAddr(), SocksProxyAddr: app.settings.GetSOCKSAddr(), - AuthEnabled: authEnabled(app), + AuthEnabled: true, ChatEnabled: false, SplitTunneling: false, HasSucceedingProxy: app.HasSucceedingProxy(), diff --git a/desktop/auth.go b/desktop/auth.go index 50680f1d35..976637f905 100644 --- a/desktop/auth.go +++ b/desktop/auth.go @@ -71,6 +71,7 @@ func signup(email *C.char, password *C.char) *C.char { setting.SetEmailAddress(C.GoString(email)) a.SetUserLoggedIn(true) a.ProClient().FetchPaymentMethodsAndCache(context.Background()) + a.SendConfig() return C.CString("true") } @@ -129,9 +130,19 @@ func logout() *C.char { clearLocalUserData() // Create new user - if _, err := a.ProClient().UserCreate(ctx); err != nil { + userData, err := a.ProClient().UserCreate(ctx) + if err != nil { return sendError(err) } + //Update new user data to UI + user := userData.User + if user.UserStatus == "" { + user.UserStatus = "free" + } + setting := a.Settings() + setting.SetUserIDAndToken(user.UserId, user.Token) + setting.SetReferralCode(user.Referral) + a.SetUserData(context.Background(), user.UserId, userData.User) return C.CString("true") } @@ -207,6 +218,9 @@ func completeRecoveryByEmail(email *C.char, code *C.char, password *C.char) *C.c //Save new salt saveUserSalt(newsalt) log.Debugf("CompleteRecoveryByEmail response %v", recovery) + a.SendConfig() + a.SendUpdateUserDataToUI() + return C.CString("true") } diff --git a/desktop/lib.go b/desktop/lib.go index 5b0c47ff2f..abf2de45ba 100644 --- a/desktop/lib.go +++ b/desktop/lib.go @@ -254,6 +254,7 @@ func testProviderRequest(email *C.char, paymentProvider *C.char, plan *C.char) * if err != nil { return sendError(err) } + go a.FetchOrUpdateUserData(ctx) return C.CString("true") } diff --git a/internalsdk/android.go b/internalsdk/android.go index 57fe9cd693..93e742cfbf 100644 --- a/internalsdk/android.go +++ b/internalsdk/android.go @@ -608,7 +608,8 @@ func run(configDir, locale string, settings Settings, wrappedSession Session) { authEnabled := runner.FeatureEnabled(config.FeatureAuth, common.ApplicationVersion) log.Debugf("Feature: Auth enabled? %v", authEnabled) - session.SetAuthEnabled(authEnabled) + // Make auth enable for all + session.SetAuthEnabled(true) // Check if ads feature is enabled or not if !session.IsProUser() { showAdsEnabled := runner.FeatureEnabled(config.FeatureInterstitialAds, common.ApplicationVersion) diff --git a/internalsdk/session_model.go b/internalsdk/session_model.go index f06880ce26..5af03c45bb 100644 --- a/internalsdk/session_model.go +++ b/internalsdk/session_model.go @@ -784,10 +784,7 @@ func (m *SessionModel) checkAvailableFeatures() { // Check for auth feature authEnabled := m.featureEnabled(config.FeatureAuth) m.SetAuthEnabled(authEnabled) - platfrom, _ := m.platform() - if platfrom == "ios" { - m.SetAuthEnabled(true) - } + m.SetAuthEnabled(true) // Check for ads feature googleAdsEnabled := m.featureEnabled(config.FeatureInterstitialAds) diff --git a/lib/core/extension/error_extension.dart b/lib/core/extension/error_extension.dart index 8db687f2bd..f65870fb7c 100644 --- a/lib/core/extension/error_extension.dart +++ b/lib/core/extension/error_extension.dart @@ -7,6 +7,7 @@ extension ErrorX on Object { if (this is PlatformException) { // Extract the message from the PlatformException String description = (this as PlatformException).message ?? ''; + print("description $description"); if (description.contains("proxy_error")) { return "proxy_error".i18n; } @@ -21,7 +22,8 @@ extension ErrorX on Object { return "recovery_not_found".i18n; } - if (description.contains("wrong-link-code")) { + if (description.contains("wrong-link-code") || + description.contains("wrong_device_linking_code")) { return "wrong_link_code".i18n; } if (description diff --git a/lib/core/service/websocket_subscriber.dart b/lib/core/service/websocket_subscriber.dart index f28ff7d428..61973c30c7 100644 --- a/lib/core/service/websocket_subscriber.dart +++ b/lib/core/service/websocket_subscriber.dart @@ -85,24 +85,39 @@ class WebsocketSubscriber { } case _WebsocketMessageType.pro: _webSocketLogger.i("Websocket message[Pro]: $message"); - final userStatus = message['userStatus']; - final userLevel = message['userLevel']; - final deviceLinkingCode = message['deviceLinkingCode']; - final isLevelPro = userLevel != null && userLevel == 'pro'; - final isStatusPro = userStatus != null && userStatus == 'active'; - sessionModel.proUserNotifier.value = (isLevelPro || isStatusPro); - if (deviceLinkingCode != null) { - sessionModel.linkingCodeNotifier.value = deviceLinkingCode; + final proMap = message as Map; + + ///Since pro channel has been used many places, we need to check if the key exists + /// Sometime is send only one key, sometime multiple keys if don't then values goes back to default + if (proMap.containsKey('userStatus') || + proMap.containsKey('userLevel')) { + final userStatus = proMap['userStatus']; + final userLevel = proMap['userLevel']; + final isLevelPro = userLevel != null && userLevel == 'pro'; + final isStatusPro = userStatus != null && userStatus == 'active'; + sessionModel.proUserNotifier.value = (isLevelPro || isStatusPro); } - final userSignedIn = message['login']; - if (userSignedIn != null) { - sessionModel.hasUserSignedInNotifier.value = userSignedIn as bool; + + if (proMap.containsKey('deviceLinkingCode')) { + final deviceLinkingCode = proMap['deviceLinkingCode']; + if (deviceLinkingCode != null) { + sessionModel.linkingCodeNotifier.value = deviceLinkingCode; + } } - final language = message['language']; - if (language != null) { - sessionModel.langNotifier.value = language; + if (proMap.containsKey('login')) { + final userSignedIn = proMap['login']; + if (userSignedIn != null) { + sessionModel.hasUserSignedInNotifier.value = + userSignedIn as bool; + } } + if (proMap.containsKey('language')) { + final language = proMap['language']; + if (language != null) { + sessionModel.langNotifier.value = language; + } + } case _WebsocketMessageType.bandwidth: _webSocketLogger.i("Websocket message[Bandwidth]: $message"); sessionModel.bandwidthNotifier.value = Bandwidth.create() diff --git a/lib/core/widgtes/tos.dart b/lib/core/widgtes/tos.dart index 3183193173..297c77f7fb 100644 --- a/lib/core/widgtes/tos.dart +++ b/lib/core/widgtes/tos.dart @@ -3,8 +3,8 @@ import 'package:lantern/core/utils/common.dart'; class TOS extends StatelessWidget { const TOS({ - Key? key, - }) : super(key: key); + super.key, + }); @override Widget build(BuildContext context) { @@ -12,17 +12,14 @@ class TOS extends StatelessWidget { TextSpan( children: [ TextSpan( - text: 'by_creating_an_account'.i18n, + text: 'by_clicking_continue'.i18n, style: tsFloatingLabel, ), - const TextSpan( - text: ' ', - ), + const TextSpan(text: ' '), TextSpan( text: 'terms_of_service'.i18n, style: tsFloatingLabel!.copiedWith( - decoration: TextDecoration.underline, - ), + decoration: TextDecoration.underline, color: onSwitchColor), recognizer: TapGestureRecognizer() ..onTap = () => openTermsOfService(context), ), diff --git a/lib/features/account/account_management.dart b/lib/features/account/account_management.dart index c73d276832..a9df4ba695 100644 --- a/lib/features/account/account_management.dart +++ b/lib/features/account/account_management.dart @@ -3,9 +3,8 @@ import 'package:lantern/core/utils/utils.dart'; @RoutePage(name: 'AccountManagement') class AccountManagement extends StatefulWidget { - const AccountManagement({Key? key, required this.isPro}) : super(key: key); + const AccountManagement({super.key, required this.isPro}); final bool isPro; - @override State createState() => _AccountManagementState(); } @@ -310,6 +309,10 @@ class _AccountManagementState extends State icon: ImagePaths.email, content: emailAddress, trailingArray: [], + onTap: () => copyText( + context, + emailAddress, + ) ); }), diff --git a/lib/features/auth/create_account_password.dart b/lib/features/auth/create_account_password.dart index 24cc8ed1fd..979e8f774b 100644 --- a/lib/features/auth/create_account_password.dart +++ b/lib/features/auth/create_account_password.dart @@ -3,6 +3,7 @@ import 'package:flutter/gestures.dart'; import 'package:lantern/common/ui/password_criteria.dart'; import 'package:lantern/core/utils/utils.dart'; +import 'package:lantern/core/widgtes/tos.dart'; import '../../core/utils/common.dart'; @RoutePage(name: 'CreateAccountPassword') @@ -62,6 +63,8 @@ class _CreateAccountPasswordState extends State { textEditingController: _passwordController, ), const SizedBox(height: 24), + const TOS(), + const SizedBox(height: 24), SizedBox( width: double.infinity, child: Button( @@ -71,29 +74,7 @@ class _CreateAccountPasswordState extends State { ), ), const SizedBox(height: 24), - Text.rich( - TextSpan( - children: [ - TextSpan( - text: 'by_creating_an_account'.i18n, - style: tsFloatingLabel, - ), - const TextSpan( - text: ' ', - ), - TextSpan( - text: 'terms_of_service'.i18n, - style: tsFloatingLabel!.copiedWith( - decoration: TextDecoration.underline, - ), - recognizer: TapGestureRecognizer() - ..onTap = openTermsOfService, - ), - ], - ), - textAlign: TextAlign.center, - ), - const SizedBox(height: 20), + ], ), ), diff --git a/lib/features/checkout/checkout.dart b/lib/features/checkout/checkout.dart index 5c10bf4e87..c478d63003 100644 --- a/lib/features/checkout/checkout.dart +++ b/lib/features/checkout/checkout.dart @@ -1,7 +1,8 @@ import 'package:lantern/core/utils/common.dart'; import 'package:lantern/core/utils/common_desktop.dart'; -import 'package:lantern/features/checkout/payment_provider.dart'; import 'package:lantern/core/utils/utils.dart'; +import 'package:lantern/core/widgtes/tos.dart'; +import 'package:lantern/features/checkout/payment_provider.dart'; import 'package:retry/retry.dart'; @RoutePage(name: 'Checkout') @@ -139,6 +140,8 @@ class _CheckoutState extends State ), ), const Spacer(), + const TOS(), + const SizedBox(height: 20), Tooltip( message: AppKeys.continueCheckout, child: SizedBox( @@ -467,11 +470,11 @@ class _CheckoutState extends State /// There is edge case where user is signup with email and password but not pro /// this happens when does restore purchase on other device so older device /// does not have pro status but have email and password - if (sessionModel.hasUserSignedInNotifier.value ?? false) { + if ((sessionModel.hasUserSignedInNotifier.value ?? false) && + widget.verificationPin == null) { showSuccessDialog(context, widget.isPro); return; } - context.pushRoute(CreateAccountPassword( email: widget.email.validateEmail, code: widget.verificationPin!, diff --git a/lib/features/checkout/plan_details.dart b/lib/features/checkout/plan_details.dart index 492dc47f20..5ddc399fdb 100644 --- a/lib/features/checkout/plan_details.dart +++ b/lib/features/checkout/plan_details.dart @@ -174,13 +174,6 @@ class _PlanCardState extends State { return appStorePrice == '' ? totalCost : appStorePrice; } -// paymentProvidersFromMethods returns a list of payment providers that correspond with payment methods available to a user - List paymentProvidersFromMethods( - Iterable paymentMethods) { - var providers = []; - paymentMethods.forEach((value) => providers.addAll(value.providers)); - return providers; - } Future onPlanTap(BuildContext context) async { switch (Platform.operatingSystem) { diff --git a/lib/features/checkout/stripe_checkout.dart b/lib/features/checkout/stripe_checkout.dart index 4fc10be9c9..6fade47690 100644 --- a/lib/features/checkout/stripe_checkout.dart +++ b/lib/features/checkout/stripe_checkout.dart @@ -188,7 +188,6 @@ class _StripeCheckoutState extends State { refCode: widget.refCode, isPro: widget.isPro, ), - const TOS(), const SizedBox(height: 16), checkoutButton(), ],