• Strona głównaStrona główna
    • Aplikacja mobilna 2FAS Pass
    • Rozszerzenie przeglądarki 2FAS Pass
    • Cennik
    • Aplikacja mobilna 2FAS Auth
    • Rozszerzenie przeglądarki 2FAS Auth
    • Wesprzyj
  • O nasO nas
  • Centrum pomocyCentrum pomocy
  • Pobierz aplikacjePobierz aplikacje
  • Strona głównaStrona główna
    • Aplikacja mobilna 2FAS Pass
    • Rozszerzenie przeglądarki 2FAS Pass
    • Cennik
    • Aplikacja mobilna 2FAS Auth
    • Rozszerzenie przeglądarki 2FAS Auth
    • Wesprzyj
  • O nasO nas
  • Centrum pomocyCentrum pomocy
  • Pobierz aplikacjePobierz aplikacje

Wierzymy, że Internet może być bezpieczniejszym
i lepiej chronionym miejscem. Dla każdego.

Aplikacje 2FAS są kluczowe dla naszej misji zrewolucjonizowania standardów ochrony kont w Internecie.


                      import UIKit
                      import Common
                      
                      final class TokensViewController: UIViewController {
                          var presenter: TokensPresenter!
                          var addButton: UIBarButtonItem? {
                              navigationItem.rightBarButtonItem
                          }
                          private(set) var gridView: GridView!
                          private(set) var gridLayout: UICollectionViewFlowLayout!
                          private(set) var dataSource: UICollectionViewDiffableDataSource<GridSection, GridCell>!
                          
                          let headerHeight: CGFloat = 50
                          let emptySearchScreenView = GridViewEmptySearchScreen()
                          let emptyListScreenView = GridViewEmptyListScreen()
                          
                          private var configuredWidth: CGFloat = 0
                          var searchBarAdded = false
                          
                          let searchController = CommonSearchController()
                          
                          override func loadView() {
                              gridLayout = UICollectionViewFlowLayout()
                              gridView = GridView(frame: .zero, collectionViewLayout: gridLayout)
                              self.view = gridView
                              gridView.configure()
                          }
                          
                          override func viewDidLoad() {
                              super.viewDidLoad()
                              
                              setupView()
                              setupEmptyScreensLayout()
                              setupEmptyScreensEvents()
                              setupDelegates()
                              setupDataSource()
                              setupDragAndDrop()
                              setupNotificationsListeners()
                          }
                          
                          // MARK: - App events
                          
                          override func viewWillLayoutSubviews() {
                              super.viewWillLayoutSubviews()
                              configureLayout()
                          }
                          
                          override func viewWillAppear(_ animated: Bool) {
                              super.viewWillAppear(animated)
                              presenter.viewWillAppear()
                              startSafeAreaKeyboardAdjustment()
                          }
                          
                          override func viewWillDisappear(_ animated: Bool) {
                              super.viewWillDisappear(animated)
                              stopSafeAreaKeyboardAdjustment()
                          }
                          
                          deinit {
                              NotificationCenter.default.removeObserver(self)
                          }
                      }
                      
                      private extension TokensViewController {
                          func setupView() {
                              extendedLayoutIncludesOpaqueBars = true
                              view.backgroundColor = Theme.Colors.Fill.background
                              title = T.Commons.tokens
                              accessibilityTraits = .header
                          }
                          
                          func setupDelegates() {
                              searchController.searchBarDelegate = self
                              gridView.delegate = self
                          }
                          
                          func setupDataSource() {
                              dataSource = UICollectionViewDiffableDataSource(
                                  collectionView: gridView,
                                  cellProvider: { collectionView, indexPath, item in
                                      if item.cellType == .serviceTOTP {
                                          if collectionView.isEditing {
                                              let cell = collectionView.dequeueReusableCell(
                                                  withReuseIdentifier: GridViewEditItemCell.reuseIdentifier,
                                                  for: indexPath
                                              ) as? GridViewEditItemCell
                                              cell?.update(
                                                  name: item.name,
                                                  additionalInfo: item.additionalInfo,
                                                  serviceTypeName: item.serviceTypeName,
                                                  iconType: item.iconType,
                                                  category: item.category,
                                                  canBeDragged: item.canBeDragged
                                              )
                                              return cell
                                          } else {
                                              let cell = collectionView.dequeueReusableCell(
                                                  withReuseIdentifier: GridViewItemCell.reuseIdentifier,
                                                  for: indexPath
                                              ) as? GridViewItemCell
                                              cell?.update(
                                                  name: item.name,
                                                  secret: item.secret,
                                                  serviceTypeName: item.serviceTypeName,
                                                  additionalInfo: item.additionalInfo,
                                                  iconType: item.iconType,
                                                  category: item.category,
                                                  useNextToken: item.useNextToken
                                              )
                                              return cell
                                          }
                                      } else if item.cellType == .serviceHOTP {
                                          if collectionView.isEditing {
                                              let cell = collectionView.dequeueReusableCell(
                                                  withReuseIdentifier: GridViewEditItemCell.reuseIdentifier,
                                                  for: indexPath
                                              ) as? GridViewEditItemCell
                                              cell?.update(
                                                  name: item.name,
                                                  additionalInfo: item.additionalInfo,
                                                  serviceTypeName: item.serviceTypeName,
                                                  iconType: item.iconType,
                                                  category: item.category,
                                                  canBeDragged: item.canBeDragged
                                              )
                                              return cell
                                          } else {
                                              let cell = collectionView.dequeueReusableCell(
                                                  withReuseIdentifier: GridViewCounterItemCell.reuseIdentifier,
                                                  for: indexPath
                                              ) as? GridViewCounterItemCell
                                              cell?.update(
                                                  name: item.name,
                                                  secret: item.secret,
                                                  serviceTypeName: item.serviceTypeName,
                                                  additionalInfo: item.additionalInfo,
                                                  iconType: item.iconType,
                                                  category: item.category
                                              )
                                              return cell
                                          }
                                      }
                                      let cell = collectionView.dequeueReusableCell(
                                          withReuseIdentifier: GridEmptyCollectionViewCell.reuseIdentifier,
                                          for: indexPath
                                      ) as? GridEmptyCollectionViewCell
                                      return cell
                                  })
                              dataSource.supplementaryViewProvider = { [weak self] collectionView, kind, indexPath
                                  -> UICollectionReusableView? in
                                  let header = collectionView.dequeueReusableSupplementaryView(
                                      ofKind: kind,
                                      withReuseIdentifier: GridSectionHeader.reuseIdentifier,
                                      for: indexPath
                                  ) as? GridSectionHeader
                                  header?.setIsEditing(collectionView.isEditing)
                                  header?.dataSource = self
                                  if let data = self?.dataSource.snapshot().sectionIdentifiers[indexPath.section] {
                                      header?.setConfiguration(data)
                                  }
                                  return header
                              }
                          }
                          
                          func setupDragAndDrop() {
                              gridView.dragDelegate = self
                              gridView.dropDelegate = self
                              gridView.dragInteractionEnabled = presenter.enableDragAndDropOnStart
                          }
                          
                          func setupEmptyScreensLayout() {
                              view.addSubview(emptySearchScreenView, with: [
                                  emptySearchScreenView.leadingAnchor.constraint(equalTo: gridView.frameLayoutGuide.leadingAnchor),
                                  emptySearchScreenView.trailingAnchor.constraint(equalTo: gridView.frameLayoutGuide.trailingAnchor),
                                  emptySearchScreenView.topAnchor.constraint(equalTo: gridView.frameLayoutGuide.topAnchor),
                                  emptySearchScreenView.bottomAnchor.constraint(equalTo: gridView.frameLayoutGuide.bottomAnchor)
                              ])
                              emptySearchScreenView.isHidden = true
                              emptySearchScreenView.alpha = 0
                              
                              view.addSubview(emptyListScreenView, with: [
                                  emptyListScreenView.leadingAnchor.constraint(equalTo: gridView.frameLayoutGuide.leadingAnchor),
                                  emptyListScreenView.trailingAnchor.constraint(equalTo: gridView.frameLayoutGuide.trailingAnchor),
                                  emptyListScreenView.topAnchor.constraint(equalTo: gridView.safeTopAnchor),
                                  emptyListScreenView.bottomAnchor.constraint(equalTo: gridView.safeBottomAnchor)
                              ])
                              emptyListScreenView.isHidden = true
                              emptyListScreenView.alpha = 0
                          }
                          
                          func configureLayout() {
                              guard let screenWidth = UIApplication.keyWindow?.bounds.size.width,
                                    configuredWidth != screenWidth else { return }
                              
                              configuredWidth = screenWidth
                              
                              let cellHeight = Theme.Metrics.servicesCellHeight
                              
                              let minimumCellWidth: CGFloat = Theme.Metrics.pageWidth
                              let itemsInRow = Int(screenWidth / minimumCellWidth)
                              let margin: CGFloat = 0
                              
                              let marginsWidth = margin * CGFloat(itemsInRow - 1)
                              let screenWidthWithoutMargins = screenWidth - marginsWidth
                              let elementWidth = floor(screenWidthWithoutMargins / CGFloat(itemsInRow))
                              
                              gridLayout.itemSize = CGSize(width: elementWidth, height: cellHeight)
                              gridLayout.minimumInteritemSpacing = margin
                              
                              gridLayout.headerReferenceSize = CGSize(width: 100, height: headerHeight)
                              
                              gridLayout.minimumLineSpacing = 0
                          }
                          
                          func setupEmptyScreensEvents() {
                              emptyListScreenView.pairNewService = { [weak self] in self?.presenter.handleShowCamera() }
                              emptyListScreenView.import2FAS = { [weak self] in
                                  AnalyticsLog(.onboardingBackupFile)
                                  self?.presenter.handleImport2FAS()
                              }
                              emptyListScreenView.importGA = { [weak self] in
                                  AnalyticsLog(.onboardingGA)
                                  self?.presenter.handleImportGA()
                              }
                              emptyListScreenView.help = { [weak self] in self?.presenter.handleShowHelp() }
                          }
                          
                          func setupNotificationsListeners() {
                              let center = NotificationCenter.default
                              center.addObserver(
                                  self, selector: #selector(notificationServicesWereUpdated), name: .servicesWereUpdated, object: nil
                              )
                              center.addObserver(
                                  self, selector: #selector(notificationSectionsWereUpdated), name: .sectionsWereUpdated, object: nil
                              )
                              center.addObserver(
                                  self,
                                  selector: #selector(notificationAppDidBecomeActive),
                                  name: UIApplication.didBecomeActiveNotification,
                                  object: nil
                              )
                              center.addObserver(
                                  self,
                                  selector: #selector(notificationAppDidBecomeInactive),
                                  name: UIApplication.willResignActiveNotification,
                                  object: nil
                              )
                              center.addObserver(
                                  self,
                                  selector: #selector(notificationAppDidBecomeInactive),
                                  name: UIApplication.didEnterBackgroundNotification,
                                  object: nil
                              )
                          }
                      }
                      import UIKit
                      import Common
                      
                      final class TokensViewController: UIViewController {
                          var presenter: TokensPresenter!
                          var addButton: UIBarButtonItem? {
                              navigationItem.rightBarButtonItem
                          }
                          private(set) var gridView: GridView!
                          private(set) var gridLayout: UICollectionViewFlowLayout!
                          private(set) var dataSource: UICollectionViewDiffableDataSource<GridSection, GridCell>!
                          
                          let headerHeight: CGFloat = 50
                          let emptySearchScreenView = GridViewEmptySearchScreen()
                          let emptyListScreenView = GridViewEmptyListScreen()
                          
                          private var configuredWidth: CGFloat = 0
                          var searchBarAdded = false
                          
                          let searchController = CommonSearchController()
                          
                          override func loadView() {
                              gridLayout = UICollectionViewFlowLayout()
                              gridView = GridView(frame: .zero, collectionViewLayout: gridLayout)
                              self.view = gridView
                              gridView.configure()
                          }
                          
                          override func viewDidLoad() {
                              super.viewDidLoad()
                              
                              setupView()
                              setupEmptyScreensLayout()
                              setupEmptyScreensEvents()
                              setupDelegates()
                              setupDataSource()
                              setupDragAndDrop()
                              setupNotificationsListeners()
                          }
                          
                          // MARK: - App events
                          
                          override func viewWillLayoutSubviews() {
                              super.viewWillLayoutSubviews()
                              configureLayout()
                          }
                          
                          override func viewWillAppear(_ animated: Bool) {
                              super.viewWillAppear(animated)
                              presenter.viewWillAppear()
                              startSafeAreaKeyboardAdjustment()
                          }
                          
                          override func viewWillDisappear(_ animated: Bool) {
                              super.viewWillDisappear(animated)
                              stopSafeAreaKeyboardAdjustment()
                          }
                          
                          deinit {
                              NotificationCenter.default.removeObserver(self)
                          }
                      }
                      
                      private extension TokensViewController {
                          func setupView() {
                              extendedLayoutIncludesOpaqueBars = true
                              view.backgroundColor = Theme.Colors.Fill.background
                              title = T.Commons.tokens
                              accessibilityTraits = .header
                          }
                          
                          func setupDelegates() {
                              searchController.searchBarDelegate = self
                              gridView.delegate = self
                          }
                          
                          func setupDataSource() {
                              dataSource = UICollectionViewDiffableDataSource(
                                  collectionView: gridView,
                                  cellProvider: { collectionView, indexPath, item in
                                      if item.cellType == .serviceTOTP {
                                          if collectionView.isEditing {
                                              let cell = collectionView.dequeueReusableCell(
                                                  withReuseIdentifier: GridViewEditItemCell.reuseIdentifier,
                                                  for: indexPath
                                              ) as? GridViewEditItemCell
                                              cell?.update(
                                                  name: item.name,
                                                  additionalInfo: item.additionalInfo,
                                                  serviceTypeName: item.serviceTypeName,
                                                  iconType: item.iconType,
                                                  category: item.category,
                                                  canBeDragged: item.canBeDragged
                                              )
                                              return cell
                                          } else {
                                              let cell = collectionView.dequeueReusableCell(
                                                  withReuseIdentifier: GridViewItemCell.reuseIdentifier,
                                                  for: indexPath
                                              ) as? GridViewItemCell
                                              cell?.update(
                                                  name: item.name,
                                                  secret: item.secret,
                                                  serviceTypeName: item.serviceTypeName,
                                                  additionalInfo: item.additionalInfo,
                                                  iconType: item.iconType,
                                                  category: item.category,
                                                  useNextToken: item.useNextToken
                                              )
                                              return cell
                                          }
                                      } else if item.cellType == .serviceHOTP {
                                          if collectionView.isEditing {
                                              let cell = collectionView.dequeueReusableCell(
                                                  withReuseIdentifier: GridViewEditItemCell.reuseIdentifier,
                                                  for: indexPath
                                              ) as? GridViewEditItemCell
                                              cell?.update(
                                                  name: item.name,
                                                  additionalInfo: item.additionalInfo,
                                                  serviceTypeName: item.serviceTypeName,
                                                  iconType: item.iconType,
                                                  category: item.category,
                                                  canBeDragged: item.canBeDragged
                                              )
                                              return cell
                                          } else {
                                              let cell = collectionView.dequeueReusableCell(
                                                  withReuseIdentifier: GridViewCounterItemCell.reuseIdentifier,
                                                  for: indexPath
                                              ) as? GridViewCounterItemCell
                                              cell?.update(
                                                  name: item.name,
                                                  secret: item.secret,
                                                  serviceTypeName: item.serviceTypeName,
                                                  additionalInfo: item.additionalInfo,
                                                  iconType: item.iconType,
                                                  category: item.category
                                              )
                                              return cell
                                          }
                                      }
                                      let cell = collectionView.dequeueReusableCell(
                                          withReuseIdentifier: GridEmptyCollectionViewCell.reuseIdentifier,
                                          for: indexPath
                                      ) as? GridEmptyCollectionViewCell
                                      return cell
                                  })
                              dataSource.supplementaryViewProvider = { [weak self] collectionView, kind, indexPath
                                  -> UICollectionReusableView? in
                                  let header = collectionView.dequeueReusableSupplementaryView(
                                      ofKind: kind,
                                      withReuseIdentifier: GridSectionHeader.reuseIdentifier,
                                      for: indexPath
                                  ) as? GridSectionHeader
                                  header?.setIsEditing(collectionView.isEditing)
                                  header?.dataSource = self
                                  if let data = self?.dataSource.snapshot().sectionIdentifiers[indexPath.section] {
                                      header?.setConfiguration(data)
                                  }
                                  return header
                              }
                          }
                          
                          func setupDragAndDrop() {
                              gridView.dragDelegate = self
                              gridView.dropDelegate = self
                              gridView.dragInteractionEnabled = presenter.enableDragAndDropOnStart
                          }
                          
                          func setupEmptyScreensLayout() {
                              view.addSubview(emptySearchScreenView, with: [
                                  emptySearchScreenView.leadingAnchor.constraint(equalTo: gridView.frameLayoutGuide.leadingAnchor),
                                  emptySearchScreenView.trailingAnchor.constraint(equalTo: gridView.frameLayoutGuide.trailingAnchor),
                                  emptySearchScreenView.topAnchor.constraint(equalTo: gridView.frameLayoutGuide.topAnchor),
                                  emptySearchScreenView.bottomAnchor.constraint(equalTo: gridView.frameLayoutGuide.bottomAnchor)
                              ])
                              emptySearchScreenView.isHidden = true
                              emptySearchScreenView.alpha = 0
                              
                              view.addSubview(emptyListScreenView, with: [
                                  emptyListScreenView.leadingAnchor.constraint(equalTo: gridView.frameLayoutGuide.leadingAnchor),
                                  emptyListScreenView.trailingAnchor.constraint(equalTo: gridView.frameLayoutGuide.trailingAnchor),
                                  emptyListScreenView.topAnchor.constraint(equalTo: gridView.safeTopAnchor),
                                  emptyListScreenView.bottomAnchor.constraint(equalTo: gridView.safeBottomAnchor)
                              ])
                              emptyListScreenView.isHidden = true
                              emptyListScreenView.alpha = 0
                          }
                          
                          func configureLayout() {
                              guard let screenWidth = UIApplication.keyWindow?.bounds.size.width,
                                    configuredWidth != screenWidth else { return }
                              
                              configuredWidth = screenWidth
                              
                              let cellHeight = Theme.Metrics.servicesCellHeight
                              
                              let minimumCellWidth: CGFloat = Theme.Metrics.pageWidth
                              let itemsInRow = Int(screenWidth / minimumCellWidth)
                              let margin: CGFloat = 0
                              
                              let marginsWidth = margin * CGFloat(itemsInRow - 1)
                              let screenWidthWithoutMargins = screenWidth - marginsWidth
                              let elementWidth = floor(screenWidthWithoutMargins / CGFloat(itemsInRow))
                              
                              gridLayout.itemSize = CGSize(width: elementWidth, height: cellHeight)
                              gridLayout.minimumInteritemSpacing = margin
                              
                              gridLayout.headerReferenceSize = CGSize(width: 100, height: headerHeight)
                              
                              gridLayout.minimumLineSpacing = 0
                          }
                          
                          func setupEmptyScreensEvents() {
                              emptyListScreenView.pairNewService = { [weak self] in self?.presenter.handleShowCamera() }
                              emptyListScreenView.import2FAS = { [weak self] in
                                  AnalyticsLog(.onboardingBackupFile)
                                  self?.presenter.handleImport2FAS()
                              }
                              emptyListScreenView.importGA = { [weak self] in
                                  AnalyticsLog(.onboardingGA)
                                  self?.presenter.handleImportGA()
                              }
                              emptyListScreenView.help = { [weak self] in self?.presenter.handleShowHelp() }
                          }
                          
                          func setupNotificationsListeners() {
                              let center = NotificationCenter.default
                              center.addObserver(
                                  self, selector: #selector(notificationServicesWereUpdated), name: .servicesWereUpdated, object: nil
                              )
                              center.addObserver(
                                  self, selector: #selector(notificationSectionsWereUpdated), name: .sectionsWereUpdated, object: nil
                              )
                              center.addObserver(
                                  self,
                                  selector: #selector(notificationAppDidBecomeActive),
                                  name: UIApplication.didBecomeActiveNotification,
                                  object: nil
                              )
                              center.addObserver(
                                  self,
                                  selector: #selector(notificationAppDidBecomeInactive),
                                  name: UIApplication.willResignActiveNotification,
                                  object: nil
                              )
                              center.addObserver(
                                  self,
                                  selector: #selector(notificationAppDidBecomeInactive),
                                  name: UIApplication.didEnterBackgroundNotification,
                                  object: nil
                              )
                          }
                      }
                    

