v3.0 rebase

pull/4800/head
Carlgo11 4 years ago
parent 86412a9227
commit 84549c8b0e
No known key found for this signature in database
GPG Key ID: 5BC1F7A96CE756A5

@ -10,12 +10,12 @@ jobs:
- run:
name: Check Twitter handles
command: bash twitter.sh
working_directory: ./.tests
working_directory: _deployment/tests
- run:
name: Check Facebook handles
command: bash facebook.sh
working_directory: ./.tests
working_directory: _deployment/tests
- restore_cache:
keys:
@ -24,7 +24,7 @@ jobs:
- run:
name: Check Alexa ranking
command: bash alexa.sh
working_directory: ./.tests
working_directory: _deployment/tests
- save_cache:
key: awis-cache

@ -0,0 +1,69 @@
name: Deploy to GitHub Pages
on:
push:
branches: master
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2.1.0
- name: Get Cache
id: cache
uses: actions/cache@v1.1.2
with:
path: vendor/cache
key: ${{ runner.os }}-bundle-${{ hashFiles('**/Gemfile.lock') }}
- uses: actions/setup-ruby@v1
- name: Install dependencies
run: |
bundle config set path 'vendor/cache'
bundle config set cache_all true
bundle install --jobs 4 --retry 3
npm i babel-minify
sudo apt install webp -y
[ -d "vendor/cache" ] || { bundle package; }
- name: Check file extensions
run: |
./_deployment/tests/extensions.sh ${{ github.workspace }}/notes md
./_deployment/tests/extensions.sh ${{ github.workspace }}/css scss
./_deployment/tests/extensions.sh ${{ github.workspace }}/js js
./_deployment/tests/extensions.sh ${{ github.workspace }}/_layouts html
./_deployment/tests/extensions.sh ${{ github.workspace }}/_includes html
./_deployment/tests/extensions.sh ${{ github.workspace }}/_data yml
- name: Build region sites
run: ruby ./_deployment/regions.rb
- name: Generate webp images
run: ./_deployment/webp.sh
- name: Build the site
run: bundle exec jekyll build --config _config.yml,_deployment/config-production.yml
- name: Minify JavaScript files
run: ./_deployment/minify-js.sh
- name: Test HTML files
run: bundle exec rake proof
env:
NOKOGIRI_USE_SYSTEM_LIBRARIES: true
- name: Test JSON files
run: bundle exec rake jsonlint
- name: Deploy to GH Pages
if: success()
uses: crazy-max/ghaction-github-pages@v2.0.0
with:
target_branch: gh-pages
build_dir: _site
fqdn: twofactorauth.org
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

@ -7,24 +7,36 @@ jobs:
runs-on: ubuntu-latest
name: Test Jekyll
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v2.1.0
- uses: actions/cache@v1
- uses: actions/cache@v1.1.2
with:
path: vendor/cache
key: ${{ runner.os }}-bundle-${{ hashFiles('**/Gemfile.lock') }}
restore-keys: ${{ runner.os }}-bundle-
- name: Install requirements
- uses: actions/setup-ruby@v1
- name: Install dependencies
run: |
bundle config set path 'vendor/cache'
bundle config set cache_all true
bundle install --jobs 4 --retry 3
sudo npm i babel-minify -g
sudo apt install webp -y
[ -d "vendor/cache" ] || { bundle package; }
- name: Check file extensions
run: |
sudo snap install ruby --classic
bundle config set path 'vendor/cache'
bundle config set cache_all true
bundle install --jobs 4 --retry 3
[ -d "vendor/cache" ] || { bundle package; }
./_deployment/tests/extensions.sh ${{ github.workspace }}/notes md
./_deployment/tests/extensions.sh ${{ github.workspace }}/css scss
./_deployment/tests/extensions.sh ${{ github.workspace }}/js js
./_deployment/tests/extensions.sh ${{ github.workspace }}/_layouts html
./_deployment/tests/extensions.sh ${{ github.workspace }}/_includes html
./_deployment/tests/extensions.sh ${{ github.workspace }}/_data yml
- name: Build site
run: bundle exec jekyll build
run: bundle exec jekyll build --config _config.yml _deployment/config-production.yml
timeout-minutes: 1
- name: Run build checks
@ -32,8 +44,3 @@ jobs:
- name: Test JSON files
run: bundle exec rake jsonlint
- name: Test HTML files
run: bundle exec rake proof
env:
NOKOGIRI_USE_SYSTEM_LIBRARIES: true

@ -1,30 +1,28 @@
name: Rubocop
on:
push:
paths: .tests/verify.rb
pull_request:
paths: .tests/verify.rb
on: [push, pull_request]
jobs:
rubocop:
runs-on: ubuntu-latest
name: Rubocop
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2.1.0
- name: Get Cache
id: cache
uses: actions/cache@v1
with:
path: vendor/bundle
key: ${{ runner.os }}-bundler
- uses: actions/cache@v1.1.2
with:
path: vendor/cache
key: ${{ runner.os }}-bundle-${{ hashFiles('**/Gemfile.lock') }}
restore-keys: ${{ runner.os }}-bundle-
- name: Install requirements
run: sudo snap install ruby --classic
- uses: actions/setup-ruby@v1
- name: Run Bundler
run: bundle install --path vendor/bundle
- name: Run Bundler
run: |
bundle config set path 'vendor/cache'
bundle config set cache_all true
bundle install --jobs 4 --retry 3
[ -d "vendor/cache" ] || { bundle package; }
- name: Run Rubocop
run: bundle exec rake rubocop
- name: Run Rubocop
run: bundle exec rake rubocop

33
.gitignore vendored

@ -1,10 +1,33 @@
# IDE files
.idea/
nbproject/
# Jekyll/Ruby files
.bundle/
.config/
.jekyll-metadata
.sass-cache
Gemfile.lock
_site/
tmp/
vendor/
# NPM files
node_modules/
# OS files
*.DS_Store
*.swp
.idea/
Thumbs.db
ehthumbs.db
Gemfile.lock
.sass-cache
.jekyll-metadata
tmp/
# Project files
*.webp
ar/
au/
de/
gb/
nl/
nz/
se/
us/

@ -1 +0,0 @@
2.7.0

@ -1,44 +0,0 @@
#/usr/bin/ruby
require 'twitter'
# Set auth keys
client = Twitter::REST::Client.new do |config|
config.consumer_key = ENV["twitter_consumer_key"]
config.consumer_secret = ENV["twitter_consumer_secret"]
end
# Check that an argument has been sent
if ARGV.length != 1
puts "Error: Invalid amount of arguments passed."
puts "Usage: twitter.rb handle"
exit 1
end
begin
# Get twitter handle of the user
user = client.user(ARGV[0]).screen_name
# Catch any exceptions
rescue Exception => e
if e.class == Twitter::Error::NotFound
puts "Twitter user #{ARGV[0]} not found."
exit 2
elsif e.class == Twitter::Error::TooManyRequests
puts "Disregarding Twitter checks due to too many requests."
exit 0 # Soft fail if unable to access twitter api
elsif e.class == Twitter::Error::BadRequest
puts "Invalid authentication. Check Environment variables."
exit 1
else
puts e.backtrace
raise
end
end
if user.eql? ARGV[0]
exit 0
else
puts "Twitter handle \"#{ARGV[0]}\" should be \"#{user}\"."
exit 3
end

@ -1 +0,0 @@
twofactorauth.org

@ -1,5 +1,4 @@
Contributing to TwoFactorAuth.org
=======================
# Contributing to TwoFactorAuth.org
All the data is managed through a series of [Yaml][yaml] files so it may be
useful to read up on the Yaml syntax.
@ -40,19 +39,20 @@ everything for you.
makes Jekyll watch for file changes.
#### Testing with Bundler
To verify that your additions are fine, you can run the entire set of tests
locally which will check all links and images with:
```bash
$ bundle exec rake
```
To verify that your additions are fine, you can run the entire set of tests
locally which will check all links and images with:
However, this can take a while as there are roughly 900 links that it checks.
If you just wish to test your YAML changes, you can run:
```bash
$ bundle exec rake
```
However, this can take a while as there are roughly 900 links that it checks.
If you just wish to test your YAML changes, you can run:
```bash
$ bundle exec rake verify
```
```bash
$ bundle exec rake verify
```
### Using Vanilla Jekyll
@ -96,6 +96,7 @@ and follow the template below:
title: Category Name
icon: icon-class
```
The `icon-class` value needs to be chosen from [Semantic-Ui][semantic-ui].
Then create a new file in the `_data` directory with the same name as your section's
@ -133,14 +134,14 @@ websites:
The fields `name:`, `url:`, `img:`, `tfa:` are required for all entries.
#### Adding a site that *supports* TFA
#### Adding a site that _supports_ TFA
If a site does provide TFA, it is strongly recommended that you add the `doc:`
field where public documentation is available. Other fields should be included
if the website supports them. Any services that are not supported can be excluded.
Sites supporting TFA should not have a `twitter`, `facebook` or `email_address` field.
The following is an example of a website that *supports* TFA:
The following is an example of a website that _supports_ TFA:
```YAML
- name: YouTube
@ -156,14 +157,14 @@ The following is an example of a website that *supports* TFA:
doc: https://www.google.com/intl/en-US/landing/2step/features.html
```
#### Adding a site that *does not* support TFA
#### Adding a site that _does not_ support TFA
If a site does not provide TFA, the `twitter:` field should be included if the site uses
Twitter. Facebook can also be included using the `facebook` field, as well as Email using
the `email_address` field. If the website does not use the English language, the `lang:`
field should also be included. The fields `tfa:` and `doc:` can be completely removed.
The following is an example of a website that *does not* support TFA:
The following is an example of a website that _does not_ support TFA:
```YAML
- name: Netflix
@ -182,15 +183,15 @@ The `lang:` field is only used for non-English websites. The language codes shou
If a site is only available in certain countries or requires the user to do something out of the ordinary to set up 2FA, you can note this on the
website.
```YAML
- name: Site Name
url: https://www.site.com/
img: site.png
tfa:
- sms
exception: "Specific text goes here."
doc: <link to site TFA documentation>
```
```YAML
- name: Site Name
url: https://www.site.com/
img: site.png
tfa:
- sms
exception: "Specific text goes here."
doc: <link to site TFA documentation>
```
### Pro Tips
@ -216,8 +217,8 @@ website.
A lot of people have different ideas of what constitutes Two Factor Auth and
what doesn't, so it stands to reason that we should clarify a bit. For the
purposes of this site, Two Factor Auth is defined as any service provided as a
redundant layer for account *authentication*. Services that provide
*authorization* redundancy are certainly appreciated, but should not be
redundant layer for account _authentication_. Services that provide
_authorization_ redundancy are certainly appreciated, but should not be
considered Two Factor Auth.
As an example, a site that prompts you for an authentication token following

@ -1,10 +1,12 @@
# frozen_string_literal: true
source 'https://rubygems.org'
# Dependencies are bundled with the github-pages gem
gem 'github-pages', group: :jekyll_plugins
group :jekyll_plugins do
gem 'octopress-minify-html'
end
group :test do
gem 'diff-lcs', platforms: :mswin
gem 'diffy'

@ -18,6 +18,10 @@ GEM
commonmarker (0.17.13)
ruby-enum (~> 0.5)
concurrent-ruby (1.1.6)
css_press (0.3.2)
csspool-st (= 3.1.2)
json
csspool-st (3.1.2)
diffy (3.3.0)
dnsruby (1.61.3)
addressable (~> 2.5)
@ -31,12 +35,12 @@ GEM
faraday (1.0.1)
multipart-post (>= 1.2, < 3)
fastimage (2.1.7)
ffi (1.12.2)
ffi (1.13.0)
forwardable-extended (2.6.0)
gemoji (3.0.1)
github-pages (204)
github-pages (206)
github-pages-health-check (= 1.16.1)
jekyll (= 3.8.5)
jekyll (= 3.8.7)
jekyll-avatar (= 0.7.0)
jekyll-coffeescript (= 1.1.1)
jekyll-commonmark-ghpages (= 0.1.6)
@ -75,7 +79,7 @@ GEM
mercenary (~> 0.3)
minima (= 2.5.1)
nokogiri (>= 1.10.4, < 2.0)
rouge (= 3.13.0)
rouge (= 3.19.0)
terminal-table (~> 1.4)
github-pages-health-check (1.16.1)
addressable (~> 2.3)
@ -83,10 +87,10 @@ GEM
octokit (~> 4.0)
public_suffix (~> 3.0)
typhoeus (~> 1.3)
html-pipeline (2.12.3)
html-pipeline (2.13.0)
activesupport (>= 2)
nokogiri (>= 1.4)
html-proofer (3.15.2)
html-proofer (3.15.3)
addressable (~> 2.3)
mercenary (~> 0.3)
nokogumbo (~> 2.0)
@ -94,11 +98,15 @@ GEM
rainbow (~> 3.0)
typhoeus (~> 1.3)
yell (~> 2.0)
html_press (0.8.2)
htmlentities
multi_css (>= 0.1.0)
multi_js (>= 0.1.0)
htmlentities (4.3.4)
http_parser.rb (0.6.0)
i18n (0.9.5)
concurrent-ruby (~> 1.0)
jaro_winkler (1.5.4)
jekyll (3.8.5)
jekyll (3.8.7)
addressable (~> 2.4)
colorator (~> 1.0)
em-websocket (~> 0.5)
@ -203,6 +211,7 @@ GEM
gemoji (~> 3.0)
html-pipeline (~> 2.2)
jekyll (>= 3.0, < 5.0)
json (2.3.0)
jsonlint (0.3.0)
oj (~> 3)
optimist (~> 3)
@ -219,6 +228,10 @@ GEM
jekyll-feed (~> 0.9)
jekyll-seo-tag (~> 2.1)
minitest (5.14.1)
multi_css (0.1.0)
css_press
multi_js (0.1.0)
uglifier (~> 2)
multipart-post (2.1.1)
nokogiri (1.10.9)
mini_portile2 (~> 2.4.0)
@ -227,29 +240,39 @@ GEM
octokit (4.18.0)
faraday (>= 0.9)
sawyer (~> 0.8.0, >= 0.5.3)
octopress-hooks (2.6.2)
jekyll (>= 2.0)
octopress-minify-html (1.3.1)
html_press (~> 0.8)
jekyll (>= 2.0)
octopress-hooks
oj (3.10.6)
optimist (3.0.0)
optimist (3.0.1)
parallel (1.19.1)
parser (2.7.1.0)
parser (2.7.1.3)
ast (~> 2.4.0)
pathutil (0.16.2)
forwardable-extended (~> 2.6)
public_suffix (3.1.1)
rainbow (3.0.0)
rake (13.0.1)
rb-fsevent (0.10.3)
rb-fsevent (0.10.4)
rb-inotify (0.10.1)
ffi (~> 1.0)
regexp_parser (1.7.0)
rexml (3.2.4)
rouge (3.13.0)
rubocop (0.81.0)
jaro_winkler (~> 1.5.1)
rouge (3.19.0)
rubocop (0.85.0)
parallel (~> 1.10)
parser (>= 2.7.0.1)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.7)
rexml
rubocop-ast (>= 0.0.3)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 1.4.0, < 2.0)
rubocop-ast (0.0.3)
parser (>= 2.7.0.1)
ruby-enum (0.8.0)
i18n
ruby-progressbar (1.10.1)
@ -266,10 +289,13 @@ GEM
terminal-table (1.8.0)
unicode-display_width (~> 1.1, >= 1.1.1)
thread_safe (0.3.6)
typhoeus (1.3.1)
typhoeus (1.4.0)
ethon (>= 0.9.0)
tzinfo (1.2.7)
thread_safe (~> 0.1)
uglifier (2.7.2)
execjs (>= 0.3.0)
json (>= 1.8.0)
unicode-display_width (1.7.0)
yell (2.2.2)
zeitwerk (2.3.0)
@ -285,5 +311,6 @@ DEPENDENCIES
html-proofer
jsonlint
kwalify
octopress-minify-html
rake
rubocop