Nasz cel

Bezpieczeństwo w sieci jest kluczowe dla prywatności każdego z nas, zarówno online, jak i offline. Przejęcia kont prowadzą do wycieków danych osobowych, ujawniania cennych i wrażliwych informacji lub podszywania się w mediach społecznościowych, powodując co roku szkody liczone w miliardach dolarów.

Skąd wiesz, które rozwiązanie bezpieczeństwa jest dla Ciebie najlepsze? Czy oceniasz narzędzia wyłącznie na podstawie zaufania lub reputacji marki, czy może w oparciu o wiarygodne źródło informacji, w tym kod źródłowy?

Dlatego stworzyliśmy projekt 2FAS – inicjatywę opartą na wartościach transparentności, prywatności i bezpieczeństwa. Aplikacje 2FAS są zaprojektowane tak, by spełniały potrzeby każdego, pozostając przy tym bezpłatne, dostępne i łatwe w użyciu.
11

lat starannego rozwoju i ciągłych ulepszeń

4.7

średnia ocena w Google Play i App Store

6+

milionów pobrań na całym świecie

Jak zaczynaliśmy i gdzie jesteśmy dziś

2015
Mark

Marek założył 2FAS.

2016

Prowadzimy projekty R&D związane z bezpieczeństwem w sieci i 2FA.

2017

2FAS Auth debiutuje w App Store i Google Play.

2018

2FAS Auth osiąga pierwsze 100 tys. pobrań.

2019

2FAS Auth zostaje przeprojektowany zgodnie z nowymi wytycznymi UI.

2020

2FAS Auth osiąga 1 milion pobrań.

2021

Do 2FAS Auth dodano kopię zapasową, a liczba pobrań wzrosła do 2,5 miliona.

2022

Uruchomiliśmy serwer Discord oraz rozszerzenie przeglądarki. Aplikacja 2FAS Auth osiągnęła 5 milionów pobrań i stała się projektem open source.

2023

Dodaliśmy nowe języki do 2FAS Auth, a liczba pobrań wzrosła do 6 milionów.

2024

Rozpoczęliśmy pracę nad nowym projektem – 2FAS Pass, lokalnym menedżerem haseł. 2FAS Auth osiąga 8 milionów pobrań.

2025

2FAS Pass debiutuje w App Store i Google Play.

Dalej

Poznaj nasz ZESPÓŁ

Jesteśmy entuzjastami bezpieczeństwa, designu i open source, wiecznie ciekawi świata i gotowi zmienić sposób, w jaki dba się o bezpieczeństwo w sieci.

Główny zespół

Marek
Założyciel, CEO
Marek
Grzegorz
CTO
Grzegorz
Andrzej
CMO
Andrzej
Paweł
CDO, UX
Paweł
Rafał
Programista
Rafał
Zibi
Programista
Zibi
Mateusz
Programista
Mateusz
Tobiasz
Programista
Tobiasz
Krzysztof
Programista
Krzysztof
Mateusz
Projektant
Mateusz
Dominik
Projektant
Dominik
Irena
Menedżer ds. Wizerunku i Relacji
Irena
Rafał
Główny tłumacz, QA
Rafał
Leo
Lider społeczności
Leo
Mateusz
Bezpieczeństwo
Mateusz
Kontrybutorzy