@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) 2014-2019 Josh Davis
Copyright (c) 2014-2020 Josh Davis
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in

@ -1,5 +1,4 @@
TwoFactorAuth.org
=================
# TwoFactorAuth.org
[![Build Status](https://img.shields.io/github/workflow/status/2factorauth/twofactorauth/Jekyll%20Tests?style=for-the-badge)](https://github.com/2factorauth/twofactorauth/actions)
[![License](https://img.shields.io/badge/license-mit-9A0F2D.svg?style=for-the-badge)](/LICENSE)
@ -14,38 +13,75 @@ The goal of this project is to build a website ([TwoFactorAuth.org](https://twof
Two Factor Authentication, as well as the methods that they provide.
Our hope is to aid consumers who are deciding between alternative services based on the security they
offer for their customers. This project also serves as an indicator of general security efforts used on a site.
offer for their customers. This project also serves as an indicator of general security efforts used on a site.
## Contributing
## Contributing :pencil2:
If you would like to contribute, please read the entire guidelines here in
[CONTRIBUTING.md][contrib].
## Running Locally
## Local installation :hammer_and_wrench:
TwoFactorAuth.org is built upon [Jekyll](https://jekyllrb.com/), using the [github-pages](https://github.com/github/pages-gem) gem.
In order to run the site locally, bundler, and all other dependencies will need to be installed, and afterwards Jekyll can serve
the site. If the `gem` command is not available, Ruby with RubyGems needs to be installed.
Once Ruby and RubyGems are installed and available from the command line, TwoFactorAuth can be setup using the following commands.
the site. Ubuntu:
```shell
```bash
sudo snap install ruby --classic
sudo apt install webp npm
npm i babel-minify
bundle install --path vendor/bundle
```
Windows Subsystem for Linux (WSL)
```bash
sudo apt install build-essential ruby-bundler ruby-dev make gcc g++ zlib1g-dev npm webp
npm i babel-minify
bundle install --path vendor/bundle
```
MacOS (_Requires Xcode_)
```bash
# Install homebrew
xcode-select --install
curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh
# Install ruby, webp & nodejs(npm)
brew install ruby
brew install webp
brew install nodejs
echo 'export PATH="/usr/local/opt/ruby/bin:$PATH"' >> ~/.bash_profile
# Install Bundler and gem dependencies
gem install bundler
cd ~/twofactorauth
bundle install
bundle exec jekyll serve
bundle install --path vendor/bundle
```
If you're using Ubuntu or [Bash on Windows (WSL)](https://docs.microsoft.com/en-us/windows/wsl/install-win10) you'll probably need to install these dependencies first:
## Running locally :running:
Ubuntu/WSL/MacOS:
```bash
# Generating regional sites (Optional)
ruby ./_deployment/regions.rb
# Minify JS (Optional)
./_deployment/minify-js.sh
# Generate WebP images
./_deployment/webp.sh
```shell
sudo apt install build-essential ruby-bundler ruby-dev make gcc g++ zlib1g-dev
# Building the site
bundle exec jekyll build
```
The TwoFactorAuth website should now be accessible from `http://localhost:4000`.
Another option is to run Jekyll inside a [Docker](https://www.docker.com/) container. Please read the [Jekyll Docker Documentation](https://github.com/envygeeks/jekyll-docker/blob/master/README.md) on how to use Jekyll.
Another option is to run Jekyll inside a [Docker](https://www.docker.com/) container. Please read the [Jekyll Docker Documentation](https://github.com/envygeeks/jekyll-docker/blob/master/README.md) on how to use Jekyll.
## License
## License :balance_scale:
This code is distributed under the MIT license. For more info, read the
[LICENSE][license] file distributed with the source code.

@ -10,25 +10,26 @@ task default: %w[proof verify jsonlint rubocop]
task :build do
config = Jekyll.configuration(
'source' => './',
'destination' => './_site'
'destination' => './_site',
'disable_disk_cache' => true
)
site = Jekyll::Site.new(config)
Jekyll::Commands::Build.build site, config
end
task :proof do
HTMLProofer.check_directory(
'./_site',
assume_extension: true,
HTMLProofer.check_file(
'./_site/index.html',
check_html: true,
empty_alt_ignore: true,
disable_external: true,
parallel: { in_threads: 5 }
checks_to_ignore: ['ScriptCheck']
).run
end
task proof_external: 'build' do
HTMLProofer.check_directory(
'./_site', \
HTMLProofer.check_file(
'./_site/index.html', \
assume_extension: true, \
check_html: true, \
cache: { timeframe: '1w' }, \
@ -36,14 +37,12 @@ task proof_external: 'build' do
).run
end
# rubocop:disable Layout/LineLength
JsonLint::RakeTask.new do |t|
t.paths = %w[_site/api/v1/data.json _site/api/v2/all.json _site/api/v2/tfa.json]
end
# rubocop:enable Layout/LineLength
task :verify do
ruby '.tests/verify.rb'
ruby '_deployment/tests/verify.rb'
end
RuboCop::RakeTask.new

@ -1,27 +1,29 @@
permalink: pretty
markdown: kramdown
title: Two Factor Auth List
title: Two Factor Auth
author: Josh Davis
description:
List of sites with Two Factor Auth support which includes SMS, email,
phone calls, hardware, and software.
List of sites with Two Factor Auth support which includes SMS, email,
phone calls, hardware, and software.
url: https://twofactorauth.org
repo: https://github.com/2factorauth/twofactorauth
img: img/logo.png
repository: 2factorauth/twofactorauth
img: /img/logo.png
env: development
twitter: 2faorg
social_image: https://repository-images.githubusercontent.com/17724730/63495880-b408-11e9-8cc4-03451aa4cc14
sass:
style: compressed
theme_color: "#39CCCC"
exclude:
- CNAME
- CONTRIBUTING.md
- EXCLUSION.md
- Gemfile
- LICENSE
- README.md
- Rakefile
- verify.rb
- vendor
- websites_schema.yml
- api/v2/README.md
- CNAME
- CONTRIBUTING.md
- CODE_OF_CONDUCT.md
- EXCLUSION.md
- Gemfile
- Gemfile.lock
- LICENSE
- README.md
- Rakefile
- vendor/
- api/v2/README.md
- .*
- node_modules/
theme: null

@ -293,7 +293,7 @@ websites:
- hardware
doc: https://www.coinfloor.co.uk/security
regions:
- uk
- gb
- name: CoinGate
url: https://coingate.com
@ -399,7 +399,7 @@ websites:
- hk
- sg
- kr
- uk
- gb
- au
- name: HitBTC

@ -297,7 +297,7 @@ websites:
- dk
- nl
- "no"
- uk
- gb
- us
- se

@ -146,7 +146,6 @@ websites:
img: gree.png
tfa:
- totp
doc: "/notes/gree/"
- name: Guild Wars 2
url: https://www.guildwars2.com

@ -32,7 +32,7 @@ websites:
- email
regions:
- es
- uk
- gb
- us
- name: CVS Caremark

@ -61,7 +61,7 @@ websites:
doc: https://help.blacknight.com/hc/en-us/articles/360001358517
regions:
- ie
- uk
- gb
- name: Bluehost
url: https://www.bluehost.com/
@ -250,7 +250,7 @@ websites:
- totp
doc: https://www.icuk.net/reseller/security.asp
regions:
- uk
- gb
- name: Infomaniak
url: https://www.infomaniak.com/
@ -542,7 +542,7 @@ websites:
- hardware
doc: https://github.com/2factorauth/twofactorauth/pull/997#issuecomment-77708501
regions:
- uk
- gb
- name: Ukraine
url: https://www.ukraine.com.ua/

@ -54,7 +54,6 @@ websites:
- sms
- proprietary
- hardware
doc: "/notes/schwab/"
- name: COL Financial
url: https://www.colfinancial.com

@ -1,33 +1,24 @@
# Languages should be categorized according to ISO 639-1
# Language codes (including within data files) should be in lowercase
cs:
progress_tweet: Děkujeme za práci na podpoře dvoufaktorového ověření, @TWITTERHANDLE!
work_tweet: Bezpečnost je důležitá, @TWITTERHANDLE. Byli bychom rádi, kdybyste podporovali dvoufaktorové ověření.
tweet: Bezpečnost je důležitá, @TWITTERHANDLE. Byli bychom rádi, kdybyste podporovali dvoufaktorové ověření.
de:
email_subject: Unterstützung von Zwei-Faktor-Authentifizierung
progress_tweet: Vielen Dank für die Fortschritte bei der Zwei-Faktor-Authentifizierung, @TWITTERHANDLE!
work_tweet: Sicherheit ist wichtig, @TWITTERHANDLE. Bitte aktiviert Zwei-Faktor-Authentifizierung auf eurer Webseite.
tweet: Sicherheit ist wichtig, @TWITTERHANDLE. Bitte aktiviert Zwei-Faktor-Authentifizierung auf eurer Webseite.
en:
email_subject: Support Two Factor Authentication
progress_tweet: Thanks for working on support for two factor auth, @TWITTERHANDLE!
work_tweet: Security is important, @TWITTERHANDLE. We'd like it if you supported two factor auth.
tweet: Security is important, @TWITTERHANDLE. We'd like it if you supported two factor auth.
es:
email_subject: Considere implementar autenticación de doble factor
progress_tweet: Gracias por estar trabajando en la implementación de la autenticación de doble factor (2FA), @TWITTERHANDLE!
work_tweet: La seguridad es importante, @TWITTERHANDLE. Nos gustaría que consideren implementar autenticación de doble factor (2FA).
tweet: La seguridad es importante, @TWITTERHANDLE. Nos gustaría que consideren implementar autenticación de doble factor (2FA).
fr:
progress_tweet: Merci d'avoir commencé à mettre en place un système de double authentification (2FA), @TWITTERHANDLE!
work_tweet: La sécurité est importante @TWITTERHANDLE. C'est pour quand la double authentification (2FA)?
tweet: La sécurité est importante @TWITTERHANDLE. C'est pour quand la double authentification (2FA)?
he:
email_subject: תמיכה באימות דו-שלבי
progress_tweet: תודה שהתחלתם לעבוד על תמיכה באימות דו-שלבי, @TWITTERHANDLE!
work_tweet: אבטחת מידע היא דבר חשוב, @TWITTERHANDLE. מתי תתמכו באימות דו-שלבי?
tweet: אבטחת מידע היא דבר חשוב, @TWITTERHANDLE. מתי תתמכו באימות דו-שלבי?
it:
progress_tweet: Grazie per l'interesse nel supportare l'autenticazione a due fattori (2FA), @TWITTERHANDLE!
work_tweet: La sicurezza è importante, @TWITTERHANDLE. Ci piacerebbe che supportaste l'autenticazione a due fattori (2FA).
tweet: La sicurezza è importante, @TWITTERHANDLE. Ci piacerebbe che supportaste l'autenticazione a due fattori (2FA).
pt:
progress_tweet: Obrigado pelo seu interesse em suportar a autenticação de dois fatores, @TWITTERHANDLE!
work_tweet: A segurança é importante, @TWITTERHANDLE. Agradecemos que suportasse a autenticação de dois fatores (2FA).
tweet: A segurança é importante, @TWITTERHANDLE. Agradecemos que suportasse a autenticação de dois fatores (2FA).
sv:
progress_tweet: Tack för att ni arbetar på two factor authentication, @TWITTERHANDLE!
work_tweet: Säkerhet är viktigt, @TWITTERHANDLE. Vänligen lägg till two factor authentication på er hemsida.
tweet: Säkerhet är viktigt, @TWITTERHANDLE. Vänligen lägg till two factor authentication på er hemsida.

@ -81,7 +81,7 @@ websites:
doc: https://support.gocardless.com/hc/en-gb/articles/360001164385
regions:
- fr
- uk
- gb
- name: Google Pay
url: https://pay.google.com/
@ -336,7 +336,7 @@ websites:
- br
- de
- au
- uk
- gb
- sg
- name: Yandex.Money

@ -1,23 +1,23 @@
- id: de
name: Germany
- id: se
name: Sweden
- id: ar
name: Argentina
- id: us
name: United States
- id: au
name: Australia
- id: gb
name: United Kindoms
- id: de
name: Germany
- id: nl
name: The Netherlands
name: Netherlands
- id: nz
name: New Zealand
- id: se
name: Sweden
- id: gb
name: United Kingdom
- id: us
name: United States

@ -1,127 +1,127 @@
- id: backup
title: Backup and Sync
icon: cloud upload
icon: fas fa-cloud-upload-alt
- id: banking
title: Banking
icon: dollar
icon: fas fa-dollar-sign
- id: betting
title: Betting
icon: trophy
icon: fas fa-trophy
- id: cloud
title: Cloud Computing
icon: cloud
icon: fas fa-cloud
- id: communication
title: Communication
icon: chat
icon: fas fa-comments
- id: cryptocurrencies
title: Cryptocurrencies
icon: btc
icon: fab fa-btc
- id: developer
title: Developer
icon: code
icon: fas fa-code
- id: domains
title: Domains
icon: globe
icon: fas fa-globe-europe
- id: education
title: Education
icon: book
icon: fas fa-book
- id: email
title: Email
icon: mail
icon: fas fa-envelope
- id: entertainment
title: Entertainment
icon: play
icon: fas fa-play
- id: finance
title: Finance
icon: money
icon: fas fa-dollar-sign
- id: food
title: Food
icon: utensils
icon: fas fa-utensils
- id: gaming
title: Gaming
icon: gamepad
icon: fas fa-gamepad
- id: government
title: Government
icon: university
icon: fas fa-university
- id: health
title: Health
icon: heartbeat
icon: fas fa-heartbeat
- id: hosting
title: Hosting/VPS
icon: sitemap
icon: fas fa-sitemap
- id: hotels
title: Hotels and Accommodations
icon: bed
icon: fas fa-bed
- id: identity
title: Identity Management
icon: id card
icon: fas fa-id-card
- id: investing
title: Investing
icon: chart line
icon: fas fa-chart-line
- id: iot
title: IoT
icon: wifi
icon: fas fa-wifi
- id: legal
title: Legal
icon: legal
icon: fas fa-balance-scale-left
- id: other
title: Other
icon: ellipsis horizontal
icon: fas fa-ellipsis-h
- id: payments
title: Payments
icon: credit card outline
icon: fas fa-credit-card
- id: remote
title: Remote Access
icon: desktop
icon: fas fa-desktop
- id: retail
title: Retail
icon: shopping cart
icon: fas fa-shopping-cart
- id: security
title: Security
icon: unlock
icon: fas fa-unlock
- id: social
title: Social
icon: users
icon: fas fa-users
- id: task
title: Task Management
icon: tasks
icon: fas fa-tasks
- id: transport
title: Transport
icon: car
icon: fas fa-car
- id: utilities
title: Utilities
icon: phone
icon: fas fa-phone-alt
- id: vpn
title: VPN Providers
icon: shield alternate
icon: fas fa-shield-alt

@ -124,7 +124,7 @@ websites:
facebook: gwruk
img: gwr.png
regions:
- uk
- gb
- name: Greyhound
url: https://www.greyhound.com
@ -167,7 +167,7 @@ websites:
facebook: LNERail
img: lner.png
regions:
- uk
- gb
- name: Lufthansa
url: https://www.lufthansa.com
@ -243,7 +243,7 @@ websites:
facebook: ScotRail
img: scotrail.png
regions:
- uk
- gb
- name: Sixt
url: https://www.sixt.com/
@ -287,7 +287,7 @@ websites:
facebook: swrailway
img: swr.png
regions:
- uk
- gb
- name: Spirit
url: https://www.spirit.com
@ -305,7 +305,7 @@ websites:
- nl
- be
- fr
- uk
- gb
- it
- es
@ -315,7 +315,7 @@ websites:
facebook: transportforlondon
img: tfl.png
regions:
- uk
- gb
- name: TripIt
url: https://www.tripit.com

@ -15,7 +15,7 @@ websites:
doc: https://aa.net.uk/kb-broadband-2fa.html
exception: "While both the accounts and control web pages support 2FA, each system is separate and requires its own setup."
regions:
- uk
- gb
- name: Arcadia
url: https://www.arcadia.com/
@ -48,7 +48,7 @@ websites:
twitter: bt_uk
facebook: BTUK
regions:
- uk
- gb
- name: Bulb
url: https://www.bulb.co.uk
@ -56,7 +56,7 @@ websites:
facebook: bulb
img: bulbenergy.png
regions:
- uk
- gb
- name: Cablevisión Fibertel
url: https://www.cablevisionfibertel.com.ar/
@ -196,7 +196,7 @@ websites:
facebook: ee
img: ee.png
regions:
- uk
- gb
- name: Ergon Energy
url: https://www.ergon.com.au/
@ -478,7 +478,7 @@ websites:
facebook: ThreeUK
img: three.png
regions:
- uk
- gb
- name: TIM
url: https://www.tim.it/
@ -537,7 +537,7 @@ websites:
facebook: virginmedia
img: virginmedia.png
regions:
- uk
- gb
- name: Virgin Mobile
url: https://www.virgin.com/gateways/mobile
@ -576,7 +576,7 @@ websites:
tfa:
- sms
regions:
- uk
- gb
- name: VoIP.ms
url: https://voip.ms/

@ -0,0 +1,3 @@
env: production
sass:
style: compressed

@ -0,0 +1,4 @@
#!/bin/bash
for file in _site/js/*.js; do
./node_modules/.bin/babel-minify "$file" -o "$file" --simplifyComparisons --simplify --mangle
done

@ -0,0 +1,54 @@
# frozen_string_literal: true
require 'yaml'
require 'fileutils'
data_dir = './_data'
sections = YAML.load_file("#{data_dir}/sections.yml")
regions = YAML.load_file("#{data_dir}/regions.yml")
tmp_dir = '/tmp'
git_dir = Dir.glob('.git')
FileUtils.cp_r(git_dir, "#{tmp_dir}/") unless File.exist?("#{tmp_dir}/.git")
# Region loop
# rubocop:disable Metrics/BlockLength
regions.each do |region|
dest_dir = "#{tmp_dir}/#{region['id']}"
unless File.exist?(dest_dir)
Dir.mkdir(dest_dir) unless File.exist?(dest_dir)
files = %w[index.html _includes _layouts _data]
FileUtils.cp_r(files, dest_dir)
end
# Category loop
sections.each do |section|
data = YAML.load_file("#{data_dir}/#{section['id']}.yml")
websites = data['websites']
section_array = []
# Website loop
websites.each do |website|
if website['regions'].nil?
section_array.push(website)
section_array.push(website)
elsif website['regions'].include?(region['id'].to_s)
end
end
website_array = { websites: section_array }
website_yaml = website_array.to_yaml.gsub("---\n:", '')
File.open("#{dest_dir}/_data/#{section['id']}.yml", 'w') do |file|
file.write website_yaml
end
end
out_dir = "#{Dir.pwd}/#{region['id']}"
puts "Building #{region['id']}..."
# rubocop:disable Layout/LineLength
puts `bundle exec jekyll build -s #{dest_dir} -d #{out_dir} --config _config.yml,_deployment/config-production.yml --baseurl #{region['id']}` # Add -V for debugging
# rubocop:enable Layout/LineLength
puts "#{region['id']} built!"
end
# rubocop:enable Metrics/BlockLength

@ -31,9 +31,7 @@ else
request['Accept'] = 'application/json'
response = https.request(request)
unless response.code == '200'
raise("Request failed. Check URL & API key. (#{response.code})")
end
raise("Request failed. Check URL & API key. (#{response.code})") unless response.code == '200'
# Parse response
body = JSON.parse(response.body)

@ -2,7 +2,7 @@
# Check Alexa rank
check_rank () {
urls="$(git log -p origin/master..HEAD ../_data | grep "^+[[:space:]]*url: " | cut -c11-)"
urls="$(git log -p origin/master..HEAD ../../_data | grep "^+[[:space:]]*url: " | cut -c11-)"
if [ -z "$urls" ]; then
echo "No URLs found."

@ -0,0 +1,8 @@
#!/bin/bash
dir=$1
ext=$2
cmd=`ls $dir | grep -v "\.${ext}$"`
for file in $cmd; do
echo "$dir/${file} doesn't contain the correct file extension for it's directory."
done
exit ${#cmd}

@ -0,0 +1,45 @@
# /usr/bin/ruby
# frozen_string_literal: true
require 'twitter'
# Set auth keys
client = Twitter::REST::Client.new do |config|
config.consumer_key = ENV['twitter_consumer_key']
config.consumer_secret = ENV['twitter_consumer_secret']
end
# Check that an argument has been sent
if ARGV.length != 1
puts 'Error: Invalid amount of arguments passed.'
puts 'Usage: twitter.rb handle'
exit 1
end
begin
# Get twitter handle of the user
user = client.user(ARGV[0]).screen_name
# Catch any exceptions
rescue Twitter::Error => e
if e.class == Twitter::Error::NotFound
puts "Twitter user #{ARGV[0]} not found."
exit 2
elsif e.class == Twitter::Error::TooManyRequests
puts 'Disregarding Twitter checks due to too many requests.'
exit 0 # Soft fail if unable to access twitter api
elsif e.class == Twitter::Error::BadRequest
puts 'Invalid authentication. Check Environment variables.'
exit 1
else
puts e.backtrace
raise
end
end
if user.eql? ARGV[0]
exit 0
else
puts "Twitter handle \"#{ARGV[0]}\" should be \"#{user}\"."
exit 3
end

@ -68,6 +68,7 @@ def test_img_file(img, name)
end
# rubocop:enable Style/GuardClause
end
# rubocop:enable Metrics/AbcSize
# rubocop:enable Metrics/MethodLength
@ -79,8 +80,9 @@ begin
# Check sections.yml alphabetization
error('section.yml is not alphabetized by name', sections_file) \
if sections != (sections.sort_by { |section| section['id'].downcase })
schema = YAML.load_file('websites_schema.yml')
schema = YAML.load_file('_deployment/tests/websites_schema.yml')
validator = Kwalify::Validator.new(schema)
# rubocop:disable Metrics/BlockLength
sections.each do |section|
data_file = "_data/#{section['id']}.yml"
data = YAML.load_file(data_file)
@ -114,14 +116,21 @@ begin
# After removing images associated with entries in test_img, alert
# for unused or orphaned images
imgs.each { |img| next unless img.nil? error("#{img} is not used", img) }
imgs.each do |img|
next if img.nil? || img.end_with?('webp') do
next
end
error("#{img} is not used", img)
end
end
# rubocop:enable Metrics/BlockLength
rescue Psych::SyntaxError => e
puts "<------------ ERROR in a YAML file ------------>\n"
puts "::error:: #{e}"
exit 1
rescue StandardError => e
puts "#{e}"
puts e.to_s
exit 1
else
puts "<------------ No errors. You\'re good to go! ------------>\n"

@ -17,23 +17,22 @@ mapping:
unique: yes
"img":
type: str
pattern: /^[a-z0-9_\-\+]+\.png/
pattern: /^[a-z0-9_\-\+]+\.(png|svg)$/
required: yes
"tfa":
type: seq
sequence:
- type: str
pattern: /^(sms|hardware|phone|email|u2f|totp|proprietary)+$/
pattern: /^(sms|hardware|phone|email|u2f|totp|proprietary)$/
"exception":
type: str
"doc":
type: str
"twitter":
type: str
pattern: /(\w){1,15}$/
pattern: /^(\w){1,15}$/
"facebook":
type: str
pattern: /(\w){1,50}$/
"email_address":
type: str
pattern: /\A([\w+\-].?)+@[a-z\d\-]+(\.[a-z]+)*\.[a-z]+\z/i
@ -42,8 +41,9 @@ mapping:
pattern: /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/
"lang":
type: str
pattern: /^[a-z]+$/
pattern: /^[a-z]{2}$/
"regions":
type: seq
sequence:
- type: str
pattern: /^[a-z]{2}$/

@ -0,0 +1,8 @@
#!/bin/bash
# converting PNG images
find $1 -type f -and -iname "*.png" \
-exec bash -c '
webp_path=$(sed 's/\.[^.]*$/.webp/' <<< "$0");
if [ ! -f "$webp_path" ]; then
cwebp -quiet "$0" -o "$webp_path";
fi;' {} \;

@ -0,0 +1,11 @@
<div class="col-12 col-md btn cat" type="button" data-toggle="collapse" data-target="#{{section.id}}-table" aria-expanded="false" aria-controls="{{section.id}}-table" id="{{section.id}}">
<h5 style="display: inline-block; text-align: center; margin-top: 0;">
<div style="width: 100%;">
<div style="display: flex; align-items: center; margin: auto;">
<i class="{{section.icon}} category-icon fa-fw"></i>
</div>
<small class="category-title">{{ section.title }}</small>
</div>
</h5>
</div>

@ -1,106 +1,121 @@
{% assign section_id = include.id-param %}
{% assign section_title = include.title-param %}
{% assign section_file = site.data[section_id] %}
<div class="website-table desktop-table {{ section_id }}-table" id="{{ section_id }}-desktoptable">
<table class="ui celled table content-wrapper">
<thead>
<tr>
<th class="single line four wide"><h3>{{ section_title }}</h3></th>
<th class="two wide">Docs</th>
<th class="two wide">SMS</th>
<th class="two wide">Phone Call</th>
<th class="two wide">Email</th>
<th class="two wide">Hardware Token</th>
<th class="two wide">Software Token</th>
</tr>
<div id="{{section_id}}-table" class="collapse category-table desktop-only">
<a id="{{section_id}}" class="category-href"></a>
<table class="table table-hover table-bordered table-bordered">
<thead class="sticky-top">
<tr>
<th scope="col">{{ section_title }}</th>
<th scope="col">Docs</th>
<th scope="col">SMS</th>
<th scope="col">Phone Call</th>
<th scope="col">Email</th>
<th scope="col">Hardware token</th>
<th scope="col">Software token</th>
</tr>
</thead>
<tbody class="jets-content">
{% for website in section_file.websites %}
{% assign email_subject = site.data.languages["en"].email_subject %}
{% assign progress_tweet = site.data.languages["en"].progress_tweet %}
{% assign workonit_tweet = site.data.languages["en"].work_tweet %}
{% if website.lang and site.data.languages[website.lang] %}
{% if site.data.languages[website.lang].email_subject %}
{% assign email_subject = site.data.languages[website.lang].email_subject %}
{% endif %}
{% if site.data.languages[website.lang].progress_tweet %}
{% assign progress_tweet = site.data.languages[website.lang].progress_tweet %}
{% endif %}
{% if site.data.languages[website.lang].work_tweet %}
{% assign workonit_tweet = site.data.languages[website.lang].work_tweet %}
{% endif %}
{% endif %}
<tr class="desktop-tr">
{% if website.status %}
<td class="main progress">
{% include row-title.html section=section_id website=website type='desktop' %}
<div class="progress-info">
<a class="ui mini orange button" href="{{website.status}}" target="_blank">
<i class="star icon"></i> In Progress!
</a>
</div>
</td>
<td class="twitter progress" colspan="6">
{% if website.twitter %}
<a class="ui twitter mini button"
href="https://twitter.com/share?url={{site.url|cgi_escape}}&amp;text={{progress_tweet|replace:'TWITTERHANDLE',website.twitter|cgi_escape}}&amp;hashtags={{page.hash|cgi_escape}}"
target="_blank"><i class="twitter icon"></i> {{page.link_progress}}</a>
{% else %}
&nbsp;
{% endif %}
</td>
{% elsif website.tfa %}
<td class="main positive">
{% include row-title.html section=section_id website=website type='desktop' %}
</td>
<td class="positive icon">
{% if website.doc %}
<a href="{{ website.doc }}"><i class="book link large icon"></i></a>
{% endif %}
</td>
<tbody class="searchContainer">
{% for website in site.data[section_id].websites %}
<td class="positive icon">
{% if website.tfa contains 'sms' %}
<i class="checkmark large icon" title="SMS"></i>
{% endif %}
</td>
<tr class="table-{% if website.tfa %}success{%else %}danger{% endif %}">
<td class="positive icon">
{% if website.tfa contains 'phone' %}
<i class="checkmark large icon" title="Phone"></i>
{% endif %}
</td>
<td>
<div class="searchWords" style="display: none;">{{ website.name }}&nbsp;{{ website.url }}&nbsp;{% for item in website.tfa %} 2fa:{{ item }}{% endfor %}</div>
<div class="row no-gutters">
<picture>
{% assign webp = website.img | replace: ".png", ".webp" %}
<source data-srcset="/img/{{section_id}}/{{webp}} 1x" type="image/webp">
<img class="logo lazyload{% if website.no_img_border %} no-border{%endif%}" data-src="/img/{{ section_id }}/{{ website.img }}" src="/img/placeholder.png" alt="">
</picture>
<td class="positive icon">
{% if website.tfa contains 'email' %}
<i class="checkmark large icon" title="Email"></i>
{% endif %}
</td>
<a class="site-name {% if website.exception %}exception-site{% endif %}" href="{{ website.url }}">{{ website.name }}</a>
<td class="positive icon">
{% if website.tfa contains 'u2f' or website.tfa contains 'hardware' %}
<i class="checkmark large icon" title="Hardware Token"></i>
{% endif %}
</td>
{% if website.exception %}
<i class="fas fa-exclamation-triangle exception" data-content="{{ website.exception }}"></i>
{% endif %}
</div>
</td>
{% if website.tfa %}
{% assign tfa = website.tfa %}
<td class="icon-cell">
{% if website.doc %}
<a href="{{ website.doc }}">
<i class="fas fa-book"></i>
</a>
{% endif %}
</td>
<td class="icon-cell">
{% if tfa contains "sms" %}
<i class="tfa-icon fas fa-check"></i>
{% endif %}
</td>
<td class="icon-cell">
{% if tfa contains "phone" %}
<i class="tfa-icon fas fa-check"></i>
{%endif%}</td>
</td>
<td class="icon-cell">
{% if tfa contains "email" %}
<i class="tfa-icon fas fa-check"></i>
{% endif %}
</td>
<td class="icon-cell">
<div class="row">
{% if tfa contains "hardware" %}
<i class="tfa-icon fas fa-check col"></i>
{% endif %}
{% if tfa contains "u2f" %}
<i class="tfa-icon u2f-icon col" title="U2F">
<img alt="U2F" height="20" src="/img/u2f.svg" type="image/svg">
</i>
{% endif %}
</div>
</td>
<td class="icon-cell">
<div class="row">
{% if tfa contains "totp" %}
<i class="tfa-icon fas fa-check col"></i>
{% endif %}
{% if tfa contains "proprietary" %}
<i class="tfa-icon fas fa-info col" title="Proprietary software based 2FA"></i>
{% endif %}
</div>
</td>
{% else %}
<td class="positive icon">
{% if website.tfa contains 'totp' or website.tfa contains 'proprietary' %}
<i class="checkmark large icon" title="Software Token"></i>
<td colspan="6">
Tell them to support 2FA!
<div class="social-button-group">
{% if website.twitter %}
<div class="twitter-button social-button btn" data-twitter="{{ website.twitter }}" data-lang="{{ website.lang }}">
<i class="fab fa-twitter"></i>
On Twitter
</div>
{% endif %}
{% if website.facebook %}
<div class="facebook-button social-button btn" data-facebook="{{ website.facebook }}">
<i class="fab fa-facebook-f"></i>
On Facebook
</div>
{% endif %}
{% if website.email_address %}
<div class="email-button social-button btn" data-email="{{ website.email_address }}" data-lang="{{ website.lang }}">
<i class="fas fa-envelope"></i>
Via Email</div>
{% endif %}
</div>
</td>
{% endif %}
</td>
{% else %}
<td class="main negative">
{% include row-title.html section=section_id website=website type='desktop' %}
</td>
<td class="twitter negative" colspan="6">
{% if website.twitter or website.facebook or website.email_address %}<span>{{page.link}} </span>{% endif %}
{% if website.twitter %} <a class="ui twitter mini button" href="https://twitter.com/share?url={{site.url|cgi_escape}}&amp;text={{workonit_tweet|replace:'TWITTERHANDLE',website.twitter|cgi_escape}}&amp;hashtags={{page.hash|cgi_escape}}" target="_blank"><i class="twitter icon"></i> on Twitter</a>{% endif %}
{% if website.facebook %} <a class="ui facebook mini button" href="https://facebook.com/{{website.facebook}}/" target="_blank"><i class="facebook icon"></i> on Facebook</a>{%endif%}
{% if website.email_address %} <a class="ui green mini button" href="mailto:{{website.email_address}}?subject={{email_subject|uri_escape}}" target="_blank"><i class="mail icon"></i> via Email</a>{% endif %}
</td>
{% endif %}
</tr>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
</div>

@ -1,18 +0,0 @@
{% if include.website.exception %}
{% capture html %}
<div class='header'>
Exceptions &amp; Restrictions
</div>
<div class='content'>
{% if include.website.exception %}
{{ include.website.exception }}
{% endif %}
</div>
{% endcapture %}
<span class="popup exception"
data-position="bottom center"
data-html="{{ html | strip_newlines }}">
<i class="warning sign red link icon"></i>
</span>
{% endif %}

@ -1,9 +0,0 @@
<div class="ui segment attached {{ include.class }}">
<h3 id="{{ same-value-as-yml-name }}" class="ui header">
{{ site.name }}
</h3>
<p>
Description of restriction more in depth here.
</p>
</div><!-- Section -->

@ -1,5 +0,0 @@
<div class="ui raised padded segment">
<h3 class="ui header">
No Site Restrictions Listed
</h3>
</div><!-- Section -->

@ -1,13 +0,0 @@
<div class="ui teal inverted menu">
<a href="/" class="item">
<i class="home icon"></i>
Home
</a>
<div class="right menu">
<a href="{{ site.repo }}" class="item">
<i class="github alternate icon"></i>
Contribute
</a>
</div>
</div>

@ -0,0 +1,41 @@
<meta content="/img/icons/icon_310x310.png" name="msapplication-square310x310logo">
<link href="/img/icons/apple-icon_128x128.png" rel="apple-touch-icon" sizes="128x128">
<link href="/img/icons/apple-icon_180x180.png" rel="apple-touch-icon" sizes="180x180">
<link href="/img/icons/apple-icon_192x192.png" rel="apple-touch-icon" sizes="192x192">
<link href="/img/icons/icon.svg" rel="icon">
<link href="/img/icons/icon_192x192.png" rel="icon" sizes="192x192">
<link href="/img/icons/splashscreens/iphone5_splash.png"
media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2)"
rel="apple-touch-startup-image" />
<link href="/img/icons/splashscreens/iphone6_splash.png"
media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2)"
rel="apple-touch-startup-image" />
<link href="/img/icons/splashscreens/iphoneplus_splash.png"
media="(device-width: 621px) and (device-height: 1104px) and (-webkit-device-pixel-ratio: 3)"
rel="apple-touch-startup-image" />
<link href="/img/icons/splashscreens/iphonex_splash.png"
media="(device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3)"
rel="apple-touch-startup-image" />
<link href="/img/icons/splashscreens/iphonexr_splash.png"
media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2)"
rel="apple-touch-startup-image" />
<link href="/img/icons/splashscreens/iphonexsmax_splash.png"
media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3)"
rel="apple-touch-startup-image" />
<link href="/img/icons/splashscreens/ipad_splash.png"
media="(device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2)"
rel="apple-touch-startup-image" />
<link href="/img/icons/splashscreens/ipadpro1_splash.png"
media="(device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2)"
rel="apple-touch-startup-image" />
<link href="/img/icons/splashscreens/ipadpro3_splash.png"
media="(device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2)"
rel="apple-touch-startup-image" />
<link href="/img/icons/splashscreens/ipadpro2_splash.png"
media="(device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2)"
rel="apple-touch-startup-image" />
<link rel="mask-icon" href="/img/icons/apple-icon.svg" color="{{ site.theme_color }}">

@ -1,68 +1,80 @@
{% assign section_id = include.id-param %}
{% assign section_title = include.title-param %}
{% assign section_file = site.data[section_id] %}
<div class="website-table mobile-table {{ section_id }}-table" id="{{ section_id }}-mobiletable">
<div class="label">
<h3>{{ section_title }}</h3>
</div>
<div class="jets-content">
{% for website in section_file.websites %}
{% assign email_subject = site.data.languages["en"].email_subject %}
{% assign progress_tweet = site.data.languages["en"].progress_tweet %}
{% assign workonit_tweet = site.data.languages["en"].work_tweet %}
{% if website.lang and site.data.languages[website.lang] %}
{% if site.data.languages[website.lang].email_subject %}
{% assign email_subject = site.data.languages[website.lang].email_subject %}
{% endif %}
{% if site.data.languages[website.lang].progress_tweet %}
{% assign progress_tweet = site.data.languages[website.lang].progress_tweet %}
{% endif %}
{% if site.data.languages[website.lang].work_tweet %}
{% assign workonit_tweet = site.data.languages[website.lang].work_tweet %}
{% endif %}
{% endif %}
{% if website.status %}
<div class="main progress">
{% include row-title.html section=section_id website=website type='mobile' %}
<p>IN PROGRESS!</p>
{% if website.twitter %}
<div>
<a class="ui twitter mini button"
href="https://twitter.com/share?url={{site.url|cgi_escape}}&amp;text={{progress_tweet|replace:'TWITTERHANDLE',website.twitter|cgi_escape}}&amp;hashtags={{page.hash|cgi_escape}}"
target="_blank"><i class="twitter icon"></i> {{page.link_progress_mobile}}</a>
</div>
{% endif %}
</div>
{% elsif website.tfa %}
<div class="main positive">
{% include row-title.html section=section_id website=website type='mobile' %}
<div class="methods">
{% if website.hardware or website.tfa contains 'hardware' %}<p><i class="checkmark small icon" title="Hardware"></i> Hardware</p>{% endif %}
{% if website.tfa contains 'u2f' %}<p><i class="checkmark small icon" title="U2F"></i> U2F</p>{% endif %}
{% if website.tfa contains 'totp' or website.tfa contains 'proprietary' %}<p><i class="checkmark small icon" title="Software"></i> Software</p>{% endif %}
{% if website.tfa contains 'sms' %}<p><i class="checkmark small icon" title="SMS"></i> SMS</p>{% endif %}
{% if website.tfa contains 'phone' %}<p><i class="checkmark small icon" title="Phone"></i> Phone</p>{% endif %}
{% if website.tfa contains 'email' %}<p><i class="checkmark small icon" title="Email"></i> Email</p>{% endif %}
</div>
{% if website.doc %}
<div class="button-group">
<a alt="Documentation" href="{{ website.doc }}" class="ui twitter mini button"><i class="large book icon"></i> Docs</a>
<div class="collapse category-table mobile-only searchContainer" id="{{section_id}}-mobile-table">
<h2 class="search-table-title">{{ section_title }}</h2>
{% for website in site.data[section_id].websites %}
<div class="col-11 {% if website.tfa %}table-success{%else%}table-danger{%endif%}">
<div class="searchWords" style="display: none;">{{ website.name }}&nbsp;{{ website.url }}&nbsp;{% for item in website.tfa %} 2fa:{{ item }}{% endfor %}</div>
<!-- Title -->
<div class="site-title">
<a class="site-name" href="{{ website.url }}">
<img class="logo lazyload{% if website.no_img_border %} no-border{%endif%}" data-src="/img/{{ section_id }}/{{ website.img }}" src="/img/placeholder.png" alt="">
{{ website.name }}</a>
{% if website.exception %}
<i class="fas fa-exclamation-triangle exception" data-content="{{ website.exception }}"></i>
{% endif %}
</div>
<!-- tfa options -->
{% if website.tfa %}
<div class="row row-cols-2">
{% for tfa in website.tfa %}
<div class="col text-success">
<i class="fas fa-check"></i>
<b>
{{ tfa | replace: "proprietary", "software" | replace: "hardware", "hardware" | capitalize | replace: "Sms", "SMS" | replace: "Totp", "TOTP" | replace: "U2f", "U2F" }}</b>
</div>
{% endfor %}
</div>
{% if website.doc %}
<div class="btn doc-btn col-11 col-sm-8 d-flex justify-content-center website-doc">
<a href="{{ website.doc }}">
<i class="fas fa-book"></i>
Read more
</a>
</div>
{% endif %}
{% else %}
<b class="text-danger">2FA not supported</b>
<div class="row justify-content-center">
{% if website.twitter %}
<div class="col ml-md-auto twitter-button social-button btn" title="Tweet them!" data-twitter="{{ website.twitter }}" data-lang="{{ website.lang }}">
<i class="fab fa-twitter"></i>
</div>
{% endif %}
{% if website.facebook %}
<div class="col facebook-button social-button btn" title="Contact them!" data-facebook="{{ website.facebook }}">
<i class="fab fa-facebook-f"></i>
</div>
{% endif %}
{% if website.email_address %}
<div class="col email-button social-button btn" title="Email them!" data-email="{{ website.email_address }}" data-lang="{{ website.lang }}">
<i class="fas fa-envelope"></i>
</div>
{% endif %}
</div>
{% endif %}
</div>
{% else %}
<div class="main negative">
{% include row-title.html section=section_id website=website type='mobile' %}
<div class="methods">
<p><i class="ban small icon" title="None"></i> 2FA not supported</p>
</div>
<div class="button-group">
{% if website.twitter %} <a class="ui twitter mini button" alt="Twitter" href="https://twitter.com/share?url={{site.url|cgi_escape}}&amp;text={{workonit_tweet|replace:'TWITTERHANDLE',website.twitter|cgi_escape}}&amp;hashtags={{page.hash|cgi_escape}}" target="_blank"><i class="twitter icon"></i></a>{% endif %}
{% if website.facebook %} <a class="ui facebook mini button" alt="Facebook" href="https://facebook.com/{{website.facebook}}/" target="_blank"><i class="facebook icon"></i></a>{%endif%}
{% if website.email_address %} <a class="ui green mini button" alt="Email" href="mailto:{{website.email_address}}?subject={{email_subject|uri_escape}}" target="_blank"><i class="mail icon"></i></a>{% endif %}
</div>
</div>
{% endif %}
{% endfor %}
</div>
{% endfor %}
</div>

@ -0,0 +1,39 @@
<nav class="navbar navbar-expand-lg">
<div class="container">
<ul class="navbar-nav navbar-table ml-auto pr-5" style="flex-direction: row;">
{% unless page.name == "index.html" %}
<li class="nav-item" style="float:left">
<a class="nav-link" href="/">Home</a>
</li>
{% endunless %}
<li class="nav-item">
<a class="nav-link" href="/about">About</a>
</li>
{% if page.name == "index.html" %}
<li class="nav-item dropdown">
<a aria-expanded="false" aria-haspopup="true" class="nav-link dropdown-toggle" data-toggle="dropdown" id="regionDropdown" role="button">
Region
{% assign baseurl = site.baseurl %}
{% assign regions = site.data.regions | sort: "name" %}
{% assign regions2 = regions | map: 'id' %}
{% if regions2 contains baseurl %}
<span class="flag-icon flag-icon-{{ baseurl }}"></span>
{% else %}
<i class="fas fa-globe-africa"></i>
{% endif %}
</a>
<div aria-labelledby="regionDropdown" class="dropdown-menu">
<a class="dropdown-item" href="/">
<i class="fas fa-globe-africa"></i>
Global</a>
{% for region in regions %}
<a class="dropdown-item" href="/{{ region.id }}/">
<span class="flag-icon flag-icon-{{ region.id }}"></span>
{{ region.name }}</a>
{% endfor %}
</div>
</li>
{% endif %}
</ul>
</div>
</nav>

@ -1,16 +0,0 @@
{%- assign website = include.website -%}
{%- assign img_path = '/img/' | append: include.section | append: '/' | append: website.img -%}
<div class="title">
<div class="keywords" style="display:none;">{{ website.name }}&nbsp;{{ website.url }}&nbsp;{% for item in website.tfa %} tfa:{{ item }}{% endfor %}</div>
<noscript>
<img src="{{ img_path }}" class="icon" alt="{{ website.name }}">
</noscript>
<img src="/img/placeholder.png" data-src="{{ img_path }}" class="icon" alt="{{ website.name }}">
<a href="{{ website.url }}" class="name">{{ website.name }}</a>
{%- include exception.html website=website -%}
{%- if website.status and include.type == 'mobile' -%}
<a href="{{ website.status }}" target="_blank">
<i class="external url link large icon"></i>
</a>
{%- endif -%}
</div>

@ -1,73 +1,101 @@
---
---
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv='Content-Security-Policy' content="script-src 'self' https://ajax.cloudflare.com https://code.jquery.com https://cdnjs.cloudflare.com; style-src 'self' 'unsafe-inline' data: https://fonts.googleapis.com https://cdnjs.cloudflare.com; font-src 'self' data: https://fonts.gstatic.com https://cdnjs.cloudflare.com; img-src 'self';">
<meta charset="UTF-8">
<meta name="description" content="{{ page.description | default: site.description }}">
<meta name="author" content="{{ site.author }}">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/png" href="/img/logo.png"/>
<meta property="og:title" content="{{ page.title | default: site.title }}">
<meta property="og:type" content="website">
<meta property="og:image" content="{{ site.url }}/{{ site.img }}">
<meta property="og:url" content="{{ page.url | prepend: site.url }}">
<meta property="og:description" content="{{ page.description | default: site.description }}">
<head>
<meta charset="utf-8">
<meta content="width=device-width, initial-scale=1, shrink-to-fit=no" name="viewport">
<meta content="yes" name="apple-mobile-web-app-capable">
<meta content="default" name="apple-mobile-web-app-status-bar-style">
<meta name="msapplication-TileColor" content="{{ site.theme_color }}">
<meta name="description" content="{{ site.description }}">
<meta name="theme-color" content="{{ site.theme_color }}">
<meta name="application-name" content="{{ site.title }}">
<meta property="og:title" content="{{ site.title }}">
<meta property="og:url" content="{{ site.url }}">
<meta property="og:description" content="{{ site.description }}">
<meta content="https://twofactorauth.org/img/logo.png" property="og:image">
<meta content="website" property="og:type">
<meta content="summary_large_image" property="twitter:card">
<meta property="twitter:title" content="{{ site.title }}">
<meta property="twitter:creator" content="{{ site.author }}">
<meta property="twitter:site" content="{{ site.twitter }}">
<meta property="twitter:image" content="{{ site.social_image }}">
<meta property="twitter:description" content="{{ site.description }}">
<title>{{ site.title }}</title>
{% include icons.html %}
<link href="/manifest.json" rel="manifest">
<link rel="stylesheet" href="/css/bootstrap.css"/>
<link rel="stylesheet" crossorigin="anonymous" integrity="sha512-9BwLAVqqt6oFdXohPLuNHxhx36BVj5uGSGmizkmGkgl3uMSgNalKc/smum+GJU/TTP0jy0+ruwC3xNAk3F759A==" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/css/all.min.css"/>
<link rel="stylesheet" crossorigin="anonymous" integrity="sha512-xbKj38YamwOa1yyC9gTFLExhbbV6r8WZwaEYYYaedfU0gosQuncv6p//9zcjK1NO2nkV/Nv5X5TkM/zjOnlc+w==" href="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/css/flag-icon.min.css"/>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:400,700|Roboto:300|Spartan:500&display=swap">
<link href="/css/main.css" rel="stylesheet">
<link href="/css/navbar.css" rel="stylesheet">
<link href="/css/corner.css" rel="stylesheet">
{% if page.name == "index.html" %}
<link href="/css/popup.css" rel="stylesheet">
<link href="/css/desktop-table.css" rel="stylesheet">
<link href="/css/mobile-table.css" rel="stylesheet">
<link href="/css/social-media.css" rel="stylesheet">
{% elsif page.name == "about.html" %}
<link href="/css/about.css" rel="stylesheet">
{% endif %}
</head>
<meta property="twitter:card" content="summary_large_image">
<meta property="twitter:title" content="{{ page.title | default: site.title }}">
<meta property="twitter:creator" content="{{ site.author }}">
<meta property="twitter:site" content="{{ site.twitter }}">
<meta property="twitter:image" content="{{ site.social_image }}">
<meta property="twitter:description" content="{{ page.description | default: site.description }}">
<body>
{% include navbar.html %}
<a href="{{ site.github.repository_url }}" class="github-corner" aria-label="View source on Github">
<svg viewbox="0 0 250 250">
<path class="octo-triangle" d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path>
<path class="octo-arm" d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2"></path>
<path class="octo-body" d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z"></path>
</svg>
</a>
<title>{{ page.title | default: site.title }}</title>
{% unless page.name == "index.html" %}
<div class="back-arrow">
<a onclick="history.back()">
<i class="fas fa-arrow-left"></i>
</a>
</div>
{% endunless %}
<!-- Google Fonts should not use SRI hashes as the CSS served dynamically changes depending on browser -->
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:400,700">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.3.1/semantic.min.css"
integrity="sha384-vQPhfJdJkfTCHP7ouiqoAojjcDFuU346yP8z/pRpSn0xsWOfkMd+DkNmxns9jy4l" crossorigin="anonymous">
<link rel="stylesheet" href="/css/base.css">
<link rel="stylesheet" href="/css/corner.css">
</head>
<div class="container">
<noscript>
<div class="alert bg-danger text-white border" style="padding: 1vh 1vw;margin-top: 1vh;">
<h2>It looks like you have JavaScript disabled!</h2>
<p>Without JavaScript, this page probably won't work very well.
For more information, or if you would like to talk to us about this,
please take a look at our
<b><a href="{{ site.repo }}" style="color: whitesmoke;">
GitHub repository</a></b>.</p>
</div>
</noscript>
{{ content }}
</div>
<body>
{{ content }}
<div class="footer">
<div id="innerFooter">Created by
<a href="https://joshldavis.com">Josh Davis</a>, designed by <a href="https://carlgo11.com">Carlgo11</a>
and maintained by
<a href="https://github.com/2factorauth">2factorauth</a>.<br>
With help from some awesome <a href="https://github.com/2factorauth/twofactorauth/graphs/contributors">contributors</a>. <i style="color: {{ site.theme_color }}" class="fas fa-heart"></i>
</div>
<div id="buildNumber" class="desktop-only" title="{{ site.github.build_revision }}">
Build #: {{ site.github.build_revision | slice: 0,7 }}<br>
Build Date: {{ site.time | slice: 0,10}}
</div>
</div>
<div class="ui divider"></div>
<script crossorigin="anonymous" integrity="sha512-C5x7QiS49O4ubITbqnAX93oOLk9/cASa+m8GawJMki1i4z8AjFDeklRCqiBBjj7niQULNW6nDhqf7l06zrZ9mA==" src="https://cdnjs.cloudflare.com/ajax/libs/jets/0.14.1/jets.min.js"></script>
<script crossorigin="anonymous" integrity="sha512-bLT0Qm9VnAYZDflyKcBaQ2gg0hSYNQrJ8RilYldYQ1FxQYoCLtUjuuRuZo+fjqhx/qtq/1itJ0C2ejDxltZVFg==" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script crossorigin="anonymous" integrity="sha512-nkVN47hpd3LOCD7BXeONKhZVrx2EE69VNvOwH28U6QTfjZ/LBfUN6EkmsinvuGVD5UWhyQeJudkVkkT+B4ffrA==" src="https://cdn.jsdelivr.net/npm/vanilla-lazyload@15.1.1/dist/lazyload.min.js"></script>
<script src="/js/bootstrap.min.js"></script>
<script src="/js/popup.js"></script>
<script src="/js/main.js"></script>
<script src="/js/social-media.js"></script>
<script src="/js/search.js"></script>
</body>
<div class="footer ui basic center aligned segment">
See an issue or want to add to this website? Fork it or create an issue on
<a href="{{ site.repo }}">GitHub</a>.
</div>
<div class="ui divider"></div>
<div class="footer ui basic center aligned segment">
Made with tea
<i class="leaf circular small icon"></i>
by
<a href="https://joshldavis.com">Josh Davis</a>
and love
<i class="heart circular small icon"></i>
from some awesome
<a href="{{ site.repo }}/graphs/contributors">Contributors</a>.
</div>
<!-- 3rd Party Libraries -->
<script src="https://code.jquery.com/jquery-3.2.1.min.js"
integrity="sha384-xBuQ/xzmlsLoJpyjoggmTEz8OWUFM0/RC5BsqQBDX2v5cMvDHcMakNTNrHIW2I5f"
crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.3.1/semantic.min.js"
integrity="sha384-d0+ufSr6Y7eU5V6E8Bt1AioIn4ParGkr0AwQ5RZD/S2mTaiEXMV78mqaYKMLE2qv"
crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.lazy/1.7.7/jquery.lazy.min.js"
integrity="sha384-wEyDFNGLEw12qsWXsjI32XObMejLosmqXK9KGBRTeR7Nbn2AED6YnD3mxmRqnBv9"
crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jets/0.14.0/jets.min.js"
integrity="sha384-NWhMP2tjh/VCnDqD+TXCEUMpy11tXXR80Jm/xqsYYwTLwuD4DwfPpcyr4xPdKAXl"
crossorigin="anonymous"></script>
<!-- TFA JS -->
<script src="/js/app.js"></script>
</body>
</html>

@ -0,0 +1,11 @@
---
layout: default
---
<h1 class="display-4" style="text-align: center;margin-bottom: 3vh;">{{ page.title }}</h1>
<h1 class="lead" style="text-align: center; font-size: 2em; font-family: 'Segoe UI Light',Arial,Helvetica">Information regarding
{{ page.title }}'s 2FA.</h1>
<hr>
{{ content }}

@ -1,83 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv='Content-Security-Policy' content="script-src 'self' https://ajax.cloudflare.com https://code.jquery.com https://cdnjs.cloudflare.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com https://cdnjs.cloudflare.com; font-src 'self' data: https://fonts.gstatic.com https://cdnjs.cloudflare.com; img-src 'self';">
<meta charset="UTF-8">
<meta name="description" content="{{ page.description | default: site.description }}">
<meta name="author" content="{{ site.author }}">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/png" href="/img/logo.png"/>
<meta property="og:title" content="{{ page.title | default: site.title }}">
<meta property="og:type" content="website">
<meta property="og:image" content="{{ site.url }}/{{ site.img }}">
<meta property="og:url" content="{{ page.url | prepend: site.url }}">
<meta property="og:description" content="{{ page.description | default: site.description }}">
<title>{{ page.title | default: site.title }}</title>
<!-- Google Fonts should not use SRI hashes as the CSS served dynamically changes depending on browser -->
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:400,700">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.3.1/semantic.min.css"
integrity="sha384-vQPhfJdJkfTCHP7ouiqoAojjcDFuU346yP8z/pRpSn0xsWOfkMd+DkNmxns9jy4l" crossorigin="anonymous">
<link rel="stylesheet" href="/css/base.css">
<link rel="stylesheet" href="/css/notes.css">
</head>
<body>
<div class="ui teal inverted menu">
<a href="/" class="item">
<i class="home icon"></i>
Home
</a>
<div class="right menu">
<a href="{{ site.repo }}" class="item">
<i class="github alternate icon"></i>
Contribute
</a>
</div>
</div>
{%- if page.dir == '/notes/' and page.name == 'index.html' -%}
<div id="note-header" class="ui center aligned icon header">
<i class="circular file outline icon"></i>
<h2>Notes</h2>
</div>
{%- else -%}
<div class="ui center aligned icon header">
<i class="circular mobile alternate icon"></i>
<h2>Two Factor Auth (2FA)</h2>
</div>
{%- endif -%}
{{ content }}
<div class="ui divider"></div>
<div class="footer ui basic center aligned segment">
See an issue or want to add to this website? Fork it or create an issue on
<a href="{{ site.repo }}">GitHub</a>.
</div>
<div class="ui divider"></div>
<div class="footer ui basic center aligned segment">
Made with tea
<i class="leaf circular small icon"></i>
by
<a href="https://joshldavis.com">Josh Davis</a>
and love
<i class="heart circular small icon"></i>
from some awesome
<a href="{{ site.repo }}/graphs/contributors">Contributors</a>.
</div>
<!-- 3rd Party Libraries -->
<script src="https://code.jquery.com/jquery-3.2.1.min.js"
integrity="sha384-xBuQ/xzmlsLoJpyjoggmTEz8OWUFM0/RC5BsqQBDX2v5cMvDHcMakNTNrHIW2I5f"
crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.3.1/semantic.min.js"
integrity="sha384-d0+ufSr6Y7eU5V6E8Bt1AioIn4ParGkr0AwQ5RZD/S2mTaiEXMV78mqaYKMLE2qv"
crossorigin="anonymous"></script>
</body>
</html>

@ -1,27 +0,0 @@
div,
.ui.table td {
&.positive {
background-color: rgba(46, 204, 64, 0.10) !important;
p {
color: rgba(45, 135, 46, 0.91);
}
}
&.negative {
background-color: rgba(255, 65, 54, 0.10) !important;
p {
color: rgba(195, 45, 42, 0.7);
margin-top: 10px;
}
}
&.progress {
background-color: rgba(255, 133, 27, 0.15) !important;
p {
color: rgba(195, 99, 27, 0.51);
}
}
}

@ -1,24 +0,0 @@
@mixin transition($element, $type, $time) {
-webkit-transition: $element $time $type;
-moz-transition: $element $time $type;
-ms-transition: $element $time $type;
-o-transition: $element $time $type;
transition: $element $time $type;
}
@mixin box-sizing($type) {
-webkit-box-sizing: $type;
-moz-box-sizing: $type;
box-sizing: $type;
}
@mixin display-flex() {
display: flex;
display: -webkit-flex;
display: -ms-flexbox;
}
@mixin flex-direction($direction) {
flex-direction: $direction;
-ms-flex-direction: $direction;
}

@ -0,0 +1,32 @@
---
layout: default
---
<h1 class="display-3 desktop-only title">The 2FactorAuth Group</h1>
<h1 class="mobile-only title">The 2FactorAuth Group</h1>
<!--
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc ultricies orci varius, dignissim dolor sed, malesuada
risus. Aenean lobortis orci augue, eu ultricies justo rutrum ac. Donec ultrices ullamcorper nunc, nec consectetur
nisl pharetra eu. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Phasellus
ultrices risus ut consectetur egestas. Donec dignissim, lectus et auctor ornare, quam ante aliquam augue, posuere
scelerisque est velit id nulla. Suspendisse neque ante, sodales et iaculis quis, aliquam quis lectus. Quisque
viverra posuere dignissim. Integer porta quis diam ut placerat.
</p>
<h2 class="display-4" id="team-title" style="display: none;">The Team</h2>-->
<div class="row">
{% for maintainer in site.github.organization_members %}
<div class="maintainer col-12 col-md-4 col-lg-3" id="{{ maintainer.login }}">
<a href="{{ maintainer.html_url}}">
<div class="card">
<img class="maintainer-img card-img-top lazyload" data-src="{{ maintainer.avatar_url }}&size=291" src="/img/placeholder.png">
<div class="card-body">
<h2 class="maintainer-name card-title">{{ maintainer.login }}</h2>
<hr>
</div>
</div>
</a>
</div>
{% endfor %}
</div>

@ -0,0 +1,46 @@
---
---
.title {
text-align: center;
margin-top: 10vh;
margin-bottom: 4vh;
&.mobile-only {
font-size: 8vw;
}
}
#team-title {
text-align: center;
margin-top: 10vh;
}
.row {
width: 95%;
margin: auto;
a {
text-decoration: none !important;
color: initial;
}
}
.maintainer {
align-items: center;
margin-top: 4vh;
margin-bottom: 4vh;
.card {
border-radius: 2px;
transition: all ease .4s;
&:hover {
transform: translateY(-0.75em);
}
.maintainer-name {
text-align: center;
color: #000000;
}
}
}

@ -1,338 +0,0 @@
---
---
@import 'mixins';
@import 'colors';
$primary-color: #39CCCC;
html, body, div, h1, h2, h3, h4, h5, h6, ul, ol, dl, li, dt, dd, p, blockquote, pre, form, fieldset, table, th, td {
margin: 0;
padding: 0;
}
html, body {
@include box-sizing(border-box);
height: 100%;
font-size: 18px;
}
*, *:before, *:after {
@include box-sizing(inherit);
}
img {
border: none;
}
a {
color: #009FDA;
text-decoration: none;
}
body {
font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
color: #505050;
line-height: 22px;
background: none;
}
p {
margin: 1em 0;
}
table {
th {
top: 0;
position: sticky;
z-index: 1;
}
}
.website-table .left,
.website-table .right {
display: inline-block;
height: 100%;
line-height: 2em;
}
.website-table .left {
width: 60%;
.name {
font-size: 22px;
font-weight: 300;
}
p {
margin-top: 10px;
}
}
.website-table .right {
float: right;
padding-left: 30px;
width: 40%;
}
.ui.inverted.teal.menu {
border-radius: 0;
}
#top-header {
padding: 3em 0;
.sub.header {
margin: 10px auto;
max-width: 80%;
}
}
#search-wrapper {
margin: 40px auto;
position: relative;
text-align: left;
width: 60%;
label {
left: 17px;
position: absolute;
top: 12px;
i {
color: #333333;
display: inline-block;
font-size: inherit;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
}
}
input[type=search] {
@include transition(all, ease, 300ms);
border: 1px #E3E3E3 solid;
border-radius: 30px;
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
display: block;
padding: 10px 45px;
width: 100%;
-moz-box-sizing: border-box;
box-sizing: border-box;
&:focus {
border-color: $primary-color;
box-shadow: 0 0 10px $primary-color;
outline: none;
}
}
#no-results {
display: none;
padding-bottom: 40px;
text-align: center;
}
.active-icon {
background-color: $primary-color;
color: white;
& + small {
color: #389B9B;
}
}
.ui.grid > .row {
padding: 0;
}
.desktop-table {
padding: 18px 0;
}
.category {
cursor: pointer;
padding-top: 20px;
text-align: center;
h5 i {
@include transition(all, ease, 300ms);
&:hover {
@extend .active-icon;
}
}
}
.ui.table td.twitter {
text-align: left;
span {
vertical-align: middle;
}
}
.website-table {
display: none;
margin: auto;
position: relative;
width: 90vw;
z-index: 1000;
}
.mobile-table {
display: none;
.label {
display: none;
padding: 15px 0;
text-align: center;
}
.jets-content {
border: 1px groove rgba(34, 36, 38, 0.14902);
border-radius: 5px;
margin: 0 auto 40px auto;
width: 90%;
> div {
border-bottom: 1px groove rgba(34, 36, 38, 0.14902);
padding: 1em;
}
.main {
.title {
@include display-flex();
@include flex-direction(row);
-ms-flex-align: center;
align-items: center;
.name {
-webkit-box-flex: 2;
-ms-flex-positive: 2;
flex-grow: 2;
margin: 0 5px;
}
}
.methods {
@include display-flex();
@include flex-direction(row);
flex-wrap: wrap;
margin: 0 10px;
p {
margin: 5px 0;
}
}
&.positive .methods p {
flex-basis: 50%;
}
.button-group {
@include display-flex();
@include flex-direction(row);
justify-content: space-between;
margin-top: 10px;
}
.icon {
margin-left: 0 !important;
margin-right: 0 !important;
}
}
.button {
padding: 1em;
width: 100%;
i.book.icon {
margin-bottom: 2px;
vertical-align: bottom;
}
}
p {
font-weight: 700;
font-size: 14px;
}
}
}
.ui.table td {
&.main {
line-height: 2em;
.title {
@include display-flex();
@include flex-direction(row);
-ms-flex-align: center;
align-items: center;
.name {
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
flex: 1;
padding-left: 0;
line-height: 1.5;
}
}
.progress-info {
@include display-flex();
-webkit-justify-content: center;
justify-content: center;
a {
width: 120px;
min-width: 120px;
padding-left: 0;
}
}
}
&.icon {
text-align: center;
width: 10%;
}
}
td img.icon,
.title img {
-webkit-box-shadow: 0 0 0 .1em rgba(0, 0, 0, .1) inset;
box-shadow: 0 0 0 .1em rgba(0, 0, 0, .1) inset;
background-color: white;
border-radius: 50%;
float: left;
padding: 4px 4px;
height: 2em;
width: 2em;
line-height: 1;
margin-right: 0.8em;
}
.ui.celled.table tr td.main a,
.ui.celled.table .exception,
.ui.celled.table .exception * {
padding-left: 3%;
vertical-align: top;
}
.ui.mini.button {
margin: 0.2em;
}
span.progress {
padding-left: 10%;
}
@media(max-width: 768px) {
.desktop-table {
display: none;
}
}

File diff suppressed because one or more lines are too long

@ -5,7 +5,8 @@
svg {
border: 0;
color:#FFFFFF;
fill:#39CCCC;
fill:
{{ site.theme_color }};
height: 80px;
position: absolute;
right: 0;

@ -0,0 +1,99 @@
---
---
@media screen and (min-width: 993px) {
/* Desktop table */
.category-table {
width: 100%;
box-shadow: 0 3px 8px 0 rgba(0, 0, 0, 0.2), 0 0 0 1px rgba(0, 0, 0, 0.08);
.category-href {
display: none;
}
table {
font-family: 'Spartan', sans-serif;
border-radius: 2px;
width: 100%;
margin-bottom: 0;
border-left: 0; // See tbody>tr>td> border-left
border-right: 0; // See tbody>tr>td> border-left
thead {
th {
font-weight: 700;
font-size: 18px;
line-height: 22px;
font-family: 'Open Sans', sans-serif;
}
}
tbody {
tr {
td {
border-left: 1px solid rgb(222, 226, 230); // Weird bug that displays borders outside of the table at 1st td in row.
&:first-child{
border-left: 0 solid !important;
}
}
&.table-danger {
td {
text-align: left;
}
}
}
td {
font-weight: 400;
font-family: 'Open Sans', sans-serif;
font-size: 18px !important;
.site-name {
text-align: left;
margin: auto 0;
text-overflow: ellipsis;
width: calc(100% - 32px - 0.8em);
max-height: 52px;
overflow: hidden;
white-space: nowrap;
&.exception-site {
margin-right: -24px;
}
}
}
/* 2FA cells */
.icon-cell {
width: 12%;
.u2f-icon {
width: min-content;
margin: auto;
img {
text-align: center;
margin: auto
}
}
.fa-book, .tfa-icon {
font-size: 27px;
line-height: 35px;
}
.tfa-icon {
color: #2c662d;
}
}
}
/* Both body and head */
tr {
height: 65.5px;
}
}
}
}

@ -0,0 +1,263 @@
---
---
body {
background-color: #fff;
font-family: open sans, helvetica neue, Helvetica, Arial, sans-serif;
min-width: 300px;
}
@media (prefers-color-scheme: dark) {
body {
background-color: #212121;
/*background: linear-gradient(#222,#333) fixed;*/
color: #eee;
}
.category-title {
color: #eee;
}
thead {
background-color: #262626 !important;
color: #eee;
}
thead > tr > th {
border-color: #424242 !important;
}
.table-success, .table-success > td {
background-color: #b1dfbb;
}
.table-danger, .table-danger > td {
background-color: #f1b0b7;
text-align: left;
}
.category-icon {
background-color: #eee !important;
}
a {
color: #3596ff;
}
}
td, th {
text-align: center;
}
thead {
background-color: #ffffff;
}
.back-arrow {
top: 0;
left: 0;
margin-top: 35px;
margin-left: 30px;
a {
.fa-arrow-left {
font-size: 35px;
color: #ccc;
&:hover {
color: #fff;
}
}
}
}
.container {
max-width: calc(1327px + 2rem);
padding: 0;
#main {
margin: 5vh auto;
height: 40vh;
text-align: center;
h2 {
font-family: 'Roboto', sans-serif;
font-weight: 300 !important;
}
}
.category-row {
margin: 2vh auto;
/* Category button */
.cat {
box-sizing: border-box;
display: block;
position: relative;
width: 90vw;
z-index: 1000;
-webkit-appearance: none;
border-radius: 0;
h5 {
box-sizing: border-box;
display: inline-block;
float: none;
position: static;
}
.category-title {
box-sizing: border-box;
display: inline;
float: none;
line-height: 23px;
position: static;
font-family: 'Spartan', sans-serif;
font-weight: 500;
font-size: 93%;
}
.category-icon {
background-color: #fff;
font-size: 36px;
margin: 15px auto;
text-align: center;
width: 1.7em;
line-height: 1.64em;
border-radius: 50%;
border: solid rgba(0, 0, 0, 0.1) 3px;
}
}
}
#logo {
margin: 1vh auto;
height: 30vh;
display: block;
}
.col {
display: block;
}
.collapsing {
-webkit-transition: none;
transition: none;
display: none;
}
.fas, .fab {
line-height: inherit;
}
/* Site name and logo */
.logo {
border-radius: 50%;
height: 32px;
width: 32px;
margin-right: .8em;
&.no-border {
border-radius: 0 !important;
}
}
h5:first-child {
margin-top: 0;
}
.fa-2x {
vertical-align: middle;
}
.btn {
border-radius: 2px;
}
}
#outerSearchBox {
height: 2.4em;
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.16), 0 0 0 1px rgba(0, 0, 0, 0.08);
border: 1px #e3e3e3 solid;
background-color: #fff;
color: rgba(0, 0, 0, .77);
font-size: 18px;
font-family: Arial, Helvetica, sans-serif;
padding: 0 5px;
margin: auto auto 6vh;
#searchIcon {
font-size: 1.2em;
height: 22px;
margin-left: 2px;
}
#innerSearchBox {
border: none;
width: calc(100% - 35px);
height: 100%;
float: right;
outline: none;
}
}
#outerSearchBox:focus-within, #outerSearchBox:hover {
box-shadow: 0 3px 8px 0 rgba(0, 0, 0, 0.2), 0 0 0 1px rgba(0, 0, 0, 0.08);
}
.footer {
bottom: 0;
position: static;
padding-top: 4vh;
padding-bottom: 2vh;
width: 100%;
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: 1fr;
grid-column-gap: 0px;
grid-row-gap: 0px;
#innerFooter {
grid-area: 1 / 2 / 2 / 3;
font-size: 0.9em;
text-align: center;
}
#buildNumber {
grid-area: 1 / 3 / 2 / 4;
font-family: Arial, Helvetica, sans-serif;
font-size: 15px;
text-align: right;
padding-right: 1vw;
}
}
#no-results {
display: none;
text-align: center;
}
.active {
.category-icon {
color: #fff;
background: {{ site.theme_color }} !important;
}
.category-title {
color: {{ site.theme_color }} !important;
}
}
@media screen and (min-width: 993px) {
.mobile-only {
display: none !important;
}
}
@media screen and (max-width: 992px) {
.desktop-only {
display: none !important;
}
#innerFooter {
grid-area: 1 / 1 / 1 / 4 !important;
}
}