Projekt 2FAS rozwijany jest dzięki wsparciu wspaniałej grupy społeczności, która regularnie ulepsza bazę kodu aplikacji 2FAS, jej zawartość i rozwija naszą społeczność na Discordzie i Reddicie.

Dhavan Bhayani@‌Dhavan Bhayani

Yurashi

AndJustice4All

Leonardo@Spluffity

Vijay Pondini@vijaypondini

Chris@Bravo_six

Justin Reitmeier

Fluffy

Jan Tennert

Noah@noah

Pedro Monteiro

SrHallowen_

SadBeats

Syun

Emp

NΞОИ

ThePokyx

Artem@Globart

Samuel Rollón del Río

Rosanna @roclahy

pmtz

Skyglitch

Davide Fiorini@fiorins

ΛMNESIΛ

Bruce

Kyriakos Parmakelis@Talos

Alexander K

polygon0323/ぽりごん

ROCKTAKEY

Mikuqwq

Xiaohuli_zi

Yoru.kot

Ceviz

Arsquid

Nifty

xfoxx

gabrielebonini99

Chcesz wesprzeć projekt 2FAS?

Udostępniamy światu aplikacje 2FAS całkowicie bezpłatnie. Jeśli wierzysz w utrzymanie Internetu bezpiecznym, otwartym i chronionym dla każdego, Twoje wsparcie będzie dla nas ogromnie ważne!