@ -0,0 +1,48 @@
---
---
@media screen and (max-width: 992px) {
.category-table {
width: 100%;
.search-table-title {
text-align: center;
display: none;
margin: 4vh 0 1vh 0;
}
.table-success, .table-danger {
margin: auto;
padding: 18px;
border-bottom: 1px groove rgba(34, 36, 38, .14902);
.site-title {
font-size: 18px;
line-height: 53px;
.fa-exclamation-triangle {
float: right;
}
}
.website-doc {
background-color: #009fda;
margin: 0 auto;
a {
font-family: Spartan;
color: #fff;
text-decoration: none;
i {
color: #fff !important;
}
}
}
.text-danger {
text-align: center;
display: block;
}
}
}}

@ -0,0 +1,47 @@
---
---
#regionDropdown {
cursor: pointer;
}
.navbar {
background: #eeeeee96;
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12);
font-size: 17px;
line-height: 18px;
padding: 0.2rem 1rem;
li {
padding: 4px;
margin: 0 2px;
}
li:hover {
background: #ddd;
}
.dropdown-menu {
position: absolute !important; // Bootstrap normally sets position static for dropdowns in mobile views
}
}
.nav-link {
color: #3e3e3e;
&:hover {
color: #3e3e3e;
}
}
@media (prefers-color-scheme: dark) {
.navbar {
background: #6f6f6f96;
}
.nav-link {
color: #fff;
&:hover {
color: #3e3e3e !important;
}
}
}