Chciałbyś wesprzeć projekt 2FAS?

Jest kilka sposobów, w jakie możesz przyczynić się do rozwoju projektu 2FAS:

  • Sprawdzaj kod źródłowy 2FAS.
  • Wprowadzaj zmiany w kodzie.
  • Zwiększaj bezpieczeństwo, wyszukując i usuwając luki.
  • Tłumacz aplikację 2FAS na nowe języki.
  • Promuj aplikację 2FAS w mediach społecznościowych i innych kanałach.
  • Pomagaj innym użytkownikom w kwestiach związanych z 2FA i aplikacjami 2FAS na naszym serwerze Discord.
  • Wspieraj innych użytkowników, tworząc dokumentację i pomagając im pokonywać trudności.
  • Aktualizuj i rozbudowuj bazę ikon usług.
  • Przekaż darowiznę na projekt 2FAS.
Sprawdź naszego GitHubaDołącz do naszego Discorda

2FAS pojawił się w

Chcesz się spotkać?
Połączmy się online
lub offline!

Pracujemy w 100% zdalnie, ale jeśli jesteś zainteresowany współpracą, umówmy się na rozmowę online albo na kawę w Las Vegas!

Znajdziesz nas w słonecznej Nevadzie

Two Factor Authentication Service, Inc.