@ -1,15 +0,0 @@
---
---
#note-header {
margin-bottom: 75px;
}
.row {
margin-bottom: 50px;
}
.ui.card > img {
height: 150px;
width: 150px;
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,34 @@
---
---
@media screen and (min-width: 993px) {
.social-button-group {
display: inline-block;
margin-left: 0.5vw;
}
}
.social-button {
height: 100%;
width: 140px;
color: white;
margin: 0 6px;
&.twitter-button {
background-color: #1DA1F2;
}
&.facebook-button {
background-color: #3b5998;
}
&.email-button {
background-color: #ea4235;
}
}
@media screen and (max-width: 992px) {
.social-button {
margin: .2em;
max-width: 50%;
}}

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1125 2436"><defs><style>.a{fill:#f2f2f3;}.b{fill:#fff;}.c{fill:#dbdbdb;}.d{fill:#b4b4b4;}.e{fill:#707070;}.f{fill:#464646;}.g,.i,.k{isolation:isolate;}.h,.k{fill:#b7b7b7;}.i{fill:#959595;}.j{fill:#a1a1a1;}</style></defs><title>apple-icon</title><rect class="a" width="1125" height="2436"/><circle class="b" cx="562.5" cy="1218" r="358.1"/><rect class="c" x="430.7" y="935.9" width="281.2" height="563.75" rx="42.2"/><path class="d" d="M571.7,1443a20.9,20.9,0,1,1-20.8,20.9h0a20.9,20.9,0,0,1,20.8-20.9m0-1.4a22.3,22.3,0,1,0,22.3,22.3h0a22.3,22.3,0,0,0-22.3-22.3Z"/><path class="d" d="M576.4,1455.3a3.9,3.9,0,0,1,4,3.9v9.5a4,4,0,0,1-4,4H567a4,4,0,0,1-4-4v-9.5a3.9,3.9,0,0,1,4-3.9h9.4m0-1.5H567a5.4,5.4,0,0,0-5.4,5.4v9.5a5.4,5.4,0,0,0,5.4,5.3h9.4a5.4,5.4,0,0,0,5.4-5.3v-9.5A5.4,5.4,0,0,0,576.4,1453.8Z"/><path class="e" d="M591.2,985.1H551.4a5.4,5.4,0,0,0,0,10.8h39.8a5.4,5.4,0,0,0,0-10.8Z"/><path class="f" d="M571.4,962.5a5.1,5.1,0,0,0,0,10.2,5.1,5.1,0,0,0,0-10.2Z"/><g class="g"><path class="h" d="M547.5,1200.9c0,9.6,6.1,17.1,12.3,21.1l-4.3,37.2H562l10.6-84.2C558.8,1174.9,547.5,1186.6,547.5,1200.9Z"/></g><path class="i" d="M596.6,1200.8c0-15.1-13-25.9-24-25.9-3.2,0-19.2,9.2-19.2,24.6,0,12.5,7.3,17.8,12.3,21.8l-3.7,37.8h27.3l-4.6-37.7C590.8,1217.1,596.6,1211.7,596.6,1200.8Z"/><g class="g"><path class="h" d="M443.2,1141.9c-20.8,0-37.7,26.5-37.7,59.2s16.9,59.2,37.7,59.2,37.7-26.5,37.7-59.2S464,1141.9,443.2,1141.9Zm-4.7,95.2c-12.1,0-21.9-16.3-21.9-36.5s9.8-36.6,21.9-36.6,21.9,16.4,21.9,36.6S450.6,1237.1,438.5,1237.1Z"/><path class="i" d="M405.6,1201.1c0-32.6,16.9-59.1,37.7-59.1a26.9,26.9,0,0,0-4-.3c-23.1,0-41.8,26.7-41.8,59.7s18.7,59.7,41.8,59.7a28.2,28.2,0,0,0,8.7-1.3,24.2,24.2,0,0,1-4.7.5C422.5,1260.3,405.6,1233.8,405.6,1201.1Z"/><path class="i" d="M438.5,1164c12.1,0,21.9,16.2,21.9,36.3s-9.8,36.6-21.9,36.6h-1.6a19.5,19.5,0,0,0,4.2.1c14.6,0,26.2-16.8,26.2-37.6s-10.3-37.8-24.8-37.6a19.1,19.1,0,0,0-7.3,1.8,11,11,0,0,0-2.7,1.7,15.1,15.1,0,0,1,6-1.4"/></g><path class="j" d="M565.8,1185.8v28.6h26.5a21.2,21.2,0,0,0,4.3-13.6,26,26,0,0,0-4.8-15Z"/><path class="k" d="M578.6,1214.4H480l-.3-28.6h86.1a13,13,0,0,1,9.7,4.4c3.6,4.4,3.1,8.4,3.1,8.4Z"/><polygon class="j" points="578.6 1214.4 480 1214.4 480.9 1201.1 578.6 1201.9 578.6 1214.4"/></svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 400"><defs><style>.a{fill:#fff;}.b{fill:#dbdbdb;}.c{fill:#b4b4b4;}.d{fill:#707070;}.e{fill:#464646;}.f,.h,.j{isolation:isolate;}.g,.j{fill:#b7b7b7;}.h{fill:#959595;}.i{fill:#a1a1a1;}</style></defs><title>icon</title><circle class="a" cx="200" cy="200" r="200"/><path class="b" d="M150,42.5h110A23.5,23.5,0,0,1,283.5,66V333.7a23.5,23.5,0,0,1-23.5,23.5H150a23.6,23.6,0,0,1-23.6-23.6V66A23.5,23.5,0,0,1,150,42.5Z"/><path class="c" d="M207,325.7a11.7,11.7,0,1,1-11.6,11.7h0A11.6,11.6,0,0,1,207,325.7m0-.8a12.5,12.5,0,1,0,12.4,12.4h0A12.4,12.4,0,0,0,207,324.9Z" transform="translate(0)"/><path class="c" d="M209.6,332.5a2.2,2.2,0,0,1,2.2,2.2V340a2.2,2.2,0,0,1-2.2,2.2h-5.2a2.2,2.2,0,0,1-2.3-2.2v-5.3a2.2,2.2,0,0,1,2.3-2.2h5.2m0-.8h-5.2a2.9,2.9,0,0,0-3,3V340a3,3,0,0,0,3,3h5.2a3,3,0,0,0,3-3v-5.3A2.9,2.9,0,0,0,209.6,331.7Z" transform="translate(0)"/><path class="d" d="M216.8,69.9H194.5a3.1,3.1,0,0,0-3,3,3,3,0,0,0,3,3h22.3a3,3,0,0,0,3-3,3.1,3.1,0,0,0-3-3Z" transform="translate(0)"/><path class="e" d="M205.6,57.3a2.9,2.9,0,1,0,2.9,2.9,2.9,2.9,0,0,0-2.9-2.9Z" transform="translate(0)"/><g class="f"><path class="g" d="M191.6,190.5c0,5.3,3.4,9.5,6.9,11.7L196.1,223h3.6l5.9-47.1C198,175.9,191.6,182.4,191.6,190.5Z" transform="translate(0)"/></g><path class="h" d="M219.1,190.4c0-8.4-7.3-14.5-13.5-14.5-1.8,0-10.7,5.2-10.7,13.8,0,6.9,4.1,9.9,6.9,12.1L199.7,223H215l-2.6-21C215.8,199.5,219.1,196.5,219.1,190.4Z" transform="translate(0)"/><g class="f"><path class="g" d="M133.4,157.5c-11.7,0-21.1,14.8-21.1,33.1s9.4,33,21.1,33,21.1-14.8,21.1-33S145,157.5,133.4,157.5Zm-2.7,53.2c-6.7,0-12.2-9.2-12.2-20.4s5.5-20.5,12.2-20.5S143,179,143,190.3,137.5,210.7,130.7,210.7Z" transform="translate(0)"/><path class="h" d="M112.4,190.6c0-18.3,9.4-33,21-33.1h-2.2c-12.9,0-23.4,14.9-23.4,33.3s10.5,33.4,23.4,33.4a20,20,0,0,0,4.9-.7l-2.6.2C121.8,223.6,112.4,208.8,112.4,190.6Z" transform="translate(0)"/><path class="h" d="M130.7,169.8c6.8,0,12.3,9.1,12.3,20.3s-5.5,20.5-12.3,20.5h-.9a9.7,9.7,0,0,0,2.4.1c8.1,0,14.6-9.4,14.6-21s-5.7-21.1-13.8-21a10.3,10.3,0,0,0-4.1,1,7,7,0,0,0-1.5.9,8.4,8.4,0,0,1,3.3-.8" transform="translate(0)"/></g><path class="i" d="M201.8,182v16h14.9a12.3,12.3,0,0,0,2.4-7.6,14.1,14.1,0,0,0-2.8-8.4Z" transform="translate(0)"/><path class="j" d="M209,198H153.9l-.2-16h48.1a7.2,7.2,0,0,1,5.4,2.5,6.4,6.4,0,0,1,1.8,4.7Z" transform="translate(0)"/><polygon class="i" points="209 198 153.9 198 154.5 190.6 209 191 209 198"/></svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 402 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

@ -0,0 +1,127 @@
- id: backup
title: Backup and Sync
icon: fas fa-cloud-upload-alt
- id: banking
title: Banking
icon: fas fa-dollar-sign
- id: betting
title: Betting
icon: fas fa-trophy
- id: cloud
title: Cloud Computing
icon: fas fa-cloud
- id: communication
title: Communication
icon: fas fa-comments
- id: cryptocurrencies
title: Cryptocurrencies
icon: fab fa-btc
- id: developer
title: Developer
icon: fas fa-code
- id: domains
title: Domains
icon: fas fa-globe-europe
- id: education
title: Education
icon: fas fa-book
- id: email
title: Email
icon: fas fa-envelope
- id: entertainment
title: Entertainment
icon: fas fa-play
- id: finance
title: Finance
icon: fas fa-dollar-sign
- id: food
title: Food
icon: fas fa-utensils
- id: gaming
title: Gaming
icon: fas fa-gamepad
- id: government
title: Government
icon: fas fa-university
- id: health
title: Health
icon: fas fa-heartbeat
- id: hosting
title: Hosting/VPS
icon: fas fa-sitemap
- id: hotels
title: Hotels and Accommodations
icon: fas fa-bed
- id: identity
title: Identity Management
icon: fas fa-id-card
- id: investing
title: Investing
icon: fas fa-chart-line
- id: iot
title: IoT
icon: fas fa-wifi
- id: legal
title: Legal
icon: fas fa-balance-scale-left
- id: other
title: Other
icon: fas fa-ellipsis-h
- id: payments
title: Payments
icon: fas fa-credit-card
- id: remote
title: Remote Access
icon: fas fa-desktop
- id: retail
title: Retail
icon: fas fa-shopping-cart
- id: security
title: Security
icon: fas fa-unlock
- id: social
title: Social
icon: fas fa-users
- id: task
title: Task Management
icon: fas fa-tasks
- id: transport
title: Transport
icon: fas fa-car
- id: utilities
title: Utilities
icon: fas fa-phone-alt
- id: vpn
title: VPN Providers
icon: fas fa-shield-alt

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 167.4 66.4" style="enable-background:new 0 0 167.4 66.4;" xml:space="preserve">
<style type="text/css">
.st0{fill:#2C662D;}
</style>
<path class="st0" d="M0,40.1V0h14.7v41.6c0,7.8,2.9,12.1,9.1,12.1S33,49.4,33,41.6V0h14.2v40.1c0,16.9-7.6,26.3-23.4,26.3
S0,57,0,40.1z"/>
<path class="st0" d="M58.9,56.6c18.3-14.8,30.6-25.3,30.6-34.1c0-6-3.8-9.3-10.5-9.3c-5.1,0-9.3,3-12.9,6.3l-8-7.6
c6.6-6.5,13-9.8,22.8-9.8c13.4,0,22.5,7.7,22.5,19.5c0,10.4-11.3,21.6-23.7,32.1h27v11h-48V56.6z"/>
<polygon class="st0" points="124.1,0 167.4,0 167.4,12.4 138.8,12.4 138.8,27.5 163.2,27.5 163.2,39.9 138.8,39.9 138.8,65.2
124.1,65.2 "/>
</svg>

After

Width:  |  Height:  |  Size: 902 B

@ -1,97 +1,47 @@
---
layout: default
link: Tell them to support 2FA
link_mobile: TWEET THEM
link_progress: Thank them for working on 2FA
link_progress_mobile: THANK THEM
hash: SupportTwoFactorAuth
---
<noscript>
<div class="ui icon error message">
<i class="warning sign icon"></i>
<div class="content">
<h1>It looks like you have JavaScript disabled!</h1>
<p>
Without JavaScript, this page probably won't work very well.
For more information, or if you would like to talk to us about this,
please take a look at our <a href="{{ site.repo }}">
GitHub repository</a>.
</p>
</div>
</div>
</noscript>
<a href="{{ site.repo }}" class="github-corner" aria-label="View source on Github">
<svg viewBox="0 0 250 250">
<path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z" class="octo-triangle"></path>
<path
d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2"
class="octo-arm"></path>
<path
d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" class="octo-body"></path>
</svg>
</a>
<div id="top-header" class="ui center aligned icon header">
<i class="circular mobile alternate icon"></i>
<div id="main">
<img alt="" id="logo" src="/img/icons/icon.svg">
<h2>Two Factor Auth (2FA)</h2>
<div class="sub header">List of websites and whether or not they support
<a href="https://en.wikipedia.org/wiki/Two-factor_authentication">2FA</a>.
</div>
<div class="sub header">
Add your own favorite site by submitting a pull request on the
<a href="{{ site.repo }}">GitHub repo</a>.
</div>
<div id="search-wrapper" class="sub header">
<label for="jets-search">
<i class="search icon"></i>
</label>
<input type="search" id="jets-search" placeholder="Search websites by name, URL or method (e.g. tfa:totp)"
autocomplete="off" spellcheck="false" tabindex="0">
</div>
</div>
<div class="ui stackable grid container">
<div class="five column row">
{% assign rowcount = 0 %}
{% for section in site.data.sections %}
<div class="col-11 col-md-8 col-lg-6" id="outerSearchBox">
<i class="fas fa-search fa-2x" id="searchIcon"></i>
<input aria-label="search" id="innerSearchBox" type="search">
</div>
<div class="row justify-content-start category-row">
{% assign rowcount = 0 %}
{% for section in site.data.sections %}
{% assign rowend = forloop.index | modulo: 5 %}
{% if rowend == 0 or forloop.index == forloop.length %}
<div id="{{ section.id }}" class="category column">
<h5 class="ui icon header">
<i class="circular {{ section.icon }} icon"></i>
<small>{{ section.title }}</small>
</h5>
</div>
{% include mobile-table.html id-param=section.id title-param=section.title %}
{% assign offcount = 5 | times: rowcount %}
{% for section in site.data.sections limit: 5 offset: offcount %}
{% include desktop-table.html id-param=section.id title-param=section.title %}
{% endfor %}
</div>
{% if forloop.index != forloop.length %}
{% assign rowcount = rowcount | plus: '1' %}
<div class="five column row">
{% endif %}
{% include category-button.html %}
{% include mobile-table.html id-param=section.id title-param=section.title %}
{% assign offcount = 5 | times: rowcount %}
{% for section in site.data.sections limit: 5 offset: offcount %}
{% include desktop-table.html id-param=section.id title-param=section.title %}
{% endfor %}
{% if forloop.index != forloop.length %}
{% assign rowcount = rowcount | plus: '1' %}
<div class="w-100 d-none d-md-block"></div>
{% endif %}
{% else %}
<div id="{{ section.id }}" class="category column">
<h5 class="ui icon header">
<i class="circular {{ section.icon }} icon"></i>
<small>{{ section.title }}</small>
</h5>
</div>
{% include mobile-table.html id-param=section.id title-param=section.title %}
{% endif %}
{% endfor %}
</div>
<div id="no-results">
<h2>No results found</h2>
</div>
{% include category-button.html %}
{% include mobile-table.html id-param=section.id title-param=section.title %}
{% endif %}
{% endfor %}
<div class="col"></div>
<div class="col"></div>
<div class="col"></div>
</div>
<h2 id="no-results">No results found.</h2>

@ -1,176 +0,0 @@
// When DOM elements are ready, excluding images
$(document).ready(function () {
// Check if URL references specific category
if (window.location.hash && window.location.hash.indexOf('#') > -1) {
openCategory(window.location.hash.substring(1));
}
// Unveil images when visible in jquery
$(function() { $('img').Lazy({visibleOnly: true}); });
// Show exception warnings upon hover
$('span.popup.exception').popup({
hoverable: true
});
$('a.popup.exception').popup();
});
/**
* Create an event that is called 500ms after the browser
* window is re-sized and has finished being re-sized.
* This event corrects for browser differences in the
* triggering of window resize events.
*/
$(window).resize(function () {
if (this.resizeTO) clearTimeout(this.resizeTO);
this.resizeTO = setTimeout(function () {
$(this).trigger('resizeEnd');
}, 500);
});
var isSearching = false;
var jets = new Jets({
callSearchManually: true,
contentTag: '.jets-content',
didSearch: function (searchPhrase) {
document.location.hash = '';
$('#no-results').css('display', 'none');
$('.category h5 i').removeClass('active-icon');
// Two separate table layouts are used for desktop/mobile
var platform = ($(window).width() > 768) ? 'desktop' : 'mobile';
var content = $('.' + platform + '-table .jets-content');
var table = $('.' + platform + '-table');
// Non-strict comparison operator is used to allow for null
if (searchPhrase == '') {
// Show all categories when no search term is entered
$('.website-table').css('display', 'none');
$('.website-table .label').css('display', 'none');
$('.category').show();
$('table').show();
isSearching = false;
} else {
// Hide irrelevant categories
$('.website-table').css('display', 'none');
$('.website-table .label').css('display', 'block');
$('.category').hide();
table.css('display', 'block');
content.parent().show();
for(var i = 0; i < content.length; i++) {
var section = $(content[i]);
// Hide table when all rows within are hidden by Jets
if (section.children(':hidden').length === section.children().length) {
if (platform == 'mobile') section.parent().hide();
else section.parent().parent().hide();
}
}
if (table.children().length == table.children(':hidden').length) {
$('#no-results').css('display', 'block');
}
// Display images that came into view by searching
$('img').Lazy({visibleOnly: true});
isSearching = true;
}
},
// Process searchable elements manually
manualContentHandling: function(tag) {
return $(tag).find('.keywords').text();
}
});
// Wrap the jets.search function with a debounced function
var debouncedSearch = debounce(function(e) {
jets.search(e.target.value);
}, 350);
// Attach a keyup event listener to the input
$('#jets-search').keyup(debouncedSearch);
/**
* Ensure searching is conducted with regard to the user's viewport
* after re-sizing the screen and close all categories after re-sizing
*/
$(window).on('resizeEnd', function () {
if (isSearching) jets.options.didSearch($('#jets-search').val());
});
// Display tables and color category selectors
$('.category').click(function () {
var name = $(this).attr('id');
isOpen(name) ? closeCategory(name) : openCategory(name);
});
/**
* Checks if a category is open
*
* @param category The id of a category as a string
* @returns {*|jQuery} A true or false value, whether the category is open
*/
function isOpen(category) {
return $('#' + category + ' h5 i').hasClass('active-icon');
}
/**
* Opens a category, ensures the icon is active and scrolls to the icon
*
* @param category The id of a category as a string
*/
function openCategory(category) {
// Close all active categories
$('.category h5 i').removeClass('active-icon');
$('.website-table').css('display', 'none');
// Place the category being viewed in the URL bar
window.location.hash = category;
var icon = $('#' + category + ' h5 i');
icon.addClass('active-icon');
if ($(window).width() > 768) {
$('#' + category + '-desktoptable').css('display', 'block');
} else {
$('#' + category + '-mobiletable').css('display', 'block');
}
// Scroll smoothly to category selector
$('html, body').animate({
scrollTop: icon.offset().top - 25
}, 1000);
}
/**
* Closes a category and ensures the icon is inactive
*
* @param category The id of a category as a string
*/
function closeCategory(category) {
$('#' + category + ' h5 i').removeClass('active-icon');
$('.' + category + '-table').css('display', 'none');
document.location.hash = '';
}
/**
* Returns a function, that, as long as it continues to be invoked, will not
* be triggered. The function will be called after it stops being called for
* N milliseconds.
*
* @param func The function to be debounced
* @param wait The time in ms to debounce
*/
function debounce(func, wait) {
var timeout;
return function() {
var context = this, args = arguments;
var later = function() {
timeout = null;
func.apply(context, args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (!timeout) func.apply(context, args);
};
};

File diff suppressed because one or more lines are too long

@ -0,0 +1,55 @@
$(document).ready(function () {
// Lazy load images
const lazyLoadInstance = new LazyLoad({ elements_selector: ".lazyload" });
// Show popup notice
$('.exception').popup({ position: 'right center', hoverable: true, title: 'Exceptions & Restrictions' });
// Register service worker
if ('serviceWorker' in navigator) navigator.serviceWorker.register('/service-worker.js');
// Show category of query
const query = window.location.hash;
if (query && query.indexOf('#') > -1) {
// Remove all tables before showing the correct one
$('.collapse').collapse('hide');
showCategory(query.substring(1));
}
});
// On category click
$('.cat').click(function () {
let query = window.location.hash;
// Collapse all other tables.
$('.collapse').collapse('hide');
$('.cat').removeClass('active');
// Check if category tables are displayed
if (!$(`#${query.substring(1)}-table`).hasClass('collapsing') && !$(`#${query.substring(1)}-mobile-table`).hasClass('collapsing') || query.substring(1) !== this.id) {
window.location.hash = this.id;
showCategory(this.id);
} else {
// Remove #category in URL
history.pushState("", document.title, window.location.pathname + window.location.search);
}
});
// Show desktop & mobile tables
function showCategory(category) {
$(`#${category}-table`).collapse("show");
$(`#${category}-mobile-table`).collapse("show");
$(`#${category}`).addClass('active');
}
let resizeObserver = new ResizeObserver(() => {
// Fix the footer to bottom of viewport if body is less than viewport
if($('body').height() < $(window).height()){
$('.footer').css({position: 'absolute'});
}else{
$('.footer').css({position: 'static'});
}
});
resizeObserver.observe($('body')[0]);

File diff suppressed because one or more lines are too long

@ -0,0 +1,89 @@
$(document).ready(function () {
var jets = new Jets({
searchTag: '#innerSearchBox',
contentTag: '.searchContainer',
didSearch: function (search_phrase) {
document.location.hash = '';
if (search_phrase == '') {
// Empty search value
// Display everything. Close tables
$('.cat').show();
$('.cat').removeClass('active');
$('.category-table').removeClass('show');
$('.search-table-title').hide();
$('#no-results').hide();
} else {
// Populated search field
// Hide category icons
$('.cat').hide();
// Display all category tables
$('.category-table').addClass('show');
// Go through each table
$('tbody').each(function (i) {
// If tbody contains a visible table-*
if ($(this).find('tr.table-success:visible').length > 0 || $(this).find('tr.table-danger:visible').length > 0) {
$(this).parent().parent().addClass('show');
} else {
// Hide all tables not containing a visible tr
$(this).parent().parent().removeClass('show');
}
});
$('.searchContainer.mobile-only').each(function(i){
if($(this).find('div.table-success:visible').length > 0 || $(this).find('div.table-danger:visible').length > 0){
$(this).find('.search-table-title').show();
}else{
$(this).find('.search-table-title').hide();
}
});
if ($('.searchContainer').find(':visible').length == 0){
$('#no-results').show();
}else{
$('#no-results').hide();
}
}
},
// Process searchable elements manually
manualContentHandling: function(tag){
return $(tag).find('.searchWords').text();
}
});
});
// Wrap the jets.search function with a debounced function
var debouncedSearch = debounce(function(e) {
jets.search(e.target.value);
}, 350);
// Attach a keyup event listener to the input
$('#jets-search').keyup(debouncedSearch);
/**
* Returns a function, that, as long as it continues to be invoked, will not
* be triggered. The function will be called after it stops being called for
* N milliseconds.
*
* @param func The function to be debounced
* @param wait The time in ms to debounce
*/
function debounce(func, wait) {
var timeout;
return function() {
var context = this, args = arguments;
var later = function() {
timeout = null;
func.apply(context, args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (!timeout) func.apply(context, args);
};
};

@ -0,0 +1,31 @@
---
---
$('.facebook-button').click(function () {
window.open("https://facebook.com/" + $(this).data('facebook'), '_blank');
})
$('.email-button').click(function () {
let langs = new Map();
{% for lang in site.data.languages %}
langs.set("{{ lang[0] }}", "{{ lang[1].email_subject }}");
{% endfor %}
let lang = $(this).data('lang') // TODO: See lang in function below
if (!langs.has(lang)) lang = "en"
window.open('mailto:' + $(this).data('email') + '?subject=' + langs.get(lang))
})
$('.twitter-button').click(function () {
let langs = new Map();
{% for lang in site.data.languages %}
langs.set("{{ lang[0] }}", "{{ lang[1].tweet |cgi_escape }}");
{% endfor %}
let lang = $(this).data('lang') // TODO: Check if langs contains key of lang value
const handle = $(this).data('twitter')
if (!langs.has(lang)) lang = "en"
const text = langs.get(lang).replace('TWITTERHANDLE', handle)
window.open('https://twitter.com/share?url={{site.url | cgi_escape}}&amp;hashtags=SupportTwoFactorAuth&amp;text=' + text, '_blank');
})

@ -0,0 +1,47 @@
---
---
{
"name": "{{site.title}}",
"short_name": "{{ site.title }}",
"start_url": "/",
"display": "standalone",
"description": "{{ site.description }}",
"theme_color": "{{ site.theme_color }}",
"background_color": "#FFFFFF",
"orientation": "portrait-primary",
"icons": [
{
"src": "/img/icons/icon_180x180.png",
"type": "image/png",
"sizes": "180x180"
},
{
"src": "/img/icons/apple-icon_180x180.png",
"type": "image/png",
"sizes": "180x180",
"purpose": "maskable"
},
{
"src": "/img/icons/icon_192x192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "/img/icons/apple-icon_192x192.png",
"type": "image/png",
"sizes": "192x192",
"purpose": "maskable"
},
{
"src": "/img/icons/icon_512x512.png",
"type": "image/png",
"sizes": "512x512"
},
{
"src": "/img/icons/apple-icon_512x512.png",
"type": "image/png",
"sizes": "512x512",
"purpose": "maskable"
}
]
}

@ -0,0 +1,13 @@
---
layout: default
---
<ul>
{% for page in site.pages %}
{% assign array = page.url | split: "/" %}
{% if array[1] == "notes" and array.size > 2 %}
<li>
<a href="{{ page.url }}">{{page.title}}</a>
</li>
{% endif %}
{% endfor %}
</ul>

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save