1887 Whitney Mesa Dr #2130

Henderson, Nevada 89014

Chcesz się spotkać? Połączmy się online lub offline!Chcesz się spotkać? Połączmy się online lub offline!
  • O nas
  • Press kit
  • Regulamin
  • Polityka prywatności

Ustawienia strony

Polski

Autentykator

Produkty

  • Aplikacja mobilna 2FAS Auth
  • Rozszerzenie przeglądarki 2FAS Auth

Zasoby

  • Wsparcie projektu
  • Jak włączyć 2FA
  • Szybkie sprawdzenie rozszerzenia przeglądarki
  • Sprawdź wygenerowany token
  • Twój branding
  • Twój przewodnik po 2FA
  • Licencje open source

Porównania

  • Google Authenticator vs 2FAS Auth
  • Authy vs 2FAS Auth
  • Microsoft Authenticator vs 2FAS Auth
  • Duo vs 2FAS Auth

Polityki

  • Polityka prywatności 2FAS Auth
  • 2FAS Auth EULA

Menedżer haseł

Produkty

  • Aplikacja mobilna 2FAS Pass
  • Rozszerzenie przeglądarki 2FAS Pass

Zasoby

  • Cennik 2FAS Pass
  • Przywracanie danych 2FAS Pass
  • Licencje open source

Polityki

  • Polityka prywatności 2FAS Pass
  • 2FAS Pass EULA

Pomoc

  • Centrum pomocy
  • Wsparcie techniczne

Śledź nas

© 2026 Two Factor Authentication Service, Inc. Wszelkie prawa zastrzeżone.