Compare commits
235 Commits
improvedas
...
auth-v3.0.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
48d9ac63bb | ||
|
|
887066962f | ||
|
|
cb2615b083 | ||
|
|
de459e68eb | ||
|
|
9cc559870c | ||
|
|
395774c0e4 | ||
|
|
b3a7aebf95 | ||
|
|
0e0761bac7 | ||
|
|
79d7fe18ea | ||
|
|
48155692ff | ||
|
|
b931825d3b | ||
|
|
2dc9b015a6 | ||
|
|
32c2456f03 | ||
|
|
084027df31 | ||
|
|
852878e3f4 | ||
|
|
f07e88b2dc | ||
|
|
d2e526769d | ||
|
|
867fdb7e2c | ||
|
|
a830b771f8 | ||
|
|
cc21f1a36d | ||
|
|
9ff8469a54 | ||
|
|
cfafcf8278 | ||
|
|
1829bcfdcf | ||
|
|
608fec9129 | ||
|
|
f5c9fa3d6c | ||
|
|
4a21ee0fa9 | ||
|
|
da853fdfde | ||
|
|
f2928c8ab8 | ||
|
|
d34bcffafd | ||
|
|
67028a072c | ||
|
|
2bbf33287b | ||
|
|
e60df5c54a | ||
|
|
b100392d7e | ||
|
|
b2154429f3 | ||
|
|
e9f10f77d9 | ||
|
|
1d3452a1f0 | ||
|
|
4e9ff3024c | ||
|
|
c193377640 | ||
|
|
6f4b20ad6f | ||
|
|
ee86de6b30 | ||
|
|
7930e95f4a | ||
|
|
2c3f82023c | ||
|
|
1f6c5d9782 | ||
|
|
b4640935a8 | ||
|
|
e64ef1a7d8 | ||
|
|
346e205001 | ||
|
|
8193379fad | ||
|
|
d3b589e622 | ||
|
|
ec68a11ec3 | ||
|
|
ca949ac077 | ||
|
|
54092c8fba | ||
|
|
4b3f5e4cca | ||
|
|
aebe483d80 | ||
|
|
ea5cd4a7d0 | ||
|
|
15a745266d | ||
|
|
fdde16e76c | ||
|
|
39adba94dd | ||
|
|
ef33065c5b | ||
|
|
dab15b2429 | ||
|
|
c0367729a7 | ||
|
|
fa3d3bceed | ||
|
|
26051985d5 | ||
|
|
fe2f30a92c | ||
|
|
af3f2280d6 | ||
|
|
d513019e1b | ||
|
|
c611d43204 | ||
|
|
cd76da836d | ||
|
|
9086d37a7c | ||
|
|
7234aef6c7 | ||
|
|
20a4e78998 | ||
|
|
280fa9a171 | ||
|
|
13e0cf1826 | ||
|
|
498e651d6d | ||
|
|
66d58d1538 | ||
|
|
27f95e433a | ||
|
|
9053717699 | ||
|
|
82b6187e26 | ||
|
|
b7bf4e7015 | ||
|
|
fbd572f23a | ||
|
|
92d017a701 | ||
|
|
422adf0a62 | ||
|
|
f85a1da9c2 | ||
|
|
afffcec3f2 | ||
|
|
77715e4d05 | ||
|
|
34eb9d7fba | ||
|
|
01c3308019 | ||
|
|
2f699365fb | ||
|
|
622c4e7258 | ||
|
|
68003e203b | ||
|
|
b273ac3cf0 | ||
|
|
3d46b015e1 | ||
|
|
523317eb71 | ||
|
|
4ce913cda6 | ||
|
|
7fdf52309a | ||
|
|
186981014e | ||
|
|
0bde1ab22d | ||
|
|
b2f9c6ff6b | ||
|
|
6aa810b500 | ||
|
|
cf4d407f39 | ||
|
|
ac05f085c1 | ||
|
|
7e48953b6a | ||
|
|
6f4bb6bf95 | ||
|
|
0666fc0ac2 | ||
|
|
6f304cb7a1 | ||
|
|
30c368d99f | ||
|
|
adaa81f50c | ||
|
|
c8a5ca41a2 | ||
|
|
dce84c4262 | ||
|
|
f529460eda | ||
|
|
ae170acb30 | ||
|
|
bfca0730b2 | ||
|
|
c95260a228 | ||
|
|
da43e27688 | ||
|
|
2e442c2152 | ||
|
|
d15d2437fb | ||
|
|
860ca9852b | ||
|
|
eb8ce32acb | ||
|
|
05327bb028 | ||
|
|
47a965f0a1 | ||
|
|
f7a500b811 | ||
|
|
0ce25916e6 | ||
|
|
504bae5dd8 | ||
|
|
8bb748ae22 | ||
|
|
e5bc7b218d | ||
|
|
29ea968408 | ||
|
|
07cd9be3f4 | ||
|
|
946605554c | ||
|
|
2b00418695 | ||
|
|
1a43c0feb2 | ||
|
|
309d3321b9 | ||
|
|
25f2fc46a9 | ||
|
|
48fc966457 | ||
|
|
d2fd7dea97 | ||
|
|
a2e93489f2 | ||
|
|
5150dc00e1 | ||
|
|
68ebd1ef69 | ||
|
|
1d1fa29239 | ||
|
|
04b3e0c7fb | ||
|
|
624a8bf6a9 | ||
|
|
2bebd2ead7 | ||
|
|
e7deb0fb94 | ||
|
|
d37cb971aa | ||
|
|
4470e039eb | ||
|
|
564222b3f0 | ||
|
|
2e1c5d7684 | ||
|
|
b5e3bf8d4b | ||
|
|
fbff908c90 | ||
|
|
3cb9b12f26 | ||
|
|
c4d5bc5aa7 | ||
|
|
237fc3cdb1 | ||
|
|
96386e8f9e | ||
|
|
8df19efc1a | ||
|
|
a0f7c6f302 | ||
|
|
fdef3dc439 | ||
|
|
3285ccdb3a | ||
|
|
a27da1de31 | ||
|
|
d6885d66c3 | ||
|
|
15b2b05487 | ||
|
|
03c4d42a03 | ||
|
|
621d58ec0e | ||
|
|
e51f9f1e08 | ||
|
|
3517050c23 | ||
|
|
4561c8f85c | ||
|
|
48d0e250c6 | ||
|
|
632224b94c | ||
|
|
8ecb88cbb4 | ||
|
|
330600543e | ||
|
|
4a9fe006d5 | ||
|
|
e50ae02dbb | ||
|
|
bc7075f81a | ||
|
|
f8d2fda602 | ||
|
|
896d7402b4 | ||
|
|
55a16d053a | ||
|
|
9a1254b745 | ||
|
|
afe5809cb2 | ||
|
|
d6c4d5f87f | ||
|
|
9de5f01727 | ||
|
|
4569ae01df | ||
|
|
896001100c | ||
|
|
332c8d9695 | ||
|
|
6df8a2204f | ||
|
|
4a16fa8701 | ||
|
|
92dc6cacfa | ||
|
|
b40419bcea | ||
|
|
f84b2b5ad3 | ||
|
|
2da32c3193 | ||
|
|
3011248017 | ||
|
|
54be100830 | ||
|
|
c37b6e0441 | ||
|
|
c113e09204 | ||
|
|
19f93087db | ||
|
|
3f736e82ae | ||
|
|
4f6e97eafd | ||
|
|
8c75a2324c | ||
|
|
91a4b1143f | ||
|
|
79b37f16f5 | ||
|
|
e45792ad09 | ||
|
|
00769bdd7a | ||
|
|
89f58236fc | ||
|
|
eca48a4cc3 | ||
|
|
fe324c3124 | ||
|
|
c0ac43b6c8 | ||
|
|
af60ae46c1 | ||
|
|
d47287095d | ||
|
|
b9d4f9ff10 | ||
|
|
fc826e8acb | ||
|
|
f6377b98cb | ||
|
|
b8c6a67faa | ||
|
|
e18c79c895 | ||
|
|
f9c6151482 | ||
|
|
fb28b4ca28 | ||
|
|
a10f278d44 | ||
|
|
9c1ae27a21 | ||
|
|
37fa4ba7b6 | ||
|
|
6bd307a2cd | ||
|
|
2b34cfc688 | ||
|
|
bb957685b3 | ||
|
|
445f8c4635 | ||
|
|
f2bb1430fe | ||
|
|
eddb774b19 | ||
|
|
fabd6351d9 | ||
|
|
637f3522a9 | ||
|
|
5dda37a192 | ||
|
|
6b3c9ee19c | ||
|
|
a3ebd4c062 | ||
|
|
3d3588e64e | ||
|
|
017cb7eb96 | ||
|
|
bf36f415db | ||
|
|
24ea4374cf | ||
|
|
33656c8206 | ||
|
|
5448ca116c | ||
|
|
bfa652df36 | ||
|
|
fae54faffc | ||
|
|
d4f781bf35 | ||
|
|
9c4e72aa0f |
2
.github/workflows/auth-lint.yml
vendored
@@ -9,7 +9,7 @@ on:
|
||||
- ".github/workflows/auth-lint.yml"
|
||||
|
||||
env:
|
||||
FLUTTER_VERSION: "3.19.3"
|
||||
FLUTTER_VERSION: "3.22.2"
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
|
||||
2
.github/workflows/auth-release.yml
vendored
@@ -29,7 +29,7 @@ on:
|
||||
- "auth-v*"
|
||||
|
||||
env:
|
||||
FLUTTER_VERSION: "3.19.3"
|
||||
FLUTTER_VERSION: "3.22.2"
|
||||
|
||||
jobs:
|
||||
build-ubuntu:
|
||||
|
||||
@@ -4,7 +4,7 @@ on:
|
||||
workflow_dispatch: # Allow manually running the action
|
||||
|
||||
env:
|
||||
FLUTTER_VERSION: "3.22.1"
|
||||
FLUTTER_VERSION: "3.22.2"
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
2
.github/workflows/mobile-lint.yml
vendored
@@ -10,7 +10,7 @@ on:
|
||||
|
||||
env:
|
||||
|
||||
FLUTTER_VERSION: "3.22.1"
|
||||
FLUTTER_VERSION: "3.22.2"
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
|
||||
2
.github/workflows/mobile-release.yml
vendored
@@ -9,7 +9,7 @@ on:
|
||||
- "photos-v*"
|
||||
|
||||
env:
|
||||
FLUTTER_VERSION: "3.22.1"
|
||||
FLUTTER_VERSION: "3.22.2"
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
71
SECURITY.md
@@ -1,51 +1,54 @@
|
||||
# Security Policy
|
||||
|
||||
Ente believes that working with security researchers across the globe is crucial
|
||||
to keeping our users safe. If you believe you've found a security issue in our
|
||||
product or service, we encourage you to notify us, by email (security@ente.io)
|
||||
or by [filling this
|
||||
form](https://github.com/ente-io/ente/security/advisories/new) We welcome
|
||||
working with you to resolve the issue promptly. Thanks in advance!
|
||||
product or service, we encourage you to notify us by email at security@ente.io
|
||||
or by
|
||||
[filling out this form](https://github.com/ente-io/ente/security/advisories/new).
|
||||
We welcome working with you to resolve the issue promptly. Thanks in advance!
|
||||
|
||||
## Disclosure Policy
|
||||
|
||||
- Let us know as soon as possible upon discovery of a potential security issue,
|
||||
and we'll make every effort to quickly resolve the issue.
|
||||
- Provide us a reasonable amount of time to resolve the issue before any
|
||||
disclosure to the public or a third-party. We may publicly disclose the issue
|
||||
before resolving it, if appropriate.
|
||||
- Make a good faith effort to avoid privacy violations, destruction of data, and
|
||||
interruption or degradation of our service. Only interact with accounts you
|
||||
own or with explicit permission of the account holder.
|
||||
- If you would like to encrypt your report, please use the PGP key with long ID
|
||||
`E273695C0403F34F74171932DF6DDDE98EBD2394` (available in the public keyserver
|
||||
pool).
|
||||
- Let us know as soon as possible upon discovery of a potential security
|
||||
issue, and we'll make every effort to quickly resolve the issue.
|
||||
- Provide us with a reasonable amount of time to resolve the issue before any
|
||||
disclosure to the public or a third party. We may publicly disclose the
|
||||
issue before resolving it if appropriate.
|
||||
- Make a good faith effort to avoid privacy violations, destruction of data,
|
||||
and interruption or degradation of our service. Only interact with accounts
|
||||
you own or with the explicit permission of the account holder.
|
||||
- If you would like to encrypt your report, please use the PGP key with long
|
||||
ID `E273695C0403F34F74171932DF6DDDE98EBD2394` (available in the public
|
||||
keyserver pool).
|
||||
|
||||
## In-scope
|
||||
|
||||
- Security issues in any current release of Ente's services. Product downloads
|
||||
are available at https://ente.io. Source code is available at
|
||||
https://github.com/ente-io.
|
||||
- Security issues in any current release of Ente's services. Product downloads
|
||||
are available at [https://ente.io](https://ente.io). Source code is
|
||||
available at [https://github.com/ente-io](https://github.com/ente-io).
|
||||
|
||||
## Exclusions
|
||||
|
||||
The following bug classes are out-of scope:
|
||||
The following bug classes are out of scope:
|
||||
|
||||
- Bugs that are already reported on any of [Ente's issue
|
||||
trackers](https://github.com/ente-io), or that we already know of (Note that
|
||||
some of our issue tracking is private)
|
||||
- Issues in an upstream software dependency (ex: Flutter, Next.js etc) which are
|
||||
already reported to the upstream maintainer
|
||||
- Attacks requiring physical access to a user's device
|
||||
- Self-XSS
|
||||
- Issues related to software or protocols not under ente's control
|
||||
- Vulnerabilities in outdated versions of ente
|
||||
- Missing security best practices that do not directly lead to a vulnerability
|
||||
- Issues that do not have any impact on the general public
|
||||
- Bugs that are already reported on any of
|
||||
[Ente's issue trackers](https://github.com/ente-io) or that we already know
|
||||
of (note that some of our issue tracking is private).
|
||||
- Issues in an upstream software dependency (e.g., Flutter, Next.js, etc.)
|
||||
that are already reported to the upstream maintainer.
|
||||
- Attacks requiring physical access to a user's device.
|
||||
- Self-XSS.
|
||||
- Issues related to software or protocols not under Ente's control.
|
||||
- Vulnerabilities in outdated versions of Ente.
|
||||
- Missing security best practices that do not directly lead to a
|
||||
vulnerability.
|
||||
- Issues that do not have any impact on the general public.
|
||||
|
||||
While researching, we'd like to ask you to refrain from:
|
||||
|
||||
- Denial of service
|
||||
- Spamming
|
||||
- Social engineering (including phishing) of Ente staff or contractors
|
||||
- Any physical attempts against Ente property or data centers
|
||||
- Denial of service
|
||||
- Spamming
|
||||
- Social engineering (including phishing) of Ente staff or contractors
|
||||
- Any physical attempts against Ente property or data centers
|
||||
|
||||
Thank you for helping keep Ente and our users safe!
|
||||
|
||||
@@ -2,4 +2,5 @@
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@drawable/ic_launcher_background"/>
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
|
||||
<monochrome android:drawable="@drawable/ic_launcher_foreground"/>
|
||||
</adaptive-icon>
|
||||
|
||||
@@ -23,6 +23,12 @@
|
||||
{
|
||||
"title": "BitMEX"
|
||||
},
|
||||
{
|
||||
"title": "BitSkins"
|
||||
},
|
||||
{
|
||||
"title": "Bitstamp"
|
||||
},
|
||||
{
|
||||
"title": "Bitvavo",
|
||||
"hex": "0051FF"
|
||||
@@ -50,6 +56,9 @@
|
||||
{
|
||||
"title": "CERN"
|
||||
},
|
||||
{
|
||||
"title": "ChangeNOW"
|
||||
},
|
||||
{
|
||||
"title": "Channel Island Hosting",
|
||||
"slug": "cih",
|
||||
@@ -83,6 +92,9 @@
|
||||
{
|
||||
"title": "Discourse"
|
||||
},
|
||||
{
|
||||
"title": "DMarket"
|
||||
},
|
||||
{
|
||||
"title": "Doppler"
|
||||
},
|
||||
@@ -154,6 +166,10 @@
|
||||
{
|
||||
"title": "INWX"
|
||||
},
|
||||
{
|
||||
"title": "Itch.io",
|
||||
"slug": "itch_io"
|
||||
},
|
||||
{
|
||||
"title": "IVPN",
|
||||
"slug": "IVPN"
|
||||
@@ -202,6 +218,10 @@
|
||||
"slug": "local_wp",
|
||||
"altNames": ["LocalWP", "Local WP", "Local Wordpress"]
|
||||
},
|
||||
{
|
||||
"title": "Marketplace.tf",
|
||||
"slug": "marketplacedottf"
|
||||
},
|
||||
{
|
||||
"title": "Mastodon",
|
||||
"altNames": ["mstdn", "fediscience", "mathstodon", "fosstodon"],
|
||||
@@ -216,6 +236,9 @@
|
||||
{
|
||||
"title": "Microsoft"
|
||||
},
|
||||
{
|
||||
"title": "Migros"
|
||||
},
|
||||
{
|
||||
"title": "Mintos"
|
||||
},
|
||||
@@ -231,6 +254,10 @@
|
||||
"title": "MyFRITZ!Net",
|
||||
"slug": "myfritz"
|
||||
},
|
||||
{
|
||||
"title": "Name.com",
|
||||
"slug": "name_com"
|
||||
},
|
||||
{
|
||||
"title": "NextDNS"
|
||||
},
|
||||
@@ -341,6 +368,9 @@
|
||||
"title": "Skiff",
|
||||
"hex": "EF5A3C"
|
||||
},
|
||||
{
|
||||
"title": "Skinport"
|
||||
},
|
||||
{
|
||||
"title": "Snapchat"
|
||||
},
|
||||
@@ -397,6 +427,10 @@
|
||||
"title": "Ubisoft",
|
||||
"hex": "4285f4"
|
||||
},
|
||||
{
|
||||
"title": "Ubuntu One",
|
||||
"slug": "ubuntu_one"
|
||||
},
|
||||
{
|
||||
"title": "Unity",
|
||||
"hex": "858585"
|
||||
@@ -423,9 +457,7 @@
|
||||
{
|
||||
"title": "WorkOS",
|
||||
"slug": "workos",
|
||||
"altNames": [
|
||||
"Work OS"
|
||||
]
|
||||
"altNames": ["Work OS"]
|
||||
},
|
||||
{
|
||||
"title": "X",
|
||||
|
||||
3
auth/assets/custom-icons/icons/bitskins.svg
Normal file
|
After Width: | Height: | Size: 19 KiB |
28
auth/assets/custom-icons/icons/bitstamp.svg
Executable file
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 19.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="layer" xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 652 652" style="enable-background:new 0 0 652 652;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#003B2F;}
|
||||
</style>
|
||||
<path class="st0" d="M108.8,331.4c0-11.4-6.6-20.5-17.3-24.2c8.1-3.7,13.7-11.4,13.7-21.3c0-15.5-13-26.3-31.5-26.3H21v13.2
|
||||
c8.3,0,15,6.7,15,15s-6.7,15-15,15v11.9c8.3,0,15,6.7,15,15s-6.7,15-15,15V359h55c18.9,0,32.6-11.2,32.6-27.5 M49.3,273.9H71
|
||||
c8.9,0,15.2,5.8,15.2,13.9s-6.3,13.7-15.2,13.7H49.3C49.3,301.5,49.3,273.9,49.3,273.9z M49.3,344.5v-30H73
|
||||
c9.8,0,16.4,6.1,16.4,14.9s-6.6,15.1-16.4,15.1C73,344.5,49.3,344.5,49.3,344.5z M130.2,254.4c6.6,0,11.4,4.7,11.4,11.4
|
||||
s-4.7,11.4-11.4,11.4c-6.6,0-11.2-4.7-11.2-11.4S123.7,254.4,130.2,254.4 M120.7,286.5h18.9v72.4h-18.9V286.5L120.7,286.5z
|
||||
M176.2,286.4h20.1v14.4h-20.1v34.6c0,5.5,4.4,10.1,9.9,10.2c2.9,0,6.1-0.4,9.6-1.3l2.5,14.2c-5.8,1.5-11.2,2.2-16.4,2.2
|
||||
c-14.5,0-24.6-9.5-24.6-23.4v-67.4c0-2.6,2.1-4.7,4.7-4.7h14.2V286.4L176.2,286.4z M234.6,284.7c8.4,0,17.4,1.7,26.6,5l-4.1,13.6
|
||||
c-7.3-2.8-14.5-4.6-21-4.6c-6.5,0-11.2,3.1-11.2,7.8c0,13.1,38.7,3.6,38.7,31.6c0,13.2-11.9,22.5-29,22.5c-8.9,0-18.6-2-28.8-5.8
|
||||
l4-13.5c8.4,3.4,16.4,5.2,23.4,5.2c7,0,11.9-3.4,11.9-8.4c0-13.7-38.6-4.1-38.6-31.6c0-12.7,11.5-21.9,28.3-21.9 M293.7,286.4h20.1
|
||||
v14.4h-20.1v34.6c0,5.5,4.4,10.1,9.9,10.2c2.9,0,6.1-0.4,9.6-1.3l2.5,14.2c-5.8,1.5-11.2,2.2-16.4,2.2c-14.5,0-24.6-9.5-24.6-23.4
|
||||
v-67.4c0-2.7,2.2-4.7,4.7-4.7h14.2V286.4z M413.8,286.4h15.1l2.4,9.9c5.8-7.5,14.2-11.6,23.8-11.6c10.5,0,19,5,23.2,13.3
|
||||
c6.6-8.6,15.7-13.3,26.2-13.3c15.8,0,27.1,11,27.1,26.4v47.7h-18.9v-44.8c0-8.1-5.8-13.9-14-13.9c-9.6,0-16.4,7.3-16.4,17.6v41.1
|
||||
h-18.9v-44.8c0-8.1-5.8-13.9-13.9-13.9c-9.8,0-16.5,7.3-16.5,17.6v41.1h-18.9v-72.4H413.8z M547.1,286.4h15.1l2.4,9.3
|
||||
c5.3-7.1,13.6-11.1,23.2-11.1c19.5,0,33.3,15.7,33.3,38c0,22.3-13.7,37.9-33.3,37.9c-8.9,0-16.5-3.6-21.8-10v32.2
|
||||
c0,2.6-2.1,4.7-4.7,4.7H547L547.1,286.4L547.1,286.4z M582.8,299.6c-10,0-17.2,7.5-17.2,18.2v9.8c0,10.5,7.1,18.2,17.2,18.2
|
||||
c11.1,0,18.9-9.6,18.9-23C601.8,309.4,593.9,299.7,582.8,299.6 M378.1,327.5c0,10.5-7.1,18.2-17.2,18.2c-11.1,0-18.9-9.6-18.9-23
|
||||
c0-13.4,7.8-23.1,18.9-23.1c10,0,17.2,7.5,17.2,18.2V327.5L378.1,327.5z M396.7,323.3L396.7,323.3v-36.9h-15.1l-2.4,9.3
|
||||
c-5.3-7.1-13.6-11.1-23.2-11.1c-19.5,0-33.3,15.7-33.3,38c0,22.3,13.7,37.9,33.3,37.9c1.1,0,2.2,0,3.3-0.2
|
||||
c8.2-0.8,15.1-4.7,19.9-10.9l2.4,9.3h15.1L396.7,323.3L396.7,323.3z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
15
auth/assets/custom-icons/icons/changenow.svg
Normal file
|
After Width: | Height: | Size: 9.8 KiB |
1
auth/assets/custom-icons/icons/dmarket.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 2000 1948.02"><defs><style>.cls-1,.cls-2{opacity:0.25;isolation:isolate;}.cls-1{fill:url(#linear-gradient);}.cls-2{fill:url(#linear-gradient-2);}.cls-3{fill:url(#linear-gradient-3);}.cls-4{fill:url(#linear-gradient-4);}</style><linearGradient id="linear-gradient" x1="83.62" y1="947.07" x2="878.54" y2="947.07" gradientTransform="matrix(1, 0, 0, -1, 0, 1923)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#00ba96"/><stop offset="0.52" stop-color="#00d9af"/><stop offset="1" stop-color="#00d9af"/></linearGradient><linearGradient id="linear-gradient-2" x1="1144.49" y1="948.99" x2="2001.4" y2="948.99" gradientTransform="matrix(1, 0, 0, -1, 0, 1923)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#008d85"/><stop offset="1" stop-color="#00ffe0"/></linearGradient><linearGradient id="linear-gradient-3" x1="250.91" y1="949" x2="1904.03" y2="949" gradientTransform="matrix(1, 0, 0, -1, 0, 1923)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#008d94"/><stop offset="1" stop-color="#00ffe0"/></linearGradient><linearGradient id="linear-gradient-4" y1="947.06" x2="794.89" y2="947.06" gradientTransform="matrix(1, 0, 0, -1, 0, 1923)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#00ba96"/><stop offset="0.52" stop-color="#00d9af"/><stop offset="1" stop-color="#00faaf"/></linearGradient></defs><title>dmt</title><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><path class="cls-1" d="M857,890.24,625.08,489,389.28,83.76a168.38,168.38,0,0,0-54.57-56.49h-1.95a148.49,148.49,0,0,0-56.52,58.44L100.85,389.6a138.94,138.94,0,0,0,0,140.26L311.32,894.13c15.59,25.32,21.44,54.54,21.44,83.76h0a178.34,178.34,0,0,1-21.44,83.76L102.8,1422a138.94,138.94,0,0,0,0,140.26l175.39,303.89c13.64,23.38,33.13,44.8,56.52,58.44h2c23.39-13.64,40.93-33.12,54.57-56.49l233.86-405.18L857,1057.76A171,171,0,0,0,857,890.24Z"/><path class="cls-2" d="M1975.62,878.55,1741.76,475.31,1502.06,60.39a171.53,171.53,0,0,0-42.87-48.7C1449.44,3.9,1439.69,0,1428,0c-122.78,0-206.58,3.9-268.94,3.9-9.74,0-15.59,11.69-13.64,21.43l60.41,339c0,3.9,0,7.79-1.95,11.69-23.39,42.86-21.44,95.45,3.9,138.31l214.37,374c15.59,27.27,23.39,56.49,23.39,85.71s-7.8,58.44-23.39,85.71l-216.32,374c-25.33,42.86-25.33,95.45-3.9,138.31,2,3.9,2,7.79,2,11.69l-60.41,337c-2,9.74,3.9,21.43,13.64,21.43,56.52,0-23.39,5.84,276.73,5.84,5.85,0,13.64-2,19.49-3.9,21.44-7.79,35.08-33.12,46.77-54.54l239.71-416.87,231.91-403.24c37-58.47,37-130.53,3.9-190.92"/><path class="cls-3" d="M1880.13,890.24,1414.36,83.76C1385.13,33.12,1330.56,0,1270.15,0H338.61c-31.18,0-60.41,9.74-87.7,25.32v1.95a168.38,168.38,0,0,1,54.57,56.49L539.34,489c21.44-9.74,46.77-15.58,70.16-15.58H995.36c60.41,0,115,31.17,144.21,83.76L1332.5,890.24c29.23,50.65,29.23,114.93,0,167.53l-192.93,333.11c-29.23,50.65-85.75,83.76-144.21,83.76H611.44a168.21,168.21,0,0,1-70.16-15.58L307.43,1864.24a168.38,168.38,0,0,1-54.57,56.49v2c25.33,15.58,56.52,25.32,87.7,25.32H1274c60.41,0,115-31.17,144.21-83.76L1884,1057.76c27.31-52.59,27.31-114.93-3.87-167.52"/><path class="cls-4" d="M771.25,890.24,539.34,489,305.48,83.76a168.38,168.38,0,0,0-54.57-56.49H249a148.49,148.49,0,0,0-56.52,58.44L19,387.65a138.94,138.94,0,0,0,0,140.26L229.47,892.18c15.59,25.32,21.44,54.54,21.44,83.76h0a178.34,178.34,0,0,1-21.44,83.76L19,1422a138.94,138.94,0,0,0,0,140.26l175.4,303.92c13.64,23.38,33.13,44.8,56.52,58.44h2c23.39-13.64,40.93-33.12,54.57-56.49L541.3,1463l231.9-401.29C802.43,1005.17,802.43,942.83,771.25,890.24Z"/></g></g></svg>
|
||||
|
After Width: | Height: | Size: 3.5 KiB |
6
auth/assets/custom-icons/icons/itch_io.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="235.452" width="261.728"
|
||||
viewBox="0 0 245.371 220.736">
|
||||
<path
|
||||
d="M31.99 1.365C21.287 7.72.2 31.945 0 38.298v10.516C0 62.144 12.46 73.86 23.773 73.86c13.584 0 24.902-11.258 24.903-24.62 0 13.362 10.93 24.62 24.515 24.62 13.586 0 24.165-11.258 24.165-24.62 0 13.362 11.622 24.62 25.207 24.62h.246c13.586 0 25.208-11.258 25.208-24.62 0 13.362 10.58 24.62 24.164 24.62 13.585 0 24.515-11.258 24.515-24.62 0 13.362 11.32 24.62 24.903 24.62 11.313 0 23.773-11.714 23.773-25.046V38.298c-.2-6.354-21.287-30.58-31.988-36.933C180.118.197 157.056-.005 122.685 0c-34.37.003-81.228.54-90.697 1.365zm65.194 66.217a28.025 28.025 0 0 1-4.78 6.155c-5.128 5.014-12.157 8.122-19.906 8.122a28.482 28.482 0 0 1-19.948-8.126c-1.858-1.82-3.27-3.766-4.563-6.032l-.006.004c-1.292 2.27-3.092 4.215-4.954 6.037a28.5 28.5 0 0 1-19.948 8.12c-.934 0-1.906-.258-2.692-.528-1.092 11.372-1.553 22.24-1.716 30.164l-.002.045c-.02 4.024-.04 7.333-.06 11.93.21 23.86-2.363 77.334 10.52 90.473 19.964 4.655 56.7 6.775 93.555 6.788h.006c36.854-.013 73.59-2.133 93.554-6.788 12.883-13.14 10.31-66.614 10.52-90.474-.022-4.596-.04-7.905-.06-11.93l-.003-.045c-.162-7.926-.623-18.793-1.715-30.165-.786.27-1.757.528-2.692.528a28.5 28.5 0 0 1-19.948-8.12c-1.862-1.822-3.662-3.766-4.955-6.037l-.006-.004c-1.294 2.266-2.705 4.213-4.563 6.032a28.48 28.48 0 0 1-19.947 8.125c-7.748 0-14.778-3.11-19.906-8.123a28.025 28.025 0 0 1-4.78-6.155 27.99 27.99 0 0 1-4.736 6.155 28.49 28.49 0 0 1-19.95 8.124c-.27 0-.54-.012-.81-.02h-.007c-.27.008-.54.02-.813.02a28.49 28.49 0 0 1-19.95-8.123 27.992 27.992 0 0 1-4.736-6.155zm-20.486 26.49l-.002.01h.015c8.113.017 15.32 0 24.25 9.746 7.028-.737 14.372-1.105 21.722-1.094h.006c7.35-.01 14.694.357 21.723 1.094 8.93-9.747 16.137-9.73 24.25-9.746h.014l-.002-.01c3.833 0 19.166 0 29.85 30.007L210 165.244c8.504 30.624-2.723 31.373-16.727 31.4-20.768-.773-32.267-15.855-32.267-30.935-11.496 1.884-24.907 2.826-38.318 2.827h-.006c-13.412 0-26.823-.943-38.318-2.827 0 15.08-11.5 30.162-32.267 30.935-14.004-.027-25.23-.775-16.726-31.4L46.85 124.08C57.534 94.073 72.867 94.073 76.7 94.073zm45.985 23.582v.006c-.02.02-21.863 20.08-25.79 27.215l14.304-.573v12.474c0 .584 5.74.346 11.486.08h.006c5.744.266 11.485.504 11.485-.08v-12.474l14.304.573c-3.928-7.135-25.79-27.215-25.79-27.215v-.006l-.003.002z"
|
||||
color="#000" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
3
auth/assets/custom-icons/icons/marketplacedottf.svg
Normal file
|
After Width: | Height: | Size: 22 KiB |
19
auth/assets/custom-icons/icons/migros.svg
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
<svg
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
version="1.0"
|
||||
width="602.36218"
|
||||
height="139.53543"
|
||||
id="svg3058">
|
||||
<defs
|
||||
id="defs3060" />
|
||||
<g
|
||||
id="layer1">
|
||||
<path
|
||||
d="M 106.369,119.88512 L 106.369,62.018665 L 81.544594,119.88512 L 67.772114,119.88512 L 43.359087,62.018665 L 43.359087,119.88512 L 17.716529,119.88512 L 17.716529,19.650275 L 52.045504,19.650275 L 75.627274,76.245395 L 100.30782,19.650275 L 132.00731,19.650275 L 132.00731,119.88512 L 106.369,119.88512 z M 151.74424,119.88514 L 151.74424,19.650295 L 173.67129,19.650295 C 175.59247,19.650295 177.51259,21.571475 177.51259,23.661675 L 177.51259,119.88514 L 151.74424,119.88514 z M 248.65971,62.160065 L 281.25389,62.160065 C 283.82526,62.160065 285.27873,64.264785 285.27873,66.736595 L 285.27873,118.51459 C 276.11148,120.56404 261.78448,121.82085 251.13365,121.82085 C 213.76593,121.82085 194.05842,104.00581 194.05842,69.633955 C 194.05948,38.962025 213.76593,17.714585 246.61239,17.714585 C 261.08007,17.714585 273.76688,21.571475 281.93349,27.080965 L 271.83223,44.330845 C 264.76546,41.165965 255.25983,38.962025 248.53357,38.962025 C 229.64739,38.962025 220.81534,51.492935 220.81534,69.633955 C 220.81534,89.002025 231.04275,100.96814 249.90412,100.96814 C 253.35105,100.96814 257.64767,100.84093 261.08007,100.30377 L 261.08007,82.644625 L 248.65971,82.644625 L 248.65971,62.160065 z M 342.46983,38.962025 L 329.85459,38.962025 L 329.85459,64.094705 L 342.46983,64.094705 C 349.99971,64.094705 355.91916,60.082975 355.91916,50.546515 C 355.92022,40.883215 349.99865,38.962025 342.46983,38.962025 z M 361.45735,119.88514 L 349.56211,92.294115 C 347.1314,86.671595 345.43451,83.888325 340.27794,83.888325 L 329.85459,83.888325 L 329.85459,119.88514 L 304.66452,119.88514 L 304.66452,23.661675 C 304.66452,21.571475 306.95349,19.650295 308.59192,19.650295 L 344.15113,19.650295 C 363.47597,19.650295 380.04625,23.661675 380.04625,48.611165 C 380.04625,59.785695 373.86247,71.230215 362.26026,73.547185 C 368.0401,75.510535 373.86247,82.913205 377.01176,90.951915 L 388.47046,119.88514 L 361.45735,119.88514 z M 444.16061,38.962025 C 430.64148,38.962025 421.01998,48.611165 421.01998,69.633955 C 421.02105,90.951915 430.64042,100.57341 444.15991,100.57341 C 455.75892,100.57341 465.25215,90.951915 465.25215,69.633955 C 465.25321,48.611165 455.75892,38.962025 444.16061,38.962025 z M 444.16061,121.82085 C 411.34321,121.82085 393.97817,98.638055 393.97817,69.633955 C 393.97817,40.883215 411.34215,17.714585 444.15991,17.714585 C 474.90235,17.714585 492.29396,40.883215 492.29396,69.633955 C 492.29502,98.636985 474.90128,121.82085 444.16061,121.82085 z M 541.64053,121.82085 C 524.689,121.82085 508.94892,115.74656 501.92857,110.91455 L 513.3575,90.655685 C 519.73014,94.512575 532.13207,100.4455 543.56101,100.4455 C 550.03179,100.4455 558.21187,99.202855 558.21187,92.012065 C 558.21187,85.258875 549.07227,83.196315 537.08986,79.762855 C 522.62431,75.623205 505.78439,69.859315 505.78439,50.405135 C 505.7851,29.439745 524.41723,17.714585 548.66337,17.714585 C 564.66778,17.714585 577.07254,23.378915 583.4023,29.439745 L 569.48526,45.277265 C 562.60593,41.165965 555.57104,37.973445 547.68719,37.973445 C 538.19396,37.973445 532.82585,41.576285 532.82585,46.816835 C 532.82691,52.015925 539.70518,54.671985 548.37813,57.285175 C 563.71002,62.018685 584.64565,66.850335 584.64565,86.926005 C 584.64671,107.60829 568.11435,121.82085 541.64053,121.82085 z "
|
||||
style="fill:#f60;fill-opacity:1;fill-rule:evenodd"
|
||||
id="polygon3036" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.6 KiB |
25
auth/assets/custom-icons/icons/name_com.svg
Normal file
@@ -0,0 +1,25 @@
|
||||
<svg enable-background="new 0 0 1510.1 240.3" viewBox="0 0 1510.1 240.3"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="m873.5 203.7c0 16.2-11.9 29.1-28.9 29.1-16.4 0-28.6-12.9-28.6-29.1s12.2-30 28.6-30c17 0 28.9 13.7 28.9 30z"
|
||||
fill="#6eda78" />
|
||||
<g fill="#282828">
|
||||
<path
|
||||
d="m9.7 229v-135.4l38.7-9.4-5.9 43.6h4.2c2.4-10.1 6.2-18.6 11.3-25.7 5.2-7 11.8-12.4 19.8-16 8.2-3.8 17.6-5.7 28.4-5.7 14 0 26.1 3.2 36.3 9.7 10.1 6.3 17.9 15.5 23.3 27.7 5.6 12 8.3 26.3 8.3 43.1v68.1h-38.5v-57.9c0-11.2-1.7-20.7-5.1-28.5-3.4-8-8.4-14-14.9-18-6.5-4.2-14.4-6.3-23.5-6.3-13.7 0-24.4 4.6-32.1 13.7s-11.5 22.1-11.5 39.1v57.9z" />
|
||||
<path clip-rule="evenodd"
|
||||
d="m252.4 232.7c-19.6 0-36.4-3.9-45.7-11.7-9.3-8-14-18.7-14-32.2 0-13.1 4.7-23.6 14-31.4 25.1-21.6 103.6-13.3 108.6-11.6 0-3.3-.2-8.9-3.5-14.4-7.9-13.8-24.3-19.7-39-19.7-12.3 0-25.3 6.1-32.9 15.4-3 3.7-5.5 9.1-5.5 9.1h-36.8c.6-7 4.6-18.4 10.7-27 6-8.7 15.4-16.1 27-21.2 11.8-5.3 20.7-7.6 38-7.6 18 0 31.8 3 43.9 9.1s21.1 14.6 26.9 25.7c5.9 11 8.8 24 8.8 38.8v23.3 52h-37.7l6-30.9h-4.1c-1.9 8.5-5.4 14.9-9.6 19.6-4.3 4.7-9.8 7.6-19.5 10.5-9.5 2.8-21.4 4.2-35.6 4.2zm-23.2-46.4c-2-32.9 77-23.3 86.1-22.2 0 4.8-.3 9.5-1.4 14-5.8 23.3-38.1 28.4-58 26.6-14.5-1.3-26-6.6-26.7-18.4z"
|
||||
fill-rule="evenodd" />
|
||||
<path
|
||||
d="m375.3 94.7v134.3h38.7v-71.9c0-12.2 2.8-21.7 8.3-28.5 5.6-6.8 13.1-10.3 22.5-10.3 6.4 0 11.8 1.5 16.4 4.6 4.7 3 8.3 7.5 10.8 13.4 2.6 5.7 3.9 12.6 3.9 20.8v71.9h38.5v-71.9c0-12.2 2.8-21.7 8.3-28.5 5.7-6.8 13.3-10.3 22.8-10.3 6.4 0 11.8 1.5 16.4 4.6 4.7 3 8.3 7.5 10.8 13.4 2.4 5.7 3.7 12.6 3.7 20.8v71.9h38.7v-82.1c0-14.1-2.2-26-6.6-35.9-4.2-10.1-10.3-17.7-18.1-22.8s-17.1-7.7-27.9-7.7c-13.1 0-23.8 3.5-32.1 10.6-8.2 6.8-14 17.1-17.4 30.8h-3.4c-1.1-7.8-3.8-14.7-7.8-20.8-4.1-6.3-9.6-11.2-16.4-14.8-6.7-3.8-14.7-5.7-24-5.7-12.7 0-23.1 3.4-31.1 10.3-8 6.7-13.7 16.5-17.1 29.7h-4.2l5.1-36.2z" />
|
||||
<path clip-rule="evenodd"
|
||||
d="m718.3 232.7c-18 0-33.4-3.3-46.3-10-12.7-6.8-22.4-16-28.9-27.4-6.5-11.6-9.8-24.5-9.8-38.8s3.3-27.1 9.8-38.5c6.5-11.6 16.2-20.7 29.1-27.4 12.9-6.8 28.4-10.3 46.5-10.3s33.6 3.4 46.3 10.3c12.9 6.7 22.6 15.8 29.2 27.4 6.5 11.6 9.8 24.6 9.8 39.1 0 4-.7 10.2-.7 10.2h-133.4c.9 4.3 2.4 8.3 4.5 12.1 3.8 6.5 9.3 11.6 16.7 15.4 7.5 3.6 16.8 5.4 27.9 5.4 12.6 0 22.2-1.7 28.9-5.1 5.2-2.7 9.5-5.9 13-9.5h39.1c-2.6 6.7-6.7 13.4-12.2 20-6.4 7.6-15.4 14.1-27.2 19.4-11.5 5.2-25.6 7.7-42.3 7.7zm-43.8-98.3c-1.4 2.4-2.9 6.1-3.4 8.8h47.6 47.6c-.6-2.7-2-6.4-3.4-8.8-3.8-6.7-9.3-11.8-16.7-15.4-7.3-3.8-16.5-5.7-27.4-5.7-11.1 0-20.3 1.9-27.7 5.7-7.3 3.6-12.9 8.7-16.6 15.4z"
|
||||
fill-rule="evenodd" />
|
||||
<path
|
||||
d="m896.2 195.4c6.5 11.4 16.1 20.5 28.7 27.4 12.7 6.7 28.1 10 46.1 10 16 0 30.1-2.8 42.4-8.3 12.2-5.5 22-13.2 29.2-23.1s11.4-21.1 12.7-33.6h-38.7c-1.5 8.4-6.1 15.4-14 21.1-7.8 5.7-18.4 8.6-31.6 8.6-9.8 0-18.1-1.8-25-5.4-6.9-3.8-12.1-8.7-15.7-14.8s-5.4-12.9-5.4-20.5c0-7.4 1.8-14.2 5.4-20.2 3.6-6.3 8.8-11.2 15.7-14.8s15.2-5.4 25-5.4c8.8 0 16.5 1.4 23 4.3 6.5 2.7 11.7 6.2 15.4 10.6 3.8 4.4 6.1 9.3 7.1 14.8h38.7c-1.3-12.7-5.6-24-12.7-33.6-7.2-9.9-16.9-17.6-29.2-23.1-12.2-5.7-26.4-8.6-42.4-8.6-18 0-33.3 3.4-46.1 10.3-12.6 6.7-22.1 15.8-28.7 27.4-6.5 11.6-9.8 24.4-9.8 38.5.1 13.9 3.4 26.8 9.9 38.4z" />
|
||||
<path clip-rule="evenodd"
|
||||
d="m1159.2 232.7c-18.6 0-34.5-3.3-47.5-10-13.1-6.8-22.9-16-29.6-27.4-6.5-11.6-9.8-24.5-9.8-38.8s3.3-27.1 9.8-38.5c6.7-11.6 16.6-20.7 29.6-27.4 13.1-6.8 28.9-10.3 47.5-10.3 18.5 0 34.2 3.4 47.3 10.3 13.1 6.7 22.9 15.8 29.4 27.4 6.7 11.4 10 24.2 10 38.5s-3.3 27.2-10 38.8c-6.5 11.4-16.3 20.5-29.4 27.4-13 6.7-28.8 10-47.3 10zm0-35.3c10.3 0 19-1.8 26.2-5.4 7.3-3.6 12.8-8.5 16.4-14.5 3.8-6.1 5.6-13 5.6-20.8 0-7.4-1.9-14.2-5.6-20.2-3.6-6.3-9.1-11.2-16.4-14.8-7.2-3.6-15.9-5.4-26.2-5.4-10.5 0-19.4 1.8-26.7 5.4-7.2 3.6-12.7 8.6-16.4 14.8-3.6 6.1-5.4 12.8-5.4 20.2 0 7.8 1.8 14.7 5.4 20.8 3.8 6.1 9.2 10.9 16.4 14.5 7.4 3.6 16.3 5.4 26.7 5.4z"
|
||||
fill-rule="evenodd" />
|
||||
<path
|
||||
d="m1265.3 93.6v135.4h38.7v-71.9c0-12.2 2.8-21.7 8.3-28.5 5.6-6.8 13.1-10.3 22.5-10.3 6.4 0 11.8 1.5 16.4 4.6 4.7 3 8.3 7.5 10.8 13.4 2.6 5.7 3.9 12.6 3.9 20.8v71.9h38.5v-71.9c0-12.2 2.8-21.7 8.3-28.5 5.7-6.8 13.3-10.3 22.8-10.3 6.4 0 11.8 1.5 16.4 4.6 4.7 3 8.3 7.5 10.8 13.4 2.4 5.7 3.7 12.6 3.7 20.8v71.9h38.7v-82.1c0-14.1-2.2-26-6.6-35.9-4.2-10.1-10.3-17.7-18.1-22.8s-17.1-7.7-27.9-7.7c-13.1 0-23.8 3.5-32.1 10.6-8.2 6.8-14 17.1-17.4 30.8h-3.4c-1.1-7.8-3.8-14.7-7.8-20.8-4.1-6.3-9.6-11.2-16.4-14.8-6.7-3.8-14.7-5.7-24-5.7-12.7 0-23.1 3.4-31.1 10.3-8 6.7-13.7 16.5-17.1 29.7h-4.2l5.1-36.2z" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.5 KiB |
3
auth/assets/custom-icons/icons/skinport.svg
Normal file
|
After Width: | Height: | Size: 34 KiB |
113
auth/assets/custom-icons/icons/ubuntu_one.svg
Normal file
@@ -0,0 +1,113 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
id="svg3039"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.2 r9819"
|
||||
width="240.20215"
|
||||
height="98.041267"
|
||||
sodipodi:docname="U1_logo.svg">
|
||||
<metadata
|
||||
id="metadata3045">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs3043" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1022"
|
||||
inkscape:window-height="529"
|
||||
id="namedview3041"
|
||||
showgrid="false"
|
||||
showguides="true"
|
||||
inkscape:guide-bbox="true"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
inkscape:zoom="3.5580214"
|
||||
inkscape:cx="188.39168"
|
||||
inkscape:cy="46.745142"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="24"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg3039" />
|
||||
<path
|
||||
style="fill:#dd4713;fill-opacity:1;stroke:none"
|
||||
d="m 0,13.135439 0.31287126,55.797305 c 0,0 -0.29397798,23.453759 25.17115774,28.396822 14.646306,2.843004 42.347094,-3.749492 42.347094,-3.749492 l -0.220563,-80.503585 -22.276334,0 0,62.638417 -20.95299,0 0,-41.464863 -9.04287,0 10.586775,-21.394113 z"
|
||||
id="path3049"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccsccccccccc" />
|
||||
<g
|
||||
id="g3898"
|
||||
transform="scale(2.2196062,2.2196062)">
|
||||
<path
|
||||
d="m 47.937238,17.527712 c -0.49137,0.12284 -1.143956,0.253358 -1.95776,0.391552 -0.798468,0.138195 -1.727443,0.207292 -2.786929,0.207293 -0.921305,-10e-7 -1.696731,-0.130518 -2.32628,-0.391552 -0.629558,-0.27639 -1.136272,-0.660264 -1.520143,-1.151624 -0.383877,-0.491358 -0.660267,-1.067169 -0.829169,-1.727435 -0.168907,-0.675616 -0.253359,-1.420332 -0.253358,-2.23415 l 0,-6.7254823 2.14202,0 0,6.2648323 c -3e-6,1.458728 0.230321,2.502865 0.690975,3.132417 0.460644,0.629556 1.23607,0.944333 2.326279,0.944331 0.230318,2e-6 0.46832,-0.0077 0.714007,-0.02303 0.245672,-0.01535 0.475996,-0.03071 0.690974,-0.04606 0.214961,-0.03071 0.406898,-0.05374 0.575812,-0.0691 0.184251,-0.03071 0.314768,-0.06142 0.391552,-0.09213 l 0,-10.1112553 2.14202,0 0,11.6313983"
|
||||
style="font-size:23.03247261px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#dd4713;fill-opacity:1;stroke:none;font-family:Ubuntu;-inkscape-font-specification:Ubuntu"
|
||||
id="path3871"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 53.207382,6.4260606 c 0.26103,-0.1688932 0.652582,-0.3454753 1.174656,-0.5297469 0.537419,-0.1842476 1.151617,-0.2763774 1.842598,-0.2763897 0.859871,1.23e-5 1.619942,0.153562 2.280214,0.4606495 0.67561,0.3071111 1.243743,0.7370502 1.704403,1.2898185 0.460638,0.5527892 0.806125,1.2130528 1.036462,1.9807926 0.245667,0.7677564 0.368507,1.6122804 0.368519,2.5335724 -1.2e-5,0.967368 -0.145884,1.842602 -0.437617,2.625701 -0.276401,0.767752 -0.67563,1.420338 -1.197688,1.957761 -0.52208,0.537425 -1.151634,0.952009 -1.888663,1.243753 -0.737047,0.291745 -1.566215,0.437617 -2.487507,0.437617 -0.998079,0 -1.88099,-0.0691 -2.648734,-0.207292 -0.767752,-0.138195 -1.397306,-0.27639 -1.888663,-0.414585 l 0,-17.15919172 2.14202,-0.36851956283681 0,6.42605988283681 m 0,9.5815084 c 0.214965,0.06142 0.514387,0.122842 0.898266,0.18426 0.399224,0.04607 0.890583,0.0691 1.474078,0.0691 1.151617,2e-6 2.072915,-0.376195 2.763897,-1.128591 0.690965,-0.767745 1.036451,-1.85027 1.036461,-3.247578 -10e-6,-0.614193 -0.06143,-1.190004 -0.184259,-1.727436 C 59.072975,9.619905 58.87336,9.159256 58.59698,8.7753728 58.320582,8.3761528 57.95974,8.0690534 57.514454,7.8540739 57.084507,7.6237594 56.562438,7.5085972 55.948246,7.5085868 c -0.583495,1.04e-5 -1.120919,0.099818 -1.612273,0.2994221 -0.491364,0.1996247 -0.867561,0.4069167 -1.128591,0.6218768 l 0,7.5776833"
|
||||
style="font-size:23.03247261px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#dd4713;fill-opacity:1;stroke:none;font-family:Ubuntu;-inkscape-font-specification:Ubuntu"
|
||||
id="path3873"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 73.905311,17.527712 c -0.49137,0.12284 -1.143957,0.253358 -1.95776,0.391552 -0.798468,0.138195 -1.727443,0.207292 -2.78693,0.207293 -0.921304,-10e-7 -1.69673,-0.130518 -2.326279,-0.391552 -0.629558,-0.27639 -1.136272,-0.660264 -1.520143,-1.151624 -0.383877,-0.491358 -0.660267,-1.067169 -0.829169,-1.727435 -0.168907,-0.675616 -0.253359,-1.420332 -0.253358,-2.23415 l 0,-6.7254823 2.14202,0 0,6.2648323 c -4e-6,1.458728 0.230321,2.502865 0.690974,3.132417 0.460645,0.629556 1.236071,0.944333 2.32628,0.944331 0.230318,2e-6 0.46832,-0.0077 0.714007,-0.02303 0.245672,-0.01535 0.475996,-0.03071 0.690974,-0.04606 0.214961,-0.03071 0.406898,-0.05374 0.575812,-0.0691 0.184251,-0.03071 0.314768,-0.06142 0.391552,-0.09213 l 0,-10.1112553 2.14202,0 0,11.6313983"
|
||||
style="font-size:23.03247261px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#dd4713;fill-opacity:1;stroke:none;font-family:Ubuntu;-inkscape-font-specification:Ubuntu"
|
||||
id="path3875"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 77.314487,6.2418008 c 0.491357,-0.1228281 1.143943,-0.2533453 1.95776,-0.391552 0.81381,-0.1381827 1.750463,-0.2072801 2.809962,-0.2072923 0.952001,1.22e-5 1.742782,0.1382069 2.372345,0.4145845 0.629544,0.2610463 1.128581,0.6372429 1.497111,1.1285912 0.383863,0.4760146 0.652575,1.0518259 0.806136,1.7274354 0.153538,0.6756275 0.230313,1.4203434 0.230325,2.2341494 l 0,6.725482 -2.14202,0 0,-6.264832 c -1e-5,-0.737032 -0.05375,-1.366586 -0.161227,-1.8886628 C 84.59274,9.1976435 84.431512,8.7753819 84.201197,8.4529182 83.970863,8.1304733 83.663764,7.9001488 83.279898,7.761944 82.896016,7.6084044 82.420012,7.5316296 81.851884,7.5316193 c -0.23033,1.03e-5 -0.468332,0.00769 -0.714006,0.023032 -0.245685,0.015365 -0.483687,0.038398 -0.714007,0.069097 -0.214974,0.015365 -0.414589,0.038398 -0.598844,0.069097 -0.168909,0.03072 -0.291749,0.053752 -0.36852,0.069097 l 0,10.1112547 -2.14202,0 0,-11.6313979"
|
||||
style="font-size:23.03247261px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#dd4713;fill-opacity:1;stroke:none;font-family:Ubuntu;-inkscape-font-specification:Ubuntu"
|
||||
id="path3877"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 91.700827,5.8963137 4.537397,0 0,1.7965329 -4.537397,0 0,5.5277934 c -3e-6,0.598848 0.04606,1.097885 0.138195,1.497111 0.09213,0.383877 0.230321,0.690976 0.414585,0.921299 0.184255,0.214971 0.414579,0.368521 0.690974,0.460649 0.276384,0.09213 0.598838,0.138197 0.967364,0.138195 0.644902,2e-6 1.159294,-0.0691 1.543175,-0.207292 0.399222,-0.153548 0.675611,-0.261033 0.829169,-0.322455 l 0.414585,1.7735 c -0.214978,0.107486 -0.591175,0.238003 -1.128591,0.391552 -0.537432,0.168905 -1.15163,0.253357 -1.842598,0.253358 -0.813819,-10e-7 -1.489438,-0.09981 -2.026858,-0.299422 -0.522072,-0.21497 -0.944334,-0.529747 -1.266786,-0.944332 -0.322456,-0.414583 -0.552781,-0.921297 -0.690974,-1.520143 -0.122841,-0.614196 -0.184261,-1.320525 -0.18426,-2.118988 l 0,-10.6870668 2.14202,-0.3685196 0,3.7082281"
|
||||
style="font-size:23.03247261px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#dd4713;fill-opacity:1;stroke:none;font-family:Ubuntu;-inkscape-font-specification:Ubuntu"
|
||||
id="path3879"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 108.21836,17.527712 c -0.49137,0.12284 -1.14395,0.253358 -1.95776,0.391552 -0.79847,0.138195 -1.72744,0.207292 -2.78693,0.207293 -0.9213,-10e-7 -1.69673,-0.130518 -2.32628,-0.391552 -0.62955,-0.27639 -1.13627,-0.660264 -1.52014,-1.151624 -0.383877,-0.491358 -0.660267,-1.067169 -0.829169,-1.727435 -0.168907,-0.675616 -0.253359,-1.420332 -0.253357,-2.23415 l 0,-6.7254823 2.142016,0 0,6.2648323 c 0,1.458728 0.23032,2.502865 0.69098,3.132417 0.46064,0.629556 1.23607,0.944333 2.32628,0.944331 0.23032,2e-6 0.46832,-0.0077 0.714,-0.02303 0.24568,-0.01535 0.476,-0.03071 0.69098,-0.04606 0.21496,-0.03071 0.4069,-0.05374 0.57581,-0.0691 0.18425,-0.03071 0.31477,-0.06142 0.39155,-0.09213 l 0,-10.1112553 2.14202,0 0,11.6313983"
|
||||
style="font-size:23.03247261px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#dd4713;fill-opacity:1;stroke:none;font-family:Ubuntu;-inkscape-font-specification:Ubuntu"
|
||||
id="path3881"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 48.692644,28.027864 c -1.2e-5,0.952013 -0.138207,1.811892 -0.414584,2.579636 -0.276402,0.767752 -0.667953,1.428016 -1.174656,1.980793 -0.49137,0.55278 -1.082536,0.982719 -1.773501,1.289819 -0.690982,0.291744 -1.443376,0.437616 -2.257182,0.437617 -0.81382,-10e-7 -1.566214,-0.145873 -2.257183,-0.437617 -0.690978,-0.3071 -1.289821,-0.737039 -1.796532,-1.289819 -0.491362,-0.552777 -0.875236,-1.213041 -1.151624,-1.980793 -0.276391,-0.767744 -0.414586,-1.627623 -0.414585,-2.579636 -10e-7,-0.936647 0.138194,-1.788848 0.414585,-2.556605 0.276388,-0.783095 0.660262,-1.451036 1.151624,-2.003825 0.506711,-0.552768 1.105554,-0.97503 1.796532,-1.266786 0.690969,-0.307088 1.443363,-0.460637 2.257183,-0.46065 0.813806,1.3e-5 1.5662,0.153562 2.257182,0.46065 0.690965,0.291756 1.282131,0.714018 1.773501,1.266786 0.506703,0.552789 0.898254,1.22073 1.174656,2.003825 0.276377,0.767757 0.414572,1.619958 0.414584,2.556605 m -2.23415,0 c -1e-5,-1.351232 -0.307109,-2.418402 -0.921299,-3.201514 -0.598853,-0.798449 -1.420343,-1.197678 -2.464474,-1.197689 -1.044145,1.1e-5 -1.873313,0.39924 -2.487507,1.197689 -0.598848,0.783112 -0.89827,1.850282 -0.898267,3.201514 -3e-6,1.351243 0.299419,2.42609 0.898267,3.224546 0.614194,0.783106 1.443362,1.174657 2.487507,1.174656 1.044131,10e-7 1.865621,-0.39155 2.464474,-1.174656 0.61419,-0.798456 0.921289,-1.873303 0.921299,-3.224546"
|
||||
style="font-size:23.03247261px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#333333;fill-opacity:1;stroke:none;font-family:Ubuntu;-inkscape-font-specification:Ubuntu"
|
||||
id="path3883"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 51.144189,22.384908 c 0.491357,-0.122828 1.143943,-0.253346 1.95776,-0.391552 0.813809,-0.138183 1.750462,-0.20728 2.809962,-0.207293 0.952001,1.3e-5 1.742782,0.138207 2.372344,0.414585 0.629545,0.261046 1.128581,0.637243 1.497111,1.128591 0.383864,0.476015 0.652576,1.051826 0.806136,1.727436 0.153539,0.675627 0.230314,1.420343 0.230325,2.234149 l 0,6.725482 -2.14202,0 0,-6.264832 c -9e-6,-0.737032 -0.05375,-1.366586 -0.161227,-1.888663 -0.09214,-0.522061 -0.253366,-0.944322 -0.483682,-1.266786 -0.230333,-0.322445 -0.537433,-0.552769 -0.921299,-0.690974 -0.383882,-0.15354 -0.859886,-0.230314 -1.428013,-0.230325 -0.230331,1.1e-5 -0.468333,0.0077 -0.714007,0.02303 -0.245685,0.01536 -0.483687,0.0384 -0.714006,0.0691 -0.214975,0.01536 -0.41459,0.0384 -0.598845,0.0691 -0.168909,0.03072 -0.291748,0.05375 -0.368519,0.0691 l 0,10.111255 -2.14202,0 0,-11.631398"
|
||||
style="font-size:23.03247261px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#333333;fill-opacity:1;stroke:none;font-family:Ubuntu;-inkscape-font-specification:Ubuntu"
|
||||
id="path3885"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 63.139815,28.050896 c -2e-6,-1.059487 0.153548,-1.980785 0.460649,-2.763897 0.307098,-0.798449 0.714004,-1.458713 1.220721,-1.980792 0.506711,-0.522059 1.0902,-0.91361 1.750468,-1.174656 0.660259,-0.261023 1.335877,-0.39154 2.026858,-0.391553 1.612264,1.3e-5 2.848339,0.506727 3.708228,1.520144 0.859867,0.998083 1.289806,2.525902 1.289818,4.583462 -1.2e-5,0.09214 -1.2e-5,0.214975 0,0.368519 -1.2e-5,0.138201 -0.0077,0.268718 -0.02303,0.391552 l -8.199561,0 c 0.09213,1.243758 0.452969,2.188088 1.082527,2.832994 0.629549,0.644912 1.612267,0.967366 2.948156,0.967364 0.752386,2e-6 1.38194,-0.06142 1.888663,-0.184259 0.522059,-0.138193 0.913611,-0.268711 1.174656,-0.391552 l 0.299422,1.796532 c -0.261045,0.138195 -0.721694,0.284068 -1.381948,0.437617 -0.644918,0.15355 -1.381957,0.230325 -2.211118,0.230325 -1.044145,0 -1.950088,-0.15355 -2.717831,-0.460649 -0.752398,-0.322454 -1.374274,-0.760071 -1.865631,-1.312851 -0.491361,-0.552778 -0.85988,-1.205364 -1.105558,-1.95776 -0.230326,-0.767745 -0.345489,-1.604591 -0.345487,-2.51054 m 8.222592,-1.174656 c 0.01535,-0.967356 -0.230334,-1.758137 -0.737039,-2.372345 -0.491367,-0.629544 -1.174663,-0.944321 -2.04989,-0.944331 -0.491365,10e-6 -0.928982,0.09982 -1.312851,0.299422 -0.368524,0.18427 -0.683301,0.429949 -0.944331,0.737039 -0.261039,0.307109 -0.468331,0.660273 -0.621877,1.059494 -0.138198,0.399237 -0.230328,0.806144 -0.27639,1.220721 l 5.942378,0"
|
||||
style="font-size:23.03247261px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#333333;fill-opacity:1;stroke:none;font-family:Ubuntu;-inkscape-font-specification:Ubuntu"
|
||||
id="path3887"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 14 KiB |
@@ -42,3 +42,7 @@ class InvalidStateError extends AssertionError {
|
||||
class SrpSetupNotCompleteError extends Error {}
|
||||
|
||||
class AuthenticatorKeyNotFound extends Error {}
|
||||
|
||||
class PassKeySessionNotVerifiedError extends Error {}
|
||||
|
||||
class PassKeySessionExpiredError extends Error {}
|
||||
|
||||
@@ -269,6 +269,7 @@
|
||||
"privacy": "Privacy",
|
||||
"terms": "Terms",
|
||||
"checkForUpdates": "Check for updates",
|
||||
"checkStatus": "Check status",
|
||||
"downloadUpdate": "Download",
|
||||
"criticalUpdateAvailable": "Critical update available",
|
||||
"updateAvailable": "Update available",
|
||||
@@ -417,6 +418,9 @@
|
||||
"waitingForBrowserRequest": "Waiting for browser request...",
|
||||
"waitingForVerification": "Waiting for verification...",
|
||||
"passkey": "Passkey",
|
||||
"passKeyPendingVerification": "Verification is still pending",
|
||||
"loginSessionExpired" : "Session expired",
|
||||
"loginSessionExpiredDetails": "Your session has expired. Please login again.",
|
||||
"developerSettingsWarning":"Are you sure that you want to modify Developer settings?",
|
||||
"developerSettings": "Developer settings",
|
||||
"serverEndpoint": "Server endpoint",
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
"codeIssuerHint": "Emittente",
|
||||
"codeSecretKeyHint": "Codice segreto",
|
||||
"codeAccountHint": "Account (username@dominio.it)",
|
||||
"codeTagHint": "Tag",
|
||||
"accountKeyType": "Tipo di chiave",
|
||||
"sessionExpired": "Sessione scaduta",
|
||||
"@sessionExpired": {
|
||||
"description": "Title of the dialog when the users current session is invalid/expired"
|
||||
@@ -77,16 +79,19 @@
|
||||
"data": "Dati",
|
||||
"importCodes": "Importa codici",
|
||||
"importTypePlainText": "Testo in chiaro",
|
||||
"importTypeEnteEncrypted": "Esportazione Ente criptata",
|
||||
"passwordForDecryptingExport": "Password per decriptare il file esportato",
|
||||
"passwordEmptyError": "La password è obbligatoria",
|
||||
"importFromApp": "Importa codici da {appName}",
|
||||
"importGoogleAuthGuide": "Esporta i tuoi account da Google Authenticator in un codice QR utilizzando l'opzione \"Trasferisci Account\". Quindi, usando un altro dispositivo, scansiona il codice QR.\n\nSuggerimento: Puoi usare la webcam del tuo computer portatile per scattare una foto del codice QR.",
|
||||
"importSelectJsonFile": "Seleziona file JSON",
|
||||
"importSelectAppExport": "Seleziona il file di esportazione {appName}",
|
||||
"importEnteEncGuide": "Seleziona il file JSON criptato esportato da Ente",
|
||||
"importRaivoGuide": "Utilizza l'opzione \"Esporta i codici OTP in archivio Zip\" nelle impostazioni di Raivo.\n\nEstrai il file zip e importa il file JSON.",
|
||||
"importBitwardenGuide": "Utilizzare l'opzione \"Esporta vault\" all'interno di Bitwarden Tools e importa il file JSON non crittografato.",
|
||||
"importAegisGuide": "Usa l'opzione \"Esporta la cassaforte\" nelle impostazioni di Aegis.\n\nSe la tua cassaforte è criptata, dovrai inserire la password della cassaforte per decriptarla.",
|
||||
"import2FasGuide": "Utilizza l'opzione \"Impostazioni->Backup -Export\" in 2FAS.\n\nSe il backup è crittografato, è necessario inserire la password per decriptare il backup",
|
||||
"importLastpassGuide": "Usa l'opzione \"Trasferisci account\" all'interno delle impostazioni di Lastpass Authenticator e premi \"Esporta account su file\". Importa il JSON scaricato.",
|
||||
"exportCodes": "Esporta codici",
|
||||
"importLabel": "Importa",
|
||||
"importInstruction": "Per favore seleziona un file contenente una lista dei tuoi codici nel seguente formato",
|
||||
@@ -111,18 +116,22 @@
|
||||
"copied": "Copiato",
|
||||
"pleaseTryAgain": "Per favore riprova",
|
||||
"existingUser": "Accedi",
|
||||
"newUser": "Nuovo utente",
|
||||
"delete": "Cancella",
|
||||
"enterYourPasswordHint": "Inserisci la tua password",
|
||||
"forgotPassword": "Password dimenticata",
|
||||
"oops": "Oops",
|
||||
"suggestFeatures": "Suggerisci funzionalità",
|
||||
"faq": "FAQ",
|
||||
"faq_q_1": "Quanto è sicuro Auth?",
|
||||
"faq_a_1": "Tutti i codici di cui fai il backup tramite Auth sono memorizzati con crittografia end-to-end. Ciò significa che solo tu puoi accedere ai tuoi codici. Le nostre app sono open source e la nostra crittografia è stata verificata esternamente.",
|
||||
"faq_q_2": "Posso accedere ai miei codici sul desktop?",
|
||||
"faq_a_2": "Puoi accedere ai tuoi codici sul web @ auth.ente.io.",
|
||||
"faq_q_3": "Come posso cancellare i codici?",
|
||||
"faq_a_3": "Puoi eliminare un codice scorrendo il dito a sinistra sul codice in questione.",
|
||||
"faq_q_4": "Come posso supportare questo progetto?",
|
||||
"faq_a_4": "Puoi supportare lo sviluppo di questo progetto abbonandoti alla nostra app Photos @ ente.io.",
|
||||
"faq_q_5": "Come posso abilitare il blocco FaceID in Auth",
|
||||
"faq_a_5": "Puoi abilitare il blocco FaceID in Impostazioni → Sicurezza → Schermata di blocco.",
|
||||
"somethingWentWrongMessage": "Qualcosa è andato storto, per favore riprova",
|
||||
"leaveFamily": "Abbandona il piano famiglia",
|
||||
@@ -136,6 +145,8 @@
|
||||
"enterCodeHint": "Inserisci il codice di 6 cifre dalla tua app di autenticazione",
|
||||
"lostDeviceTitle": "Dispositivo perso?",
|
||||
"twoFactorAuthTitle": "Autenticazione a due fattori",
|
||||
"passkeyAuthTitle": "Verifica della passkey",
|
||||
"verifyPasskey": "Verifica passkey",
|
||||
"recoverAccount": "Recupera account",
|
||||
"enterRecoveryKeyHint": "Inserisci la tua chiave di recupero",
|
||||
"recover": "Recupera",
|
||||
@@ -147,6 +158,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"invalidQRCode": "Codice QR non valido",
|
||||
"noRecoveryKeyTitle": "Nessuna chiave di recupero?",
|
||||
"enterEmailHint": "Inserisci il tuo indirizzo email",
|
||||
"invalidEmailTitle": "Indirizzo email non valido",
|
||||
@@ -190,6 +202,9 @@
|
||||
"doThisLater": "Fallo più tardi",
|
||||
"saveKey": "Salva chiave",
|
||||
"save": "Salva",
|
||||
"send": "Invia",
|
||||
"saveOrSendDescription": "Vuoi salvarlo nel tuo spazio di archiviazione (cartella Download per impostazione predefinita) o inviarlo ad altre applicazioni?",
|
||||
"saveOnlyDescription": "Vuoi salvarlo nel tuo spazio di archiviazione (cartella Download per impostazione predefinita)?",
|
||||
"back": "Indietro",
|
||||
"createAccount": "Crea account",
|
||||
"passwordStrength": "Forza password: {passwordStrengthValue}",
|
||||
@@ -337,6 +352,7 @@
|
||||
"deleteCodeAuthMessage": "Autenticarsi per cancellare il codice",
|
||||
"showQRAuthMessage": "Autenticarsi per mostrare il codice QR",
|
||||
"confirmAccountDeleteTitle": "Conferma l'eliminazione dell'account",
|
||||
"confirmAccountDeleteMessage": "Questo account è collegato ad altre app di Ente, se ne utilizzi.\n\nI tuoi dati caricati, su tutte le app di Ente, saranno pianificati per la cancellazione e il tuo account verrà eliminato definitivamente.",
|
||||
"androidBiometricHint": "Verifica l'identità",
|
||||
"@androidBiometricHint": {
|
||||
"description": "Hint message advising the user how to authenticate with biometrics. It is used on Android side. Maximum 60 characters."
|
||||
@@ -397,5 +413,28 @@
|
||||
"doNotSignOut": "Non uscire",
|
||||
"hearUsWhereTitle": "Dove hai sentito parlare di Ente? (opzionale)",
|
||||
"hearUsExplanation": "Non teniamo traccia delle installazioni dell'app. Sarebbe utile se ci dicessi dove ci hai trovato!",
|
||||
"passkey": "Passkey"
|
||||
"recoveryKeySaved": "Chiave di recupero salvata nella cartella Download!",
|
||||
"waitingForBrowserRequest": "In attesa della richiesta del browser...",
|
||||
"waitingForVerification": "In attesa di verifica...",
|
||||
"passkey": "Passkey",
|
||||
"developerSettingsWarning": "Siete sicuri di voler modificare le impostazioni sviluppatore?",
|
||||
"developerSettings": "Impostazioni sviluppatore",
|
||||
"serverEndpoint": "Endpoint del server",
|
||||
"invalidEndpoint": "Endpoint invalido",
|
||||
"invalidEndpointMessage": "Spiacenti, l'endpoint inserito non è valido. Inserisci un endpoint valido e riprova.",
|
||||
"endpointUpdatedMessage": "Endpoint aggiornato con successo",
|
||||
"customEndpoint": "Connesso a {endpoint}",
|
||||
"pinText": "Fissa",
|
||||
"unpinText": "Sgancia",
|
||||
"pinnedCodeMessage": "{code} è stato fissato",
|
||||
"unpinnedCodeMessage": "{code} è stato sganciato",
|
||||
"tags": "Tag",
|
||||
"createNewTag": "Crea un nuovo tag",
|
||||
"tag": "Tag",
|
||||
"create": "Crea",
|
||||
"editTag": "Modifica tag",
|
||||
"deleteTagTitle": "Eliminare il tag?",
|
||||
"deleteTagMessage": "Sei sicuro di voler eliminare questo tag? Questa azione è irreversibile.",
|
||||
"somethingWentWrongParsingCode": "Non siamo riusciti ad analizzare i codici {x}.",
|
||||
"updateNotAvailable": "Aggiornamento non disponibile"
|
||||
}
|
||||
@@ -19,7 +19,7 @@
|
||||
"pleaseVerifyDetails": "Por favor, verifique os detalhes e tente novamente",
|
||||
"codeIssuerHint": "Emissor",
|
||||
"codeSecretKeyHint": "Chave secreta",
|
||||
"codeAccountHint": "Conta (voce@dominio.com)",
|
||||
"codeAccountHint": "Conta (você@domínio.com)",
|
||||
"codeTagHint": "Etiqueta",
|
||||
"accountKeyType": "Tipo de chave",
|
||||
"sessionExpired": "Sessão expirada",
|
||||
@@ -27,7 +27,7 @@
|
||||
"description": "Title of the dialog when the users current session is invalid/expired"
|
||||
},
|
||||
"pleaseLoginAgain": "Por favor, faça login novamente",
|
||||
"loggingOut": "Desconectando...",
|
||||
"loggingOut": "Saindo...",
|
||||
"timeBasedKeyType": "Baseado no horário (TOTP)",
|
||||
"counterBasedKeyType": "Baseado em um contador (HOTP)",
|
||||
"saveAction": "Salvar",
|
||||
@@ -51,7 +51,7 @@
|
||||
"reportABug": "Informar um problema",
|
||||
"crashAndErrorReporting": "Reporte de erros e falhas",
|
||||
"reportBug": "Informar problema",
|
||||
"emailUsMessage": "Por favor, envie um e-mail para {email}",
|
||||
"emailUsMessage": "Envie um e-mail para {email}",
|
||||
"@emailUsMessage": {
|
||||
"placeholders": {
|
||||
"email": {
|
||||
@@ -59,12 +59,12 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"contactSupport": "Falar com o suporte",
|
||||
"contactSupport": "Falar com o Suporte",
|
||||
"rateUsOnStore": "Avalie-nos na {storeName}",
|
||||
"blog": "Blog",
|
||||
"merchandise": "Produtos",
|
||||
"verifyPassword": "Verificar senha",
|
||||
"pleaseWait": "Por favor, aguarde...",
|
||||
"pleaseWait": "Aguarde...",
|
||||
"generatingEncryptionKeysTitle": "Gerando chaves de criptografia...",
|
||||
"recreatePassword": "Recriar senha",
|
||||
"recreatePasswordMessage": "O dispositivo atual não é poderoso o suficiente para verificar sua senha, mas podemos regenerar de uma forma que funcione com todos os dispositivos.\n\nPor favor, faça o login usando sua chave de recuperação e recrie sua senha (você pode usar o mesmo novamente se desejar).",
|
||||
@@ -81,10 +81,10 @@
|
||||
"importTypePlainText": "Texto simples",
|
||||
"importTypeEnteEncrypted": "Exportação Ente criptografada",
|
||||
"passwordForDecryptingExport": "Senha para descriptografar a exportação",
|
||||
"passwordEmptyError": "O campo senha não pode estar vazio",
|
||||
"passwordEmptyError": "A senha não pode estar vazia",
|
||||
"importFromApp": "Importar códigos do {appName}",
|
||||
"importGoogleAuthGuide": "Exporte suas contas do Google Authenticator para um QR code usando a opção \"Transferir contas\". Então, usando outro dispositivo, escaneie o QR code.\n\nDica: Você pode usar a câmera do seu notebook para fotografar o QR code.",
|
||||
"importSelectJsonFile": "Selecione o arquivo JSON",
|
||||
"importSelectJsonFile": "Selecionar arquivo JSON",
|
||||
"importSelectAppExport": "Selecione o arquivo de exportação do aplicativo {appName}",
|
||||
"importEnteEncGuide": "Selecione o arquivo JSON criptografado exportado do Ente",
|
||||
"importRaivoGuide": "Use a opção \"Exportar OTPs para arquivo Zip\" nas configurações do Raivo.\n\nExtraia o arquivo zip e importe o arquivo JSON.",
|
||||
@@ -92,7 +92,7 @@
|
||||
"importAegisGuide": "Use a opção \"Exportar cofre\" nas Configurações do Aegis.\n\nSe o seu cofre estiver criptografado, você precisará inserir a senha do cofre para descriptografá-lo.",
|
||||
"import2FasGuide": "Use a opção \"Configurações->Exportar cópia de segurança\" no aplicativo 2FAS.\n\nSe a cópia de segurança estiver criptografada, será necessário inserir a senha para descriptografá-la",
|
||||
"importLastpassGuide": "Use a opção \"Transferir contas\" nas configurações do LastPass Authenticator e pressione \"Exportar contas para arquivo\". Importe o arquivo JSON baixado.",
|
||||
"exportCodes": "Exportar Códigos",
|
||||
"exportCodes": "Exportar códigos",
|
||||
"importLabel": "Importar",
|
||||
"importInstruction": "Por favor, selecione um arquivo que contenha uma lista de códigos no seguinte formato",
|
||||
"importCodeDelimiterInfo": "Os códigos podem ser separados por uma vírgula ou uma nova linha",
|
||||
@@ -114,14 +114,14 @@
|
||||
"general": "Geral",
|
||||
"settings": "Ajustes",
|
||||
"copied": "Copiado",
|
||||
"pleaseTryAgain": "Por favor, tente novamente",
|
||||
"existingUser": "Usuário Existente",
|
||||
"pleaseTryAgain": "Tente de novo",
|
||||
"existingUser": "Usuário existente",
|
||||
"newUser": "Novo no Ente",
|
||||
"delete": "Excluir",
|
||||
"enterYourPasswordHint": "Insira sua senha",
|
||||
"forgotPassword": "Esqueci a senha",
|
||||
"oops": "Opa",
|
||||
"suggestFeatures": "Sugerir funcionalidades",
|
||||
"suggestFeatures": "Sugerir recursos",
|
||||
"faq": "Perguntas frequentes",
|
||||
"faq_q_1": "Quão seguro é o Auth?",
|
||||
"faq_a_1": "Todos os códigos que você faz backup via Auth são armazenados criptografados de ponta a ponta. Isso significa que somente você pode acessar seus códigos. Nossos aplicativos são de código aberto e nossa criptografia foi auditada externamente.",
|
||||
@@ -143,12 +143,12 @@
|
||||
"verify": "Verificar",
|
||||
"verifyEmail": "Verificar e-mail",
|
||||
"enterCodeHint": "Digite o código de 6 dígitos de\nseu aplicativo autenticador",
|
||||
"lostDeviceTitle": "Perdeu seu dispositivo?",
|
||||
"lostDeviceTitle": "Perdeu um dispositivo?",
|
||||
"twoFactorAuthTitle": "Autenticação de dois fatores",
|
||||
"passkeyAuthTitle": "Autenticação via Chave de acesso",
|
||||
"verifyPasskey": "Verificar chave de acesso",
|
||||
"verifyPasskey": "Verificar senha-mestra",
|
||||
"recoverAccount": "Recuperar conta",
|
||||
"enterRecoveryKeyHint": "Digite sua chave de recuperação",
|
||||
"enterRecoveryKeyHint": "Digite a chave de recuperação",
|
||||
"recover": "Recuperar",
|
||||
"contactSupportViaEmailMessage": "Por favor, envie um e-mail para {email} a partir do seu endereço de e-mail registrado",
|
||||
"@contactSupportViaEmailMessage": {
|
||||
@@ -160,7 +160,7 @@
|
||||
},
|
||||
"invalidQRCode": "QR Code inválido",
|
||||
"noRecoveryKeyTitle": "Sem chave de recuperação?",
|
||||
"enterEmailHint": "Insira o seu endereço de e-mail",
|
||||
"enterEmailHint": "Insira o endereço de e-mail",
|
||||
"invalidEmailTitle": "Endereço de e-mail inválido",
|
||||
"invalidEmailMessage": "Por favor, insira um endereço de e-mail válido.",
|
||||
"deleteAccount": "Excluir conta",
|
||||
@@ -175,8 +175,8 @@
|
||||
"moderateStrength": "Moderada",
|
||||
"confirmPassword": "Confirme sua senha",
|
||||
"close": "Fechar",
|
||||
"oopsSomethingWentWrong": "Oops, Algo deu errado.",
|
||||
"selectLanguage": "Selecionar idioma",
|
||||
"oopsSomethingWentWrong": "Opa. Algo deu errado.",
|
||||
"selectLanguage": "Trocar idioma",
|
||||
"language": "Idioma",
|
||||
"social": "Redes sociais",
|
||||
"security": "Segurança",
|
||||
@@ -199,14 +199,14 @@
|
||||
"recoveryKeyCopiedToClipboard": "A chave de recuperação foi copiada para a área de transferência",
|
||||
"recoveryKeyOnForgotPassword": "Caso você esqueça sua senha, a única maneira de recuperar seus dados é com essa chave.",
|
||||
"recoveryKeySaveDescription": "Não armazenamos essa chave, por favor, salve essa chave de 24 palavras em um lugar seguro.",
|
||||
"doThisLater": "Fazer isso mais tarde",
|
||||
"doThisLater": "Fazer isso depois",
|
||||
"saveKey": "Salvar chave",
|
||||
"save": "Salvar",
|
||||
"send": "Enviar",
|
||||
"saveOrSendDescription": "Você deseja salvar isso no seu armazenamento (pasta de downloads por padrão) ou enviá-lo para outros aplicativos?",
|
||||
"saveOnlyDescription": "Você deseja salvar isto no seu armazenamento (pasta de downloads por padrão)?",
|
||||
"back": "Voltar",
|
||||
"createAccount": "Criar uma conta",
|
||||
"createAccount": "Criar conta",
|
||||
"passwordStrength": "Força da senha: {passwordStrengthValue}",
|
||||
"@passwordStrength": {
|
||||
"description": "Text to indicate the password strength",
|
||||
@@ -234,7 +234,7 @@
|
||||
"passwordChangedSuccessfully": "Senha alterada com sucesso",
|
||||
"generatingEncryptionKeys": "Gerando chaves de criptografia...",
|
||||
"continueLabel": "Continuar",
|
||||
"insecureDevice": "Dispositivo não seguro",
|
||||
"insecureDevice": "Dispositivo inseguro",
|
||||
"sorryWeCouldNotGenerateSecureKeysOnThisDevicennplease": "Desculpe, não foi possível gerar chaves seguras neste dispositivo.\n\npor favor, faça o login com um dispositivo diferente.",
|
||||
"howItWorks": "Como funciona",
|
||||
"ackPasswordLostWarning": "Eu entendo que se eu perder minha senha, posso perder meus dados, já que meus dados são <underline>criptografados de ponta a ponta</underline>.",
|
||||
@@ -257,11 +257,11 @@
|
||||
"recoveryKeyVerifyReason": "Sua chave de recuperação é a única maneira de recuperar suas fotos se você esquecer sua senha. Você pode encontrar sua chave de recuperação em Configurações > Conta.\n\nDigite sua chave de recuperação aqui para verificar se você a salvou corretamente.",
|
||||
"confirmYourRecoveryKey": "Confirme sua chave de recuperação",
|
||||
"confirm": "Confirmar",
|
||||
"emailYourLogs": "Enviar por email seus logs",
|
||||
"emailYourLogs": "Enviar logs por e-mail",
|
||||
"pleaseSendTheLogsTo": "Por favor, envie os logs para \n{toEmail}",
|
||||
"copyEmailAddress": "Copiar endereço de e-mail",
|
||||
"exportLogs": "Exportar logs",
|
||||
"enterYourRecoveryKey": "Digite sua chave de recuperação",
|
||||
"enterYourRecoveryKey": "Digite a chave de recuperação",
|
||||
"tempErrorContactSupportIfPersists": "Parece que algo deu errado. Por favor, tente novamente mais tarde. Se o erro persistir, entre em contato com nossa equipe de suporte.",
|
||||
"itLooksLikeSomethingWentWrongPleaseRetryAfterSome": "Parece que algo deu errado. Por favor, tente novamente mais tarde. Se o erro persistir, entre em contato com nossa equipe de suporte.",
|
||||
"about": "Sobre",
|
||||
@@ -277,7 +277,7 @@
|
||||
"youAreOnTheLatestVersion": "Você está na versão mais recente",
|
||||
"warning": "Atenção",
|
||||
"exportWarningDesc": "O arquivo exportado contém informações confidenciais. Por favor, armazene-o com segurança.",
|
||||
"iUnderStand": "Eu entendo",
|
||||
"iUnderStand": "Entendo",
|
||||
"@iUnderStand": {
|
||||
"description": "Text for the button to confirm the user understands the warning"
|
||||
},
|
||||
@@ -326,11 +326,11 @@
|
||||
"sorryTheCodeYouveEnteredIsIncorrect": "Desculpe, o código que você inseriu está incorreto",
|
||||
"emailChangedTo": "E-mail alterado para {newEmail}",
|
||||
"authenticationFailedPleaseTryAgain": "Falha na autenticação. Por favor, tente novamente",
|
||||
"authenticationSuccessful": "Autenticação bem-sucedida!",
|
||||
"authenticationSuccessful": "Autenticado!",
|
||||
"twofactorAuthenticationSuccessfullyReset": "Autenticação de dois fatores redefinida com sucesso",
|
||||
"incorrectRecoveryKey": "Chave de recuperação incorreta",
|
||||
"theRecoveryKeyYouEnteredIsIncorrect": "A chave de recuperação inserida está incorreta",
|
||||
"enterPassword": "Insira a senha",
|
||||
"enterPassword": "Inserir senha",
|
||||
"selectExportFormat": "Selecione o formato para exportação",
|
||||
"exportDialogDesc": "As exportações criptografadas ficarão protegidas por uma senha de sua escolha.",
|
||||
"encrypted": "Criptografado",
|
||||
@@ -345,7 +345,7 @@
|
||||
"showLargeIcons": "Mostrar ícones grandes",
|
||||
"shouldHideCode": "Ocultar códigos",
|
||||
"doubleTapToViewHiddenCode": "Você pode tocar duas vezes em uma entrada para ver o código",
|
||||
"focusOnSearchBar": "Foco na pesquisa ao iniciar o aplicativo",
|
||||
"focusOnSearchBar": "Foco na busca ao iniciar o app",
|
||||
"confirmUpdatingkey": "Você tem certeza que deseja atualizar a chave secreta?",
|
||||
"minimizeAppOnCopy": "Minimizar aplicativo ao copiar",
|
||||
"editCodeAuthMessage": "Autenticar para editar o código",
|
||||
@@ -357,7 +357,7 @@
|
||||
"@androidBiometricHint": {
|
||||
"description": "Hint message advising the user how to authenticate with biometrics. It is used on Android side. Maximum 60 characters."
|
||||
},
|
||||
"androidBiometricNotRecognized": "Não reconhecido. Tente novamente.",
|
||||
"androidBiometricNotRecognized": "Não reconhecido. Tente de novo.",
|
||||
"@androidBiometricNotRecognized": {
|
||||
"description": "Message to let the user know that authentication was failed. It is used on Android side. Maximum 60 characters."
|
||||
},
|
||||
@@ -385,7 +385,7 @@
|
||||
"@androidDeviceCredentialsSetupDescription": {
|
||||
"description": "Message advising the user to go to the settings and configure device credentials on their device. It shows in a dialog on Android side."
|
||||
},
|
||||
"goToSettings": "Ir para Configurações",
|
||||
"goToSettings": "Ir para Ajustes",
|
||||
"@goToSettings": {
|
||||
"description": "Message showed on a button that the user can click to go to settings pages from the current dialog. It is used on both Android and iOS side. Maximum 30 characters."
|
||||
},
|
||||
@@ -410,13 +410,13 @@
|
||||
"signOutFromOtherDevices": "Terminar sessão em outros dispositivos",
|
||||
"signOutOtherBody": "Se você acha que alguém pode saber sua senha, você pode forçar todos os outros dispositivos que estão com sua conta a desconectar.",
|
||||
"signOutOtherDevices": "Terminar sessão em outros dispositivos",
|
||||
"doNotSignOut": "Não encerrar sessão",
|
||||
"doNotSignOut": "Não sair",
|
||||
"hearUsWhereTitle": "Como você ouviu sobre o Ente? (opcional)",
|
||||
"hearUsExplanation": "Não rastreamos instalações do aplicativo. Seria útil se você nos contasse onde nos encontrou!",
|
||||
"recoveryKeySaved": "Chave de recuperação salva na pasta Downloads!",
|
||||
"waitingForBrowserRequest": "Aguardando solicitação do navegador...",
|
||||
"waitingForVerification": "Esperando por verificação...",
|
||||
"passkey": "Chave de acesso",
|
||||
"passkey": "Senha-mestra",
|
||||
"developerSettingsWarning": "Tem certeza de que deseja modificar as configurações de Desenvolvedor?",
|
||||
"developerSettings": "Configurações de desenvolvedor",
|
||||
"serverEndpoint": "Endpoint do servidor",
|
||||
@@ -429,7 +429,7 @@
|
||||
"pinnedCodeMessage": "{code} foi fixado",
|
||||
"unpinnedCodeMessage": "{code} foi desafixado",
|
||||
"tags": "Etiquetas",
|
||||
"createNewTag": "Criar etiqueta",
|
||||
"createNewTag": "Criar nova etiqueta",
|
||||
"tag": "Etiqueta",
|
||||
"create": "Criar",
|
||||
"editTag": "Editar etiqueta",
|
||||
|
||||
1
auth/lib/l10n/arb/app_te.arb
Normal file
@@ -0,0 +1 @@
|
||||
{}
|
||||
@@ -66,8 +66,6 @@ Future<void> initSystemTray() async {
|
||||
void main() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
initSystemTray().ignore();
|
||||
|
||||
if (PlatformUtil.isDesktop()) {
|
||||
await windowManager.ensureInitialized();
|
||||
await WindowListenerService.instance.init();
|
||||
@@ -77,8 +75,10 @@ void main() async {
|
||||
await windowManager.waitUntilReadyToShow(windowOptions, () async {
|
||||
await windowManager.show();
|
||||
await windowManager.focus();
|
||||
initSystemTray().ignore();
|
||||
});
|
||||
}
|
||||
|
||||
await _runInForeground();
|
||||
await _setupPrivacyScreen();
|
||||
if (Platform.isAndroid) {
|
||||
@@ -132,7 +132,7 @@ Future _runWithLogs(Function() function, {String prefix = ""}) async {
|
||||
}
|
||||
|
||||
void _registerWindowsProtocol() {
|
||||
const kWindowsScheme = 'ente';
|
||||
const kWindowsScheme = 'enteauth';
|
||||
// Register our protocol only on Windows platform
|
||||
if (!kIsWeb && Platform.isWindows) {
|
||||
WindowsProtocolHandler()
|
||||
|
||||
@@ -42,7 +42,7 @@ class PasskeyService {
|
||||
Future<void> openPasskeyPage(BuildContext context) async {
|
||||
try {
|
||||
final jwtToken = await getJwtToken();
|
||||
final url = "https://accounts.ente.io/account-handoff?token=$jwtToken";
|
||||
final url = "https://accounts.ente.io/passkeys?token=$jwtToken";
|
||||
await launchUrlString(
|
||||
url,
|
||||
mode: LaunchMode.externalApplication,
|
||||
|
||||
@@ -266,32 +266,67 @@ class UserService {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> onPassKeyVerified(BuildContext context, Map response) async {
|
||||
final userPassword = Configuration.instance.getVolatilePassword();
|
||||
if (userPassword == null) throw Exception("volatile password is null");
|
||||
|
||||
await _saveConfiguration(response);
|
||||
|
||||
Widget page;
|
||||
if (Configuration.instance.getEncryptedToken() != null) {
|
||||
await Configuration.instance.decryptSecretsAndGetKeyEncKey(
|
||||
userPassword,
|
||||
Configuration.instance.getKeyAttributes()!,
|
||||
);
|
||||
page = const HomePage();
|
||||
} else {
|
||||
throw Exception("unexpected response during passkey verification");
|
||||
}
|
||||
|
||||
// ignore: unawaited_futures
|
||||
Navigator.of(context).pushAndRemoveUntil(
|
||||
MaterialPageRoute(
|
||||
builder: (BuildContext context) {
|
||||
return page;
|
||||
Future<dynamic> getTokenForPasskeySession(String sessionID) async {
|
||||
try {
|
||||
final response = await _dio.get(
|
||||
"${_config.getHttpEndpoint()}/users/two-factor/passkeys/get-token",
|
||||
queryParameters: {
|
||||
"sessionID": sessionID,
|
||||
},
|
||||
),
|
||||
(route) => route.isFirst,
|
||||
);
|
||||
);
|
||||
return response.data;
|
||||
} on DioException catch (e) {
|
||||
if (e.response != null) {
|
||||
if (e.response!.statusCode == 404 || e.response!.statusCode == 410) {
|
||||
throw PassKeySessionExpiredError();
|
||||
}
|
||||
if (e.response!.statusCode == 400) {
|
||||
throw PassKeySessionNotVerifiedError();
|
||||
}
|
||||
}
|
||||
rethrow;
|
||||
} catch (e, s) {
|
||||
_logger.severe("unexpected error", e, s);
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> onPassKeyVerified(BuildContext context, Map response) async {
|
||||
final ProgressDialog dialog =
|
||||
createProgressDialog(context, context.l10n.pleaseWait);
|
||||
await dialog.show();
|
||||
try {
|
||||
final userPassword = _config.getVolatilePassword();
|
||||
if (userPassword == null) throw Exception("volatile password is null");
|
||||
|
||||
await _saveConfiguration(response);
|
||||
|
||||
Widget page;
|
||||
if (_config.getEncryptedToken() != null) {
|
||||
await _config.decryptSecretsAndGetKeyEncKey(
|
||||
userPassword,
|
||||
_config.getKeyAttributes()!,
|
||||
);
|
||||
page = const HomePage();
|
||||
} else {
|
||||
throw Exception("unexpected response during passkey verification");
|
||||
}
|
||||
await dialog.hide();
|
||||
|
||||
// ignore: unawaited_futures
|
||||
Navigator.of(context).pushAndRemoveUntil(
|
||||
MaterialPageRoute(
|
||||
builder: (BuildContext context) {
|
||||
return page;
|
||||
},
|
||||
),
|
||||
(route) => route.isFirst,
|
||||
);
|
||||
} catch (e) {
|
||||
_logger.severe(e);
|
||||
await dialog.hide();
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> verifyEmail(
|
||||
|
||||
@@ -32,7 +32,7 @@ class CodeDisplayStore {
|
||||
if (code.hasError) continue;
|
||||
tags.addAll(code.display.tags);
|
||||
}
|
||||
return tags.toList();
|
||||
return tags.toList()..sort();
|
||||
}
|
||||
|
||||
Future<void> showDeleteTagDialog(BuildContext context, String tag) async {
|
||||
|
||||
@@ -33,7 +33,7 @@ enum ButtonType {
|
||||
|
||||
Color defaultButtonColor(EnteColorScheme colorScheme) {
|
||||
if (isPrimary) {
|
||||
return colorScheme.primary500;
|
||||
return colorScheme.primary400;
|
||||
}
|
||||
if (isSecondary) {
|
||||
return colorScheme.fillFaint;
|
||||
|
||||
@@ -238,6 +238,8 @@ class _HomePageState extends State<HomePage> {
|
||||
title: !_showSearchBox
|
||||
? const Text('Ente Auth')
|
||||
: TextField(
|
||||
autocorrect: false,
|
||||
enableSuggestions: false,
|
||||
focusNode: searchInputFocusNode,
|
||||
autofocus: _searchText.isEmpty,
|
||||
controller: _textController,
|
||||
|
||||
@@ -2,12 +2,14 @@ import 'dart:convert';
|
||||
|
||||
import 'package:app_links/app_links.dart';
|
||||
import 'package:ente_auth/core/configuration.dart';
|
||||
import 'package:ente_auth/core/errors.dart';
|
||||
import 'package:ente_auth/l10n/l10n.dart';
|
||||
import 'package:ente_auth/models/account/two_factor.dart';
|
||||
import 'package:ente_auth/services/user_service.dart';
|
||||
import 'package:ente_auth/ui/components/buttons/button_widget.dart';
|
||||
import 'package:ente_auth/ui/components/models/button_type.dart';
|
||||
import 'package:ente_auth/utils/dialog_util.dart';
|
||||
import 'package:ente_auth/utils/toast_util.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:url_launcher/url_launcher_string.dart';
|
||||
@@ -41,13 +43,38 @@ class _PasskeyPageState extends State<PasskeyPage> {
|
||||
|
||||
Future<void> launchPasskey() async {
|
||||
await launchUrlString(
|
||||
"https://accounts.ente.io/passkeys/flow?"
|
||||
"https://accounts.ente.io/passkeys/verify?"
|
||||
"passkeySessionID=${widget.sessionID}"
|
||||
"&redirect=enteauth://passkey",
|
||||
"&redirect=enteauth://passkey"
|
||||
"&clientPackage=io.ente.auth",
|
||||
mode: LaunchMode.externalApplication,
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> checkStatus() async {
|
||||
late dynamic response;
|
||||
try {
|
||||
response = await UserService.instance
|
||||
.getTokenForPasskeySession(widget.sessionID);
|
||||
} on PassKeySessionNotVerifiedError {
|
||||
showToast(context, context.l10n.passKeyPendingVerification);
|
||||
return;
|
||||
} on PassKeySessionExpiredError {
|
||||
await showErrorDialog(
|
||||
context,
|
||||
context.l10n.loginSessionExpired,
|
||||
context.l10n.loginSessionExpiredDetails,
|
||||
);
|
||||
Navigator.of(context).pop();
|
||||
return;
|
||||
} catch (e, s) {
|
||||
_logger.severe("failed to check status", e, s);
|
||||
showGenericErrorDialog(context: context).ignore();
|
||||
return;
|
||||
}
|
||||
await UserService.instance.onPassKeyVerified(context, response);
|
||||
}
|
||||
|
||||
Future<void> _handleDeeplink(String? link) async {
|
||||
if (!context.mounted ||
|
||||
Configuration.instance.hasConfiguredAccount() ||
|
||||
@@ -59,8 +86,20 @@ class _PasskeyPageState extends State<PasskeyPage> {
|
||||
}
|
||||
try {
|
||||
if (mounted && link.toLowerCase().startsWith("enteauth://passkey")) {
|
||||
final String? uri = Uri.parse(link).queryParameters['response'];
|
||||
String base64String = uri!.toString();
|
||||
if (Configuration.instance.isLoggedIn()) {
|
||||
_logger.info('ignored deeplink: already configured');
|
||||
showToast(context, 'Account is already configured.');
|
||||
return;
|
||||
}
|
||||
final parsedUri = Uri.parse(link);
|
||||
final sessionID = parsedUri.queryParameters['passkeySessionID'];
|
||||
if (sessionID != widget.sessionID) {
|
||||
showToast(context, "Session ID mismatch");
|
||||
_logger.warning('ignored deeplink: sessionID mismatch');
|
||||
return;
|
||||
}
|
||||
final String? authResponse = parsedUri.queryParameters['response'];
|
||||
String base64String = authResponse!.toString();
|
||||
while (base64String.length % 4 != 0) {
|
||||
base64String += '=';
|
||||
}
|
||||
@@ -118,9 +157,23 @@ class _PasskeyPageState extends State<PasskeyPage> {
|
||||
const SizedBox(height: 16),
|
||||
ButtonWidget(
|
||||
buttonType: ButtonType.primary,
|
||||
labelText: context.l10n.verifyPasskey,
|
||||
labelText: context.l10n.tryAgain,
|
||||
onTap: () => launchPasskey(),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
ButtonWidget(
|
||||
buttonType: ButtonType.secondary,
|
||||
labelText: context.l10n.checkStatus,
|
||||
onTap: () async {
|
||||
try {
|
||||
await checkStatus();
|
||||
} catch (e) {
|
||||
debugPrint('failed to check status %e');
|
||||
showGenericErrorDialog(context: context).ignore();
|
||||
}
|
||||
},
|
||||
shouldSurfaceExecutionStates: true,
|
||||
),
|
||||
const Padding(padding: EdgeInsets.all(30)),
|
||||
GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
|
||||
@@ -139,7 +139,10 @@ Future<int?> _process2FasExportFile(
|
||||
for (var item in decodedServices) {
|
||||
var kind = item['otp']['tokenType'];
|
||||
var account = item['otp']['account'] ?? '';
|
||||
var issuer = item['otp']['issuer'] ?? item['name'] ?? '';
|
||||
var issuer = item['otp']['issuer'];
|
||||
if (issuer == null || (issuer as String).isEmpty) {
|
||||
issuer = item['name'] ?? '';
|
||||
}
|
||||
var algorithm = item['otp']['algorithm'];
|
||||
var secret = item['secret'];
|
||||
var timer = item['otp']['period'];
|
||||
|
||||
@@ -4,7 +4,6 @@ import 'dart:typed_data';
|
||||
import 'package:ente_auth/core/configuration.dart';
|
||||
import 'package:ente_auth/l10n/l10n.dart';
|
||||
import 'package:ente_auth/models/user_details.dart';
|
||||
import 'package:ente_auth/services/auth_feature_flag.dart';
|
||||
import 'package:ente_auth/services/local_authentication_service.dart';
|
||||
import 'package:ente_auth/services/passkey_service.dart';
|
||||
import 'package:ente_auth/services/user_service.dart';
|
||||
@@ -66,20 +65,17 @@ class _SecuritySectionWidgetState extends State<SecuritySectionWidget> {
|
||||
// We don't know if the user can disable MFA yet, so we fetch the info
|
||||
UserService.instance.getUserDetailsV2().ignore();
|
||||
}
|
||||
final bool isInternalUser =
|
||||
FeatureFlagService.instance.isInternalUserOrDebugBuild();
|
||||
children.addAll([
|
||||
if (isInternalUser) sectionOptionSpacing,
|
||||
if (isInternalUser)
|
||||
MenuItemWidget(
|
||||
captionedTextWidget: CaptionedTextWidget(
|
||||
title: l10n.passkey,
|
||||
),
|
||||
pressedColor: getEnteColorScheme(context).fillFaint,
|
||||
trailingIcon: Icons.chevron_right_outlined,
|
||||
trailingIconIsMuted: true,
|
||||
onTap: () async => await onPasskeyClick(context),
|
||||
sectionOptionSpacing,
|
||||
MenuItemWidget(
|
||||
captionedTextWidget: CaptionedTextWidget(
|
||||
title: l10n.passkey,
|
||||
),
|
||||
pressedColor: getEnteColorScheme(context).fillFaint,
|
||||
trailingIcon: Icons.chevron_right_outlined,
|
||||
trailingIconIsMuted: true,
|
||||
onTap: () async => await onPasskeyClick(context),
|
||||
),
|
||||
sectionOptionSpacing,
|
||||
MenuItemWidget(
|
||||
captionedTextWidget: CaptionedTextWidget(
|
||||
|
||||
@@ -34,7 +34,7 @@ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
||||
"Debug" "Profile" "Release")
|
||||
endif()
|
||||
|
||||
# Compilation ui.settings that should be applied to most targets.
|
||||
# Compilation settings that should be applied to most targets.
|
||||
#
|
||||
# Be cautious about adding new options here, as plugins use this function by
|
||||
# default. In most cases, you should add new options to specific targets instead
|
||||
@@ -66,8 +66,8 @@ add_executable(${BINARY_NAME}
|
||||
"${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc"
|
||||
)
|
||||
|
||||
# Apply the standard set of build ui.settings. This can be removed for applications
|
||||
# that need different build ui.settings.
|
||||
# Apply the standard set of build settings. This can be removed for applications
|
||||
# that need different build settings.
|
||||
apply_standard_settings(${BINARY_NAME})
|
||||
|
||||
# Add dependency libraries. Add any application-specific dependencies here.
|
||||
@@ -86,6 +86,7 @@ set_target_properties(${BINARY_NAME}
|
||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run"
|
||||
)
|
||||
|
||||
|
||||
# Generated plugin build rules, which manage building the plugins and adding
|
||||
# them to the application.
|
||||
include(flutter/generated_plugins.cmake)
|
||||
@@ -122,6 +123,12 @@ foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES})
|
||||
COMPONENT Runtime)
|
||||
endforeach(bundled_library)
|
||||
|
||||
# Copy the native assets provided by the build.dart from all packages.
|
||||
set(NATIVE_ASSETS_DIR "${PROJECT_BUILD_DIR}native_assets/linux/")
|
||||
install(DIRECTORY "${NATIVE_ASSETS_DIR}"
|
||||
DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
|
||||
COMPONENT Runtime)
|
||||
|
||||
# Fully re-copy the assets directory on each build to avoid having stale files
|
||||
# from a previous install.
|
||||
set(FLUTTER_ASSET_DIR_NAME "flutter_assets")
|
||||
|
||||
@@ -63,7 +63,7 @@ static void my_application_activate(GApplication *application)
|
||||
}
|
||||
|
||||
gtk_window_set_default_size(window, 1280, 720);
|
||||
gtk_widget_realize(GTK_WIDGET(window));
|
||||
gtk_widget_show(GTK_WIDGET(window));
|
||||
|
||||
g_autoptr(FlDartProject) project = fl_dart_project_new();
|
||||
fl_dart_project_set_dart_entrypoint_arguments(project, self->dart_entrypoint_arguments);
|
||||
@@ -73,6 +73,7 @@ static void my_application_activate(GApplication *application)
|
||||
gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view));
|
||||
|
||||
fl_register_plugins(FL_PLUGIN_REGISTRY(view));
|
||||
gtk_widget_hide(GTK_WIDGET(window));
|
||||
|
||||
gtk_widget_grab_focus(GTK_WIDGET(view));
|
||||
}
|
||||
@@ -98,6 +99,26 @@ static gboolean my_application_local_command_line(GApplication *application, gch
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Implements GApplication::startup.
|
||||
static void my_application_startup(GApplication *application)
|
||||
{
|
||||
// MyApplication* self = MY_APPLICATION(object);
|
||||
|
||||
// Perform any actions required at application startup.
|
||||
|
||||
G_APPLICATION_CLASS(my_application_parent_class)->startup(application);
|
||||
}
|
||||
|
||||
// Implements GApplication::shutdown.
|
||||
static void my_application_shutdown(GApplication *application)
|
||||
{
|
||||
// MyApplication* self = MY_APPLICATION(object);
|
||||
|
||||
// Perform any actions required at application shutdown.
|
||||
|
||||
G_APPLICATION_CLASS(my_application_parent_class)->shutdown(application);
|
||||
}
|
||||
|
||||
// Implements GObject::dispose.
|
||||
static void my_application_dispose(GObject *object)
|
||||
{
|
||||
@@ -110,6 +131,8 @@ static void my_application_class_init(MyApplicationClass *klass)
|
||||
{
|
||||
G_APPLICATION_CLASS(klass)->activate = my_application_activate;
|
||||
G_APPLICATION_CLASS(klass)->local_command_line = my_application_local_command_line;
|
||||
G_APPLICATION_CLASS(klass)->startup = my_application_startup;
|
||||
G_APPLICATION_CLASS(klass)->shutdown = my_application_shutdown;
|
||||
G_OBJECT_CLASS(klass)->dispose = my_application_dispose;
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
<key>CFBundleURLSchemes</key>
|
||||
<array>
|
||||
<string>otpauth</string>
|
||||
<string>enteauth</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
|
||||
@@ -293,9 +293,9 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
path: "packages/desktop_webview_window"
|
||||
ref: fix-webkit-version
|
||||
resolved-ref: fe2223e4edfecdbb3a97bb9e3ced73db4ae9d979
|
||||
url: "https://github.com/ente-io/flutter-desktopwebview-fork"
|
||||
ref: main
|
||||
resolved-ref: "726d8281a244d56ab36e843f0427c48de6d9cc56"
|
||||
url: "https://github.com/MixinNetwork/flutter-plugins"
|
||||
source: git
|
||||
version: "0.2.4"
|
||||
device_info_plus:
|
||||
@@ -602,11 +602,11 @@ packages:
|
||||
dependency: "direct overridden"
|
||||
description:
|
||||
path: flutter_secure_storage_linux
|
||||
ref: patch-1
|
||||
resolved-ref: da8ab43bc51c8c3249a261c33b27aa6f018f819b
|
||||
url: "https://github.com/prateekmedia/flutter_secure_storage.git"
|
||||
ref: develop
|
||||
resolved-ref: cb30953edc029dc4059b72700270b4cd3a3afade
|
||||
url: "https://github.com/mogol/flutter_secure_storage.git"
|
||||
source: git
|
||||
version: "1.2.0"
|
||||
version: "1.2.1"
|
||||
flutter_secure_storage_macos:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -813,10 +813,10 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: intl
|
||||
sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d"
|
||||
sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.18.1"
|
||||
version: "0.19.0"
|
||||
io:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -853,26 +853,26 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker
|
||||
sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa"
|
||||
sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "10.0.0"
|
||||
version: "10.0.4"
|
||||
leak_tracker_flutter_testing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker_flutter_testing
|
||||
sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0
|
||||
sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.1"
|
||||
version: "3.0.3"
|
||||
leak_tracker_testing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker_testing
|
||||
sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47
|
||||
sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.1"
|
||||
version: "3.0.1"
|
||||
lints:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
@@ -957,10 +957,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: meta
|
||||
sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04
|
||||
sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.11.0"
|
||||
version: "1.12.0"
|
||||
mime:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1523,10 +1523,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_api
|
||||
sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
|
||||
sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.6.1"
|
||||
version: "0.7.0"
|
||||
timezone:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1683,10 +1683,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vm_service
|
||||
sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957
|
||||
sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "13.0.0"
|
||||
version: "14.2.1"
|
||||
watcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1731,10 +1731,10 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: window_manager
|
||||
sha256: b3c895bdf936c77b83c5254bec2e6b3f066710c1f89c38b20b8acc382b525494
|
||||
sha256: "8699323b30da4cdbe2aa2e7c9de567a6abd8a97d9a5c850a3c86dcd0b34bbfbf"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.3.8"
|
||||
version: "0.3.9"
|
||||
xdg_directories:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
name: ente_auth
|
||||
description: ente two-factor authenticator
|
||||
version: 3.0.8+308
|
||||
version: 3.0.11+311
|
||||
publish_to: none
|
||||
|
||||
environment:
|
||||
@@ -20,8 +20,8 @@ dependencies:
|
||||
convert: ^3.1.1
|
||||
desktop_webview_window:
|
||||
git:
|
||||
url: https://github.com/ente-io/flutter-desktopwebview-fork
|
||||
ref: fix-webkit-version
|
||||
url: https://github.com/MixinNetwork/flutter-plugins
|
||||
ref: main
|
||||
path: packages/desktop_webview_window
|
||||
device_info_plus: ^9.1.1
|
||||
dio: ^5.4.0
|
||||
@@ -64,7 +64,7 @@ dependencies:
|
||||
google_nav_bar: ^5.0.5 #supported
|
||||
gradient_borders: ^1.0.0
|
||||
http: ^1.1.0
|
||||
intl: ^0.18.0
|
||||
intl: ^0.19.0
|
||||
json_annotation: ^4.5.0
|
||||
local_auth: ^2.2.0
|
||||
local_auth_android: ^1.0.37
|
||||
@@ -102,13 +102,13 @@ dependencies:
|
||||
url_launcher: ^6.1.5
|
||||
uuid: ^4.2.2
|
||||
win32: ^5.1.1
|
||||
window_manager: ^0.3.8
|
||||
window_manager: ^0.3.9
|
||||
|
||||
dependency_overrides:
|
||||
flutter_secure_storage_linux:
|
||||
git:
|
||||
url: https://github.com/prateekmedia/flutter_secure_storage.git
|
||||
ref: patch-1
|
||||
url: https://github.com/mogol/flutter_secure_storage.git
|
||||
ref: develop
|
||||
path: flutter_secure_storage_linux
|
||||
dev_dependencies:
|
||||
build_runner: ^2.1.11
|
||||
|
||||
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 133 KiB |
@@ -71,12 +71,15 @@ func NewClient(p Params) *Client {
|
||||
restClient: enteAPI,
|
||||
downloadClient: resty.New().
|
||||
SetRetryCount(3).
|
||||
SetRetryWaitTime(5 * time.Second).
|
||||
SetRetryMaxWaitTime(10 * time.Second).
|
||||
SetRetryWaitTime(10 * time.Second).
|
||||
SetRetryMaxWaitTime(20 * time.Second).
|
||||
AddRetryCondition(func(r *resty.Response, err error) bool {
|
||||
shouldRetry := r.StatusCode() == 429 || r.StatusCode() > 500
|
||||
shouldRetry := r.StatusCode() == 429 || r.StatusCode() >= 500
|
||||
if shouldRetry {
|
||||
log.Printf("retrying download due to %d code", r.StatusCode())
|
||||
amxRequestID := r.Header().Get("X-Amz-Request-Id")
|
||||
cfRayID := r.Header().Get("CF-Ray")
|
||||
wasabiRefID := r.Header().Get("X-Wasabi-Cm-Reference-Id")
|
||||
log.Printf("Retry scheduled. error statusCode: %d, X-Amz-Request-Id: %s, CF-Ray: %s, X-Wasabi-Cm-Reference-Id: %s", r.StatusCode(), amxRequestID, cfRayID, wasabiRefID)
|
||||
}
|
||||
return shouldRetry
|
||||
}),
|
||||
|
||||
@@ -15,7 +15,7 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
var AppVersion = "0.1.14"
|
||||
var AppVersion = "0.1.15"
|
||||
|
||||
func main() {
|
||||
cliDBPath, err := GetCLIConfigPath()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
name: "Release"
|
||||
|
||||
# Build the ente-io/ente's desktop/rc branch and create/update a draft release.
|
||||
# Build the desktop app with code from ente-io/ente and create/update a release.
|
||||
#
|
||||
# For more details, see `docs/release.md` in ente-io/ente.
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
- Remember the window size across app restarts.
|
||||
- Revert changes to the Linux icon.
|
||||
- Fix an issue where deleted items in watched folders would not move to
|
||||
uncategorized.
|
||||
|
||||
## v1.7.0
|
||||
|
||||
|
||||
@@ -6,6 +6,9 @@ files:
|
||||
extraFiles:
|
||||
- from: build
|
||||
to: resources
|
||||
protocols:
|
||||
- name: Ente
|
||||
schemes: ["ente"]
|
||||
win:
|
||||
target:
|
||||
- target: nsis
|
||||
|
||||
@@ -61,6 +61,103 @@ export const allowWindowClose = (): void => {
|
||||
shouldAllowWindowClose = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* The app's entry point.
|
||||
*
|
||||
* We call this at the end of this file.
|
||||
*/
|
||||
const main = () => {
|
||||
const gotTheLock = app.requestSingleInstanceLock();
|
||||
if (!gotTheLock) {
|
||||
app.quit();
|
||||
return;
|
||||
}
|
||||
|
||||
let mainWindow: BrowserWindow | undefined;
|
||||
|
||||
initLogging();
|
||||
logStartupBanner();
|
||||
registerForEnteLinks();
|
||||
// The order of the next two calls is important
|
||||
setupRendererServer();
|
||||
registerPrivilegedSchemes();
|
||||
migrateLegacyWatchStoreIfNeeded();
|
||||
|
||||
/**
|
||||
* Handle an open URL request, but ensuring that we have a mainWindow.
|
||||
*/
|
||||
const handleOpenURLEnsuringWindow = (url: string) => {
|
||||
log.info(`Attempting to handle request to open URL: ${url}`);
|
||||
if (mainWindow) handleEnteLinks(mainWindow, url);
|
||||
else setTimeout(() => handleOpenURLEnsuringWindow(url), 1000);
|
||||
};
|
||||
|
||||
app.on("second-instance", (_, argv: string[]) => {
|
||||
// Someone tried to run a second instance, we should focus our window.
|
||||
if (mainWindow) {
|
||||
mainWindow.show();
|
||||
if (mainWindow.isMinimized()) mainWindow.restore();
|
||||
mainWindow.focus();
|
||||
}
|
||||
// On Windows and Linux, this is how we get deeplinks.
|
||||
// See: registerForEnteLinks
|
||||
const url = argv.pop();
|
||||
if (url) handleOpenURLEnsuringWindow(url);
|
||||
});
|
||||
|
||||
// Emitted once, when Electron has finished initializing.
|
||||
//
|
||||
// Note that some Electron APIs can only be used after this event occurs.
|
||||
void app.whenReady().then(() => {
|
||||
void (async () => {
|
||||
// Create window and prepare for the renderer.
|
||||
mainWindow = createMainWindow();
|
||||
|
||||
// Setup IPC and streams.
|
||||
const watcher = createWatcher(mainWindow);
|
||||
attachIPCHandlers();
|
||||
attachFSWatchIPCHandlers(watcher);
|
||||
attachLogoutIPCHandler(watcher);
|
||||
registerStreamProtocol();
|
||||
|
||||
// Configure the renderer's environment.
|
||||
const webContents = mainWindow.webContents;
|
||||
setDownloadPath(webContents);
|
||||
allowExternalLinks(webContents);
|
||||
allowAllCORSOrigins(webContents);
|
||||
|
||||
// Start loading the renderer.
|
||||
void mainWindow.loadURL(rendererURL);
|
||||
|
||||
// Continue on with the rest of the startup sequence.
|
||||
Menu.setApplicationMenu(await createApplicationMenu(mainWindow));
|
||||
setupTrayItem(mainWindow);
|
||||
setupAutoUpdater(mainWindow);
|
||||
|
||||
try {
|
||||
await deleteLegacyDiskCacheDirIfExists();
|
||||
await deleteLegacyKeysStoreIfExists();
|
||||
} catch (e) {
|
||||
// Log but otherwise ignore errors during non-critical startup
|
||||
// actions.
|
||||
log.error("Ignoring startup error", e);
|
||||
}
|
||||
})();
|
||||
});
|
||||
|
||||
// This is a macOS only event. Show our window when the user activates the
|
||||
// app, e.g. by clicking on its dock icon.
|
||||
app.on("activate", () => mainWindow?.show());
|
||||
|
||||
app.on("before-quit", () => {
|
||||
if (mainWindow) saveWindowBounds(mainWindow);
|
||||
allowWindowClose();
|
||||
});
|
||||
|
||||
// On macOS, this is how we get deeplinks. See: registerForEnteLinks
|
||||
app.on("open-url", (_, url) => handleOpenURLEnsuringWindow(url));
|
||||
};
|
||||
|
||||
/**
|
||||
* Log a standard startup banner.
|
||||
*
|
||||
@@ -137,6 +234,32 @@ const registerPrivilegedSchemes = () => {
|
||||
]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Register a handler for deeplinks, for the "ente://" protocol.
|
||||
*
|
||||
* See: [Note: Passkey verification in the desktop app].
|
||||
*
|
||||
* Implementation notes:
|
||||
* - https://www.electronjs.org/docs/latest/tutorial/launch-app-from-url-in-another-app
|
||||
* - This works only when the app is packaged.
|
||||
* - On Windows and Linux, we get the deeplink in the "second-instance" event.
|
||||
* - On macOS, we get the deeplink in the "open-url" event.
|
||||
*/
|
||||
const registerForEnteLinks = () => app.setAsDefaultProtocolClient("ente");
|
||||
|
||||
/** Sibling of {@link registerForEnteLinks}. */
|
||||
const handleEnteLinks = (mainWindow: BrowserWindow, url: string) => {
|
||||
// [Note: Using deeplinks to navigate in desktop app]
|
||||
//
|
||||
// Both
|
||||
//
|
||||
// - our deeplink protocol, and
|
||||
// - the protocol we're using to serve/ our bundled web app
|
||||
//
|
||||
// use the same scheme ("ente://"), so the URL can directly be forwarded.
|
||||
mainWindow.webContents.send("openURL", url);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create an return the {@link BrowserWindow} that will form our app's UI.
|
||||
*
|
||||
@@ -440,79 +563,5 @@ const deleteLegacyKeysStoreIfExists = async () => {
|
||||
}
|
||||
};
|
||||
|
||||
const main = () => {
|
||||
const gotTheLock = app.requestSingleInstanceLock();
|
||||
if (!gotTheLock) {
|
||||
app.quit();
|
||||
return;
|
||||
}
|
||||
|
||||
let mainWindow: BrowserWindow | undefined;
|
||||
|
||||
initLogging();
|
||||
logStartupBanner();
|
||||
// The order of the next two calls is important
|
||||
setupRendererServer();
|
||||
registerPrivilegedSchemes();
|
||||
migrateLegacyWatchStoreIfNeeded();
|
||||
|
||||
app.on("second-instance", () => {
|
||||
// Someone tried to run a second instance, we should focus our window.
|
||||
if (mainWindow) {
|
||||
mainWindow.show();
|
||||
if (mainWindow.isMinimized()) mainWindow.restore();
|
||||
mainWindow.focus();
|
||||
}
|
||||
});
|
||||
|
||||
// Emitted once, when Electron has finished initializing.
|
||||
//
|
||||
// Note that some Electron APIs can only be used after this event occurs.
|
||||
void app.whenReady().then(() => {
|
||||
void (async () => {
|
||||
// Create window and prepare for the renderer.
|
||||
mainWindow = createMainWindow();
|
||||
|
||||
// Setup IPC and streams.
|
||||
const watcher = createWatcher(mainWindow);
|
||||
attachIPCHandlers();
|
||||
attachFSWatchIPCHandlers(watcher);
|
||||
attachLogoutIPCHandler(watcher);
|
||||
registerStreamProtocol();
|
||||
|
||||
// Configure the renderer's environment.
|
||||
const webContents = mainWindow.webContents;
|
||||
setDownloadPath(webContents);
|
||||
allowExternalLinks(webContents);
|
||||
allowAllCORSOrigins(webContents);
|
||||
|
||||
// Start loading the renderer.
|
||||
void mainWindow.loadURL(rendererURL);
|
||||
|
||||
// Continue on with the rest of the startup sequence.
|
||||
Menu.setApplicationMenu(await createApplicationMenu(mainWindow));
|
||||
setupTrayItem(mainWindow);
|
||||
setupAutoUpdater(mainWindow);
|
||||
|
||||
try {
|
||||
await deleteLegacyDiskCacheDirIfExists();
|
||||
await deleteLegacyKeysStoreIfExists();
|
||||
} catch (e) {
|
||||
// Log but otherwise ignore errors during non-critical startup
|
||||
// actions.
|
||||
log.error("Ignoring startup error", e);
|
||||
}
|
||||
})();
|
||||
});
|
||||
|
||||
// This is a macOS only event. Show our window when the user activates the
|
||||
// app, e.g. by clicking on its dock icon.
|
||||
app.on("activate", () => mainWindow?.show());
|
||||
|
||||
app.on("before-quit", () => {
|
||||
if (mainWindow) saveWindowBounds(mainWindow);
|
||||
allowWindowClose();
|
||||
});
|
||||
};
|
||||
|
||||
// Go for it.
|
||||
main();
|
||||
|
||||
@@ -46,7 +46,12 @@ import {
|
||||
computeCLIPTextEmbeddingIfAvailable,
|
||||
} from "./services/ml-clip";
|
||||
import { computeFaceEmbeddings, detectFaces } from "./services/ml-face";
|
||||
import { encryptionKey, saveEncryptionKey } from "./services/store";
|
||||
import {
|
||||
encryptionKey,
|
||||
lastShownChangelogVersion,
|
||||
saveEncryptionKey,
|
||||
setLastShownChangelogVersion,
|
||||
} from "./services/store";
|
||||
import {
|
||||
clearPendingUploads,
|
||||
listZipItems,
|
||||
@@ -101,11 +106,19 @@ export const attachIPCHandlers = () => {
|
||||
|
||||
ipcMain.handle("selectDirectory", () => selectDirectory());
|
||||
|
||||
ipcMain.handle("encryptionKey", () => encryptionKey());
|
||||
|
||||
ipcMain.handle("saveEncryptionKey", (_, encryptionKey: string) =>
|
||||
saveEncryptionKey(encryptionKey),
|
||||
);
|
||||
|
||||
ipcMain.handle("encryptionKey", () => encryptionKey());
|
||||
ipcMain.handle("lastShownChangelogVersion", () =>
|
||||
lastShownChangelogVersion(),
|
||||
);
|
||||
|
||||
ipcMain.handle("setLastShownChangelogVersion", (_, version: number) =>
|
||||
setLastShownChangelogVersion(version),
|
||||
);
|
||||
|
||||
// - App update
|
||||
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
import { safeStorage } from "electron/main";
|
||||
import { safeStorageStore } from "../stores/safe-storage";
|
||||
import { uploadStatusStore } from "../stores/upload-status";
|
||||
import { userPreferences } from "../stores/user-preferences";
|
||||
import { watchStore } from "../stores/watch";
|
||||
|
||||
/**
|
||||
* Clear all stores except user preferences.
|
||||
*
|
||||
* This is useful to reset state when the user logs out.
|
||||
* This function is useful to reset state when the user logs out. User
|
||||
* preferences are preserved since they contain things tied to the person using
|
||||
* the app or other machine specific state not tied to the account they were
|
||||
* using inside the app.
|
||||
*/
|
||||
export const clearStores = () => {
|
||||
safeStorageStore.clear();
|
||||
@@ -32,3 +36,9 @@ export const encryptionKey = (): string | undefined => {
|
||||
const keyBuffer = Buffer.from(b64EncryptedKey, "base64");
|
||||
return safeStorage.decryptString(keyBuffer);
|
||||
};
|
||||
|
||||
export const lastShownChangelogVersion = (): number | undefined =>
|
||||
userPreferences.get("lastShownChangelogVersion");
|
||||
|
||||
export const setLastShownChangelogVersion = (version: number) =>
|
||||
userPreferences.set("lastShownChangelogVersion", version);
|
||||
|
||||
@@ -9,6 +9,12 @@ interface UserPreferences {
|
||||
hideDockIcon?: boolean;
|
||||
skipAppVersion?: string;
|
||||
muteUpdateNotificationVersion?: string;
|
||||
/**
|
||||
* The changelog version for which we last showed the "What's new" screen.
|
||||
*
|
||||
* See: [Note: Conditions for showing "What's new"]
|
||||
*/
|
||||
lastShownChangelogVersion?: number;
|
||||
/**
|
||||
* The last position and size of our app's window.
|
||||
*
|
||||
@@ -33,6 +39,7 @@ const userPreferencesSchema: Schema<UserPreferences> = {
|
||||
hideDockIcon: { type: "boolean" },
|
||||
skipAppVersion: { type: "string" },
|
||||
muteUpdateNotificationVersion: { type: "string" },
|
||||
lastShownChangelogVersion: { type: "number" },
|
||||
windowBounds: {
|
||||
properties: {
|
||||
x: { type: "number" },
|
||||
|
||||
@@ -72,15 +72,26 @@ const encryptionKey = () => ipcRenderer.invoke("encryptionKey");
|
||||
const saveEncryptionKey = (encryptionKey: string) =>
|
||||
ipcRenderer.invoke("saveEncryptionKey", encryptionKey);
|
||||
|
||||
const onMainWindowFocus = (cb?: () => void) => {
|
||||
const lastShownChangelogVersion = () =>
|
||||
ipcRenderer.invoke("lastShownChangelogVersion");
|
||||
|
||||
const setLastShownChangelogVersion = (version: number) =>
|
||||
ipcRenderer.invoke("setLastShownChangelogVersion", version);
|
||||
|
||||
const onMainWindowFocus = (cb: (() => void) | undefined) => {
|
||||
ipcRenderer.removeAllListeners("mainWindowFocus");
|
||||
if (cb) ipcRenderer.on("mainWindowFocus", cb);
|
||||
};
|
||||
|
||||
const onOpenURL = (cb: ((url: string) => void) | undefined) => {
|
||||
ipcRenderer.removeAllListeners("openURL");
|
||||
if (cb) ipcRenderer.on("openURL", (_, url: string) => cb(url));
|
||||
};
|
||||
|
||||
// - App update
|
||||
|
||||
const onAppUpdateAvailable = (
|
||||
cb?: ((update: AppUpdate) => void) | undefined,
|
||||
cb: ((update: AppUpdate) => void) | undefined,
|
||||
) => {
|
||||
ipcRenderer.removeAllListeners("appUpdateAvailable");
|
||||
if (cb) {
|
||||
@@ -306,7 +317,10 @@ contextBridge.exposeInMainWorld("electron", {
|
||||
logout,
|
||||
encryptionKey,
|
||||
saveEncryptionKey,
|
||||
lastShownChangelogVersion,
|
||||
setLastShownChangelogVersion,
|
||||
onMainWindowFocus,
|
||||
onOpenURL,
|
||||
|
||||
// - App update
|
||||
|
||||
|
||||
@@ -44,7 +44,8 @@ yarn dev
|
||||
For an editor, VSCode is a good choice. Also install the Prettier extension for
|
||||
VSCode, and set VSCode to format on save. This way the editor will automatically
|
||||
format and wrap the text using the project's standard, so you can just focus on
|
||||
the content.
|
||||
the content. You can also format without VSCode by using the `yarn pretty`
|
||||
command.
|
||||
|
||||
## Have fun!
|
||||
|
||||
|
||||
@@ -44,6 +44,10 @@ export const sidebar = [
|
||||
link: "/photos/features/location-tags",
|
||||
},
|
||||
{ text: "Map", link: "/photos/features/map" },
|
||||
{
|
||||
text: "Passkeys",
|
||||
link: "/photos/features/passkeys",
|
||||
},
|
||||
{
|
||||
text: "Public link",
|
||||
link: "/photos/features/public-link",
|
||||
|
||||
@@ -97,3 +97,6 @@ your own instead of contacting support to ask them to delete your account.
|
||||
Note that both Ente photos and Ente auth data will be deleted when you delete
|
||||
your account (irrespective of which app you delete it from) since both photos
|
||||
and auth use the same underlying account.
|
||||
|
||||
To know details of how your data is deleted, including when you delete your
|
||||
account, please see https://ente.io/blog/how-ente-deletes-data/.
|
||||
|
||||
62
docs/docs/photos/features/passkeys.md
Normal file
@@ -0,0 +1,62 @@
|
||||
---
|
||||
title: Passkeys
|
||||
description: Using passkeys as a second factor for your Ente account
|
||||
---
|
||||
|
||||
# Passkeys
|
||||
|
||||
> [!CAUTION]
|
||||
>
|
||||
> This is preview documentation for an upcoming feature. This feature has not
|
||||
> yet been released yet, so the steps below will not work currently.
|
||||
|
||||
Passkeys are a new authentication mechanism that uses strong cryptography built
|
||||
into devices, like Windows Hello or Apple's Touch ID. **You can use passkeys as
|
||||
a second factor to secure your Ente account.**
|
||||
|
||||
> [!TIP]
|
||||
>
|
||||
> Passkeys are the colloquial term for a WebAuthn (Web Authentication)
|
||||
> credentials. To know more technical details about how our passkey verification
|
||||
> works, you can see this
|
||||
> [technical note in our source code](https://github.com/ente-io/ente/blob/main/web/docs/webauthn-passkeys.md).
|
||||
|
||||
## Passkeys and TOTP
|
||||
|
||||
Ente already supports TOTP codes (in fact, we built an
|
||||
[entire app](https://ente.io/auth/) to store them...). Passkeys serve as an
|
||||
alternative 2FA (second factor) mechanism.
|
||||
|
||||
If you add a passkey to your Ente account, it will be used instead of any
|
||||
existing 2FA codes that you have configured (if any).
|
||||
|
||||
## Enabling and disabling passkeys
|
||||
|
||||
Passkeys get enabled if you add one (or more) passkeys to your account.
|
||||
Conversely, passkeys get disabled if you remove all your existing passkeys.
|
||||
|
||||
To add and remove passkeys, use the _Passkey_ option in the settings menu. This
|
||||
will open up _accounts.ente.io_, where you can manage your passkeys.
|
||||
|
||||
## Login with passkeys
|
||||
|
||||
If passkeys are enabled, then _accounts.ente.io_ will automatically open when
|
||||
you log into your Ente account on a new device. Here you can follow the
|
||||
instructions given by the browser to verify your passkey.
|
||||
|
||||
> These instructions different for each browser and device, but generally they
|
||||
> will ask you to use the same mechanism that you used when you created the
|
||||
> passkey to verify it (scanning a QR code, using your fingerprint, pressing the
|
||||
> key on your Yubikey or other security key hardware etc).
|
||||
|
||||
## Recovery
|
||||
|
||||
If you are unable to login with your passkey (e.g. if you have misplaced the
|
||||
hardware key that you used to store your passkey), then you can **recover your
|
||||
account by using your Ente recovery key**.
|
||||
|
||||
During login, press cancel on the browser dialog to verify your passkey, and
|
||||
then select the "Recover two-factor" option in the error message that gets
|
||||
shown. This will take you to a place where you can enter your Ente recovery key
|
||||
and login into your account. Now you can go to the _Passkey_ page to delete the
|
||||
lost passkey and/or add a new one.
|
||||
@@ -9,6 +9,9 @@ The latest version of the Ente Photos desktop app can be downloaded from
|
||||
[ente.io/download](https://ente.io/download). If you're having trouble, please
|
||||
see if any of the following cases apply.
|
||||
|
||||
- [Windows](#windows)
|
||||
- [Linux](#linux)
|
||||
|
||||
## Windows
|
||||
|
||||
If the app stops with an "A JavaScript error occurred in the main process - The
|
||||
@@ -22,7 +25,26 @@ This is what the error looks like:
|
||||
You can install the Microsoft VC++ redistributable runtime from here:<br/>
|
||||
https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170#latest-microsoft-visual-c-redistributable-version
|
||||
|
||||
## AppImages on ARM64 Linux
|
||||
## Linux
|
||||
|
||||
### AppImage desktop integration
|
||||
|
||||
AppImages are not fully standalone, and they require additional steps to enable
|
||||
full "desktop integration":
|
||||
|
||||
- Showing the app icon,
|
||||
- Surfacing the app in the list of installed apps,
|
||||
- Handling redirection after passkey verification.
|
||||
|
||||
All the ways of enabling AppImage desktop integration are mentioned in
|
||||
[AppImage documentation](https://docs.appimage.org/user-guide/run-appimages.html#integrating-appimages-into-the-desktop).
|
||||
|
||||
For example, you can download the
|
||||
[appimaged](https://github.com/probonopd/go-appimage/releases) AppImage, run it,
|
||||
and then download the Ente Photos AppImage into your `~/Downloads` folder.
|
||||
_appimaged_ will then pick it up automatically.
|
||||
|
||||
### AppImages on ARM64
|
||||
|
||||
If you're on an ARM64 machine running Linux, and the AppImages doesn't do
|
||||
anything when you run it, you will need to run the following command on your
|
||||
@@ -42,7 +64,7 @@ details, see the following upstream issues:
|
||||
- libz.so: cannot open shared object file with Ubuntu arm64 -
|
||||
[electron-userland/electron-builder/issues/7835](https://github.com/electron-userland/electron-builder/issues/7835)
|
||||
|
||||
## AppImage says it requires FUSE
|
||||
### AppImage says it requires FUSE
|
||||
|
||||
See
|
||||
[docs.appimage.org](https://docs.appimage.org/user-guide/troubleshooting/fuse.html#the-appimage-tells-me-it-needs-fuse-to-run).
|
||||
@@ -53,7 +75,7 @@ tl;dr; for example, on Ubuntu,
|
||||
sudo apt install libfuse2
|
||||
```
|
||||
|
||||
## Linux SUID error
|
||||
### Linux SUID error
|
||||
|
||||
On some Linux distributions, if you run the AppImage from the CLI, it might fail
|
||||
with the following error:
|
||||
|
||||
5623
infra/staff/package-lock.json
generated
@@ -11,23 +11,11 @@
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@date-io/date-fns": "^3.0.0",
|
||||
"@emotion/react": "^11.11.4",
|
||||
"@emotion/styled": "^11.11.5",
|
||||
"@mui/icons-material": "^5.16.0",
|
||||
"@mui/lab": "^5.0.0-alpha.171",
|
||||
"@mui/material": "^5.16.0",
|
||||
"@mui/x-date-pickers": "^7.9.0",
|
||||
"@types/react-datepicker": "^6.2.0",
|
||||
"date-fns": "^3.6.0",
|
||||
"react": "^18",
|
||||
"react-datepicker": "^7.3.0",
|
||||
"react-dom": "^18",
|
||||
"react-toastify": "^10.0.5",
|
||||
"zod": "^3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-node-resolve": "^15.2.3",
|
||||
"@types/react": "^18",
|
||||
"@types/react-dom": "^18",
|
||||
"@typescript-eslint/eslint-plugin": "^7",
|
||||
|
||||
@@ -1,306 +0,0 @@
|
||||
.container {
|
||||
position: relative; /* Ensure the parent is relatively positioned */
|
||||
height: 100vh; /* Full viewport height */
|
||||
width: 100vw; /* Full viewport width */
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.center-table {
|
||||
display: table;
|
||||
}
|
||||
|
||||
.input-form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.horizontal-group {
|
||||
position: absolute; /* Use absolute positioning */
|
||||
top: 32px; /* 32px below the top of the page */
|
||||
left: 32px; /* 32px from the leftmost edge of the page */
|
||||
right: 32px;
|
||||
display: flex;
|
||||
align-items: center; /* Align items vertically centered */
|
||||
gap: 20px; /* Adjust the gap between elements as needed */
|
||||
background-color: #fafafa;
|
||||
height: 104px;
|
||||
width: 1375px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.fetch-button-container button {
|
||||
background-color: #00b33c;
|
||||
color: white;
|
||||
border: none;
|
||||
width: 199px;
|
||||
height: 56px;
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
.fetch-button-container button:hover {
|
||||
background-color: #007c6c;
|
||||
}
|
||||
|
||||
.link-text {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 16px; /* Add padding for better appearance */
|
||||
text-decoration: none; /* Remove underline */
|
||||
color: inherit; /* Inherit color from parent */
|
||||
font-weight: bold; /* Make the text bold */
|
||||
font-size: 40px;
|
||||
}
|
||||
|
||||
.text-field-token {
|
||||
margin-left: 70px !important; /* Adjust margin for Token field */
|
||||
}
|
||||
|
||||
.text-field-email {
|
||||
margin-left: 20px !important; /* Adjust margin for Email field */
|
||||
}
|
||||
.duckie-container {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
.center-content {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh; /* Adjust as necessary */
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.error-message {
|
||||
color: red;
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
.duckie-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.container {
|
||||
position: relative; /* Ensure the parent is relatively positioned */
|
||||
height: 100vh; /* Full viewport height */
|
||||
width: 100vw; /* Full viewport width */
|
||||
display: flex;
|
||||
flex-direction: column; /* Add this */
|
||||
justify-content: center; /* Center vertically */
|
||||
align-items: center; /* Center horizontally */
|
||||
}
|
||||
|
||||
.input-form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
z-index: 1; /* Ensure form is on top */
|
||||
}
|
||||
|
||||
.horizontal-group {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 20px; /* Adjust the gap between elements as needed */
|
||||
background-color: #fafafa;
|
||||
padding: 20px; /* Add padding around content */
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.fetch-button-container button {
|
||||
background-color: #00b33c;
|
||||
color: white;
|
||||
border: none;
|
||||
width: 199px;
|
||||
height: 56px;
|
||||
}
|
||||
|
||||
.fetch-button-container button:hover {
|
||||
background-color: #007c6c;
|
||||
}
|
||||
|
||||
.link-text {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 16px; /* Add padding for better appearance */
|
||||
text-decoration: none; /* Remove underline */
|
||||
color: inherit; /* Inherit color from parent */
|
||||
font-weight: bold; /* Make the text bold */
|
||||
font-size: 40px;
|
||||
}
|
||||
|
||||
.text-field-token {
|
||||
margin-left: 70px !important; /* Adjust margin for Token field */
|
||||
}
|
||||
|
||||
.text-field-email {
|
||||
margin-left: 50px !important; /* Adjust margin for Email field */
|
||||
}
|
||||
|
||||
.center-content {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.duckie-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* Example CSS to maintain tabs fixed position */
|
||||
.tabs-container {
|
||||
position: sticky;
|
||||
top: 20px; /* Adjust as needed */
|
||||
z-index: 1000; /* Ensure tabs are above other content */
|
||||
}
|
||||
.container {
|
||||
position: relative; /* Ensure the parent is relatively positioned */
|
||||
height: 100vh; /* Full viewport height */
|
||||
width: 100vw; /* Full viewport width */
|
||||
display: flex;
|
||||
flex-direction: column; /* Ensure children stack vertically */
|
||||
justify-content: center; /* Center vertically */
|
||||
align-items: center; /* Center horizontally */
|
||||
}
|
||||
|
||||
.input-form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
z-index: 1; /* Ensure form is on top */
|
||||
margin-bottom: 20px; /* Add space between form and tabs */
|
||||
}
|
||||
|
||||
.horizontal-group {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 20px; /* Adjust the gap between elements as needed */
|
||||
background-color: #fafafa;
|
||||
padding: 20px; /* Add padding around content */
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.fetch-button-container button {
|
||||
background-color: #00b33c;
|
||||
color: white;
|
||||
border: none;
|
||||
width: 199px;
|
||||
height: 56px;
|
||||
}
|
||||
|
||||
.fetch-button-container button:hover {
|
||||
background-color: #007c6c;
|
||||
}
|
||||
|
||||
.link-text {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 16px; /* Add padding for better appearance */
|
||||
text-decoration: none; /* Remove underline */
|
||||
color: inherit; /* Inherit color from parent */
|
||||
font-weight: bold; /* Make the text bold */
|
||||
font-size: 40px;
|
||||
}
|
||||
|
||||
.text-field-token {
|
||||
margin-left: 70px !important; /* Adjust margin for Token field */
|
||||
}
|
||||
|
||||
.text-field-email {
|
||||
margin-left: 50px !important; /* Adjust margin for Email field */
|
||||
}
|
||||
|
||||
.center-content {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.duckie-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.tabs-container {
|
||||
position: sticky; /* Make the tabs sticky */
|
||||
top: 0; /* Stick to the top of the viewport */
|
||||
z-index: 1000; /* Ensure tabs are above other content */
|
||||
background-color: #fafafa; /* Optional: Add background color to tabs */
|
||||
padding: 10px 20px; /* Optional: Add padding for better appearance */
|
||||
border-bottom: 1px solid #ccc; /* Optional: Add bottom border */
|
||||
}
|
||||
.dialog-popup-container {
|
||||
/* Styles for the overlay/background */
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.5); /* Semi-transparent black */
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.dialog-popup {
|
||||
background-color: white;
|
||||
padding: 20px;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.dialog-popup-header h2 {
|
||||
margin-bottom: 20px; /* Add space between heading and fields */
|
||||
}
|
||||
|
||||
.dialog-popup-field {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.dialog-popup-field label {
|
||||
display: block;
|
||||
margin-bottom: 5px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.dialog-popup-field input {
|
||||
width: 100%;
|
||||
padding: 8px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.submit-button {
|
||||
background-color: #4caf50; /* Green */
|
||||
color: white;
|
||||
padding: 10px 15px;
|
||||
border: none;
|
||||
border-radius: 3px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Specific styles for each field to match the image */
|
||||
.name-field input,
|
||||
.shortname-field input,
|
||||
.code-field input {
|
||||
width: calc(100% - 100px); /* Adjust as needed */
|
||||
}
|
||||
|
||||
.active-field input {
|
||||
width: 50px;
|
||||
}
|
||||
@@ -1,323 +1,224 @@
|
||||
import Box from "@mui/material/Box";
|
||||
import Button from "@mui/material/Button";
|
||||
import CircularProgress from "@mui/material/CircularProgress";
|
||||
import Tab from "@mui/material/Tab";
|
||||
import Tabs from "@mui/material/Tabs";
|
||||
import TextField from "@mui/material/TextField";
|
||||
import * as React from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import "./App.css";
|
||||
import type { UserData } from "./components/UserComponent";
|
||||
import UserComponent from "./components/UserComponent";
|
||||
import duckieimage from "./components/duckie.png";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { apiOrigin } from "./services/support";
|
||||
import S from "./utils/strings";
|
||||
|
||||
// Define and export email and token variables and their setter functions
|
||||
export let email = "";
|
||||
export let token = "";
|
||||
|
||||
export const setEmail = (newEmail: string) => {
|
||||
email = newEmail;
|
||||
};
|
||||
|
||||
export const setToken = (newToken: string) => {
|
||||
token = newToken;
|
||||
};
|
||||
|
||||
export const getEmail = () => email;
|
||||
export const getToken = () => token;
|
||||
|
||||
interface User {
|
||||
ID: string;
|
||||
email: string;
|
||||
creationTime: number;
|
||||
}
|
||||
|
||||
interface Subscription {
|
||||
productID: string;
|
||||
paymentProvider: string;
|
||||
expiryTime: number;
|
||||
storage: number;
|
||||
}
|
||||
|
||||
interface Security {
|
||||
isEmailMFAEnabled: boolean;
|
||||
isTwoFactorEnabled: boolean;
|
||||
passkeys: string; // Replace with actual passkey value if available
|
||||
}
|
||||
|
||||
interface UserResponse {
|
||||
user: User;
|
||||
subscription: Subscription;
|
||||
details?: {
|
||||
usage?: number;
|
||||
storageBonus?: number;
|
||||
profileData: Security;
|
||||
};
|
||||
}
|
||||
|
||||
const App: React.FC = () => {
|
||||
const [localEmail, setLocalEmail] = useState<string>(getEmail());
|
||||
const [localToken, setLocalToken] = useState<string>(getToken());
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
const [error, setError] = useState<string>("");
|
||||
const [fetchSuccess, setFetchSuccess] = useState<boolean>(false);
|
||||
const [tabValue, setTabValue] = useState<number>(0);
|
||||
const [userData, setUserData] = useState<UserData | null>(null);
|
||||
export const App: React.FC = () => {
|
||||
const [token, setToken] = useState("");
|
||||
const [email, setEmail] = useState("");
|
||||
const [userData, setUserData] = useState<any>(null);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const storedToken = localStorage.getItem("token");
|
||||
if (storedToken) {
|
||||
setToken(storedToken);
|
||||
setLocalToken(storedToken);
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (localToken) {
|
||||
setToken(localToken);
|
||||
localStorage.setItem("token", localToken);
|
||||
if (token) {
|
||||
localStorage.setItem("token", token);
|
||||
} else {
|
||||
localStorage.removeItem("token");
|
||||
}
|
||||
}, [localToken]);
|
||||
|
||||
useEffect(() => {
|
||||
if (localEmail) {
|
||||
setEmail(localEmail);
|
||||
localStorage.setItem("email", localEmail);
|
||||
} else {
|
||||
localStorage.removeItem("email");
|
||||
}
|
||||
}, [localEmail]);
|
||||
}, [token]);
|
||||
|
||||
const fetchData = async () => {
|
||||
setLoading(true);
|
||||
setError("");
|
||||
setFetchSuccess(false);
|
||||
const startTime = Date.now();
|
||||
try {
|
||||
const encodedEmail = encodeURIComponent(localEmail);
|
||||
const encodedToken = encodeURIComponent(localToken);
|
||||
const url = `${apiOrigin}/admin/user?email=${encodedEmail}&token=${encodedToken}`;
|
||||
console.log(`Fetching data from URL: ${url}`);
|
||||
const url = `${apiOrigin}/admin/user?email=${email}&token=${token}`;
|
||||
const response = await fetch(url);
|
||||
if (!response.ok) {
|
||||
throw new Error("Network response was not ok");
|
||||
}
|
||||
const userDataResponse: UserResponse =
|
||||
(await response.json()) as UserResponse;
|
||||
console.log("API Response:", userDataResponse);
|
||||
|
||||
const extractedUserData: UserData = {
|
||||
User: {
|
||||
"User ID": userDataResponse.user.ID || "None",
|
||||
Email: userDataResponse.user.email || "None",
|
||||
"Creation time":
|
||||
new Date(
|
||||
userDataResponse.user.creationTime / 1000,
|
||||
).toLocaleString() || "None",
|
||||
},
|
||||
Storage: {
|
||||
Total: userDataResponse.subscription.storage
|
||||
? userDataResponse.subscription.storage >= 1024 ** 3
|
||||
? `${(userDataResponse.subscription.storage / 1024 ** 3).toFixed(2)} GB`
|
||||
: `${(userDataResponse.subscription.storage / 1024 ** 2).toFixed(2)} MB`
|
||||
: "None",
|
||||
Consumed:
|
||||
userDataResponse.details?.usage !== undefined
|
||||
? userDataResponse.details.usage >= 1024 ** 3
|
||||
? `${(userDataResponse.details.usage / 1024 ** 3).toFixed(2)} GB`
|
||||
: `${(userDataResponse.details.usage / 1024 ** 2).toFixed(2)} MB`
|
||||
: "None",
|
||||
Bonus:
|
||||
userDataResponse.details?.storageBonus !== undefined
|
||||
? userDataResponse.details.storageBonus >= 1024 ** 3
|
||||
? `${(userDataResponse.details.storageBonus / 1024 ** 3).toFixed(2)} GB`
|
||||
: `${(userDataResponse.details.storageBonus / 1024 ** 2).toFixed(2)} MB`
|
||||
: "None",
|
||||
},
|
||||
Subscription: {
|
||||
"Product ID":
|
||||
userDataResponse.subscription.productID || "None",
|
||||
Provider:
|
||||
userDataResponse.subscription.paymentProvider || "None",
|
||||
"Expiry time":
|
||||
new Date(
|
||||
userDataResponse.subscription.expiryTime / 1000,
|
||||
).toLocaleString() || "None",
|
||||
},
|
||||
Security: {
|
||||
"Email MFA": userDataResponse.details?.profileData
|
||||
.isEmailMFAEnabled
|
||||
? "Enabled"
|
||||
: "Disabled",
|
||||
"Two factor 2FA": userDataResponse.details?.profileData
|
||||
.isTwoFactorEnabled
|
||||
? "Enabled"
|
||||
: "Disabled",
|
||||
Passkeys: "None", // Replace with actual passkey value if available
|
||||
},
|
||||
};
|
||||
|
||||
const elapsedTime = Date.now() - startTime;
|
||||
const delay = Math.max(3000 - elapsedTime, 0);
|
||||
setTimeout(() => {
|
||||
setLoading(false);
|
||||
setFetchSuccess(true);
|
||||
setUserData(extractedUserData);
|
||||
}, delay);
|
||||
const userData = await response.json();
|
||||
console.log("API Response:", userData);
|
||||
setUserData(userData);
|
||||
setError(null);
|
||||
} catch (error) {
|
||||
console.error("Error fetching data:", error);
|
||||
const elapsedTime = Date.now() - startTime;
|
||||
const delay = Math.max(3000 - elapsedTime, 0);
|
||||
setTimeout(() => {
|
||||
setLoading(false);
|
||||
setError("Invalid token or email id");
|
||||
}, delay);
|
||||
setError((error as Error).message);
|
||||
}
|
||||
};
|
||||
|
||||
const handleKeyPress = (event: React.KeyboardEvent<HTMLFormElement>) => {
|
||||
if (event.key === "Enter") {
|
||||
event.preventDefault();
|
||||
fetchData().catch((error: unknown) =>
|
||||
console.error("Fetch data error:", error),
|
||||
);
|
||||
}
|
||||
};
|
||||
const renderAttributes = (data: any) => {
|
||||
if (!data) return null;
|
||||
|
||||
const handleTabChange = (
|
||||
_event: React.SyntheticEvent,
|
||||
newValue: number,
|
||||
) => {
|
||||
setTabValue(newValue);
|
||||
let nullAttributes: string[] = [];
|
||||
|
||||
const rows = Object.entries(data).map(([key, value]) => {
|
||||
console.log("Processing key:", key, "value:", value);
|
||||
|
||||
if (
|
||||
typeof value === "object" &&
|
||||
value !== null &&
|
||||
!Array.isArray(value)
|
||||
) {
|
||||
return (
|
||||
<React.Fragment key={key}>
|
||||
<tr>
|
||||
<td
|
||||
colSpan={2}
|
||||
style={{
|
||||
fontWeight: "bold",
|
||||
backgroundColor: "#f1f1f1",
|
||||
padding: "10px",
|
||||
}}
|
||||
>
|
||||
{key.toUpperCase()}
|
||||
</td>
|
||||
</tr>
|
||||
{renderAttributes(value)}
|
||||
</React.Fragment>
|
||||
);
|
||||
} else {
|
||||
if (value === null) {
|
||||
nullAttributes.push(key);
|
||||
}
|
||||
|
||||
let displayValue: React.ReactNode;
|
||||
if (key === "expiryTime" && typeof value === "number") {
|
||||
displayValue = new Date(value / 1000).toLocaleString();
|
||||
} else if (
|
||||
key === "creationTime" &&
|
||||
typeof value === "number"
|
||||
) {
|
||||
displayValue = new Date(value / 1000).toLocaleString();
|
||||
} else if (key === "storage" && typeof value === "number") {
|
||||
displayValue = `${(value / 1024 ** 3).toFixed(2)} GB`;
|
||||
} else if (typeof value === "string") {
|
||||
try {
|
||||
const parsedValue = JSON.parse(value);
|
||||
displayValue = parsedValue;
|
||||
} catch (error) {
|
||||
displayValue = value;
|
||||
}
|
||||
} else if (value === null) {
|
||||
displayValue = "null";
|
||||
} else if (typeof value !== "undefined") {
|
||||
displayValue = value.toString();
|
||||
} else {
|
||||
displayValue = "undefined";
|
||||
}
|
||||
|
||||
return (
|
||||
<tr key={key}>
|
||||
<td
|
||||
style={{
|
||||
padding: "10px",
|
||||
border: "1px solid #ddd",
|
||||
}}
|
||||
>
|
||||
{key}
|
||||
</td>
|
||||
<td
|
||||
style={{
|
||||
padding: "10px",
|
||||
border: "1px solid #ddd",
|
||||
}}
|
||||
>
|
||||
{displayValue}
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
console.log("Attributes with null values:", nullAttributes);
|
||||
|
||||
return rows;
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="container center-table">
|
||||
<form className="input-form" onKeyPress={handleKeyPress}>
|
||||
<div className="horizontal-group">
|
||||
<a
|
||||
href="https://staff.ente.sh"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="link-text"
|
||||
>
|
||||
staff.ente.sh
|
||||
</a>
|
||||
<h1>{S.hello}</h1>
|
||||
|
||||
<TextField
|
||||
label="Token"
|
||||
value={localToken}
|
||||
onChange={(e) => {
|
||||
setLocalToken(e.target.value);
|
||||
setToken(e.target.value);
|
||||
}}
|
||||
size="medium"
|
||||
className="text-field-token"
|
||||
style={{ width: "350px" }}
|
||||
/>
|
||||
<TextField
|
||||
label="Email"
|
||||
value={localEmail}
|
||||
onChange={(e) => {
|
||||
setLocalEmail(e.target.value);
|
||||
setEmail(e.target.value);
|
||||
}}
|
||||
size="medium"
|
||||
className="text-field-email"
|
||||
style={{ width: "350px" }}
|
||||
/>
|
||||
<div className="fetch-button-container">
|
||||
<Button
|
||||
variant="contained"
|
||||
onClick={() => {
|
||||
fetchData().catch((error: unknown) =>
|
||||
console.error("Fetch data error:", error),
|
||||
);
|
||||
}}
|
||||
className="fetch-button"
|
||||
<form className="input-form">
|
||||
<div className="input-group">
|
||||
<label>
|
||||
Token:
|
||||
<input
|
||||
type="text"
|
||||
value={token}
|
||||
onChange={(e) => setToken(e.target.value)}
|
||||
style={{
|
||||
padding: "0 16px",
|
||||
padding: "10px",
|
||||
margin: "10px",
|
||||
width: "100%",
|
||||
}}
|
||||
>
|
||||
FETCH
|
||||
</Button>
|
||||
</div>
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
<div className="input-group">
|
||||
<label>
|
||||
Email id:
|
||||
<input
|
||||
type="text"
|
||||
value={email}
|
||||
onChange={(e) => setEmail(e.target.value)}
|
||||
style={{
|
||||
padding: "10px",
|
||||
margin: "10px",
|
||||
width: "100%",
|
||||
}}
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
</form>
|
||||
<div className="content-container">
|
||||
{loading ? (
|
||||
<CircularProgress sx={{ color: "black" }} />
|
||||
) : error ? (
|
||||
<div className="error-message">{error}</div>
|
||||
) : fetchSuccess ? (
|
||||
<>
|
||||
<Box
|
||||
sx={{
|
||||
width: "100%",
|
||||
maxWidth: "600px",
|
||||
bgcolor: "#FAFAFA",
|
||||
marginTop: "300px",
|
||||
borderRadius: "7px",
|
||||
position: "relative",
|
||||
zIndex: 1000,
|
||||
}}
|
||||
>
|
||||
<Tabs
|
||||
value={tabValue}
|
||||
onChange={handleTabChange}
|
||||
centered
|
||||
sx={{
|
||||
"& .MuiTabs-indicator": {
|
||||
backgroundColor: "#00B33C",
|
||||
height: "5px",
|
||||
borderRadius: "20px",
|
||||
},
|
||||
"& .MuiTab-root": {
|
||||
textTransform: "none",
|
||||
},
|
||||
"& .Mui-selected": {
|
||||
color: "black !important",
|
||||
},
|
||||
"& .MuiTab-root.Mui-selected": {
|
||||
color: "black !important",
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Tab label="User" />
|
||||
<Tab label="Family" />
|
||||
<Tab label="Bonuses" />
|
||||
</Tabs>
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
width: "100%",
|
||||
maxWidth: "600px",
|
||||
mt: 4,
|
||||
minHeight: "400px",
|
||||
}}
|
||||
>
|
||||
{tabValue === 0 && (
|
||||
<UserComponent userData={userData} />
|
||||
)}
|
||||
{tabValue === 1 && <div>Family tab content</div>}
|
||||
{tabValue === 2 && <div>Bonuses tab content</div>}
|
||||
</Box>
|
||||
</>
|
||||
) : (
|
||||
<div className="duckie-container">
|
||||
<img
|
||||
src={duckieimage}
|
||||
alt="Duckie"
|
||||
className="duckie-image"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div className="fetch-button">
|
||||
<button
|
||||
onClick={fetchData}
|
||||
style={{
|
||||
padding: "10px 20px",
|
||||
fontSize: "16px",
|
||||
cursor: "pointer",
|
||||
backgroundColor: "#009879",
|
||||
color: "white",
|
||||
border: "none",
|
||||
borderRadius: "5px",
|
||||
}}
|
||||
>
|
||||
FETCH
|
||||
</button>
|
||||
</div>
|
||||
<br />
|
||||
{error && <p style={{ color: "red" }}>{`Error: ${error}`}</p>}
|
||||
{userData && (
|
||||
<table
|
||||
style={{
|
||||
width: "100%",
|
||||
borderCollapse: "collapse",
|
||||
margin: "20px 0",
|
||||
fontSize: "1em",
|
||||
minWidth: "400px",
|
||||
boxShadow: "0 0 20px rgba(0, 0, 0, 0.15)",
|
||||
}}
|
||||
>
|
||||
<tbody>
|
||||
{Object.keys(userData).map((category) => (
|
||||
<React.Fragment key={category}>
|
||||
<tr>
|
||||
<td
|
||||
colSpan={2}
|
||||
style={{
|
||||
fontWeight: "bold",
|
||||
backgroundColor: "#f1f1f1",
|
||||
padding: "10px",
|
||||
}}
|
||||
>
|
||||
{category.toUpperCase()}
|
||||
</td>
|
||||
</tr>
|
||||
{renderAttributes(userData[category])}
|
||||
</React.Fragment>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
)}
|
||||
<footer className="footer">
|
||||
<p>
|
||||
<a href="https://help.ente.io">help.ente.io</a>
|
||||
</p>
|
||||
</footer>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default App;
|
||||
|
||||
@@ -1,192 +0,0 @@
|
||||
import CloseIcon from "@mui/icons-material/Close";
|
||||
import {
|
||||
Button,
|
||||
Dialog,
|
||||
DialogActions,
|
||||
DialogContent,
|
||||
DialogTitle,
|
||||
TextField,
|
||||
} from "@mui/material";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { getEmail, getToken } from "../App";
|
||||
import { apiOrigin } from "../services/support";
|
||||
interface ErrorResponse {
|
||||
message: string;
|
||||
}
|
||||
|
||||
interface ChangeEmailProps {
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
}
|
||||
|
||||
interface UserDataResponse {
|
||||
subscription: {
|
||||
userID: string;
|
||||
} | null;
|
||||
}
|
||||
|
||||
const ChangeEmail: React.FC<ChangeEmailProps> = ({ open, onClose }) => {
|
||||
const [newEmail, setNewEmail] = useState<string>("");
|
||||
const [userID, setUserID] = useState<string>("");
|
||||
|
||||
useEffect(() => {
|
||||
const fetchUserID = async () => {
|
||||
const token = getToken();
|
||||
const email = getEmail();
|
||||
setNewEmail(email); // Set initial email state
|
||||
|
||||
const encodedEmail = encodeURIComponent(email);
|
||||
const encodedToken = encodeURIComponent(token);
|
||||
const url = `${apiOrigin}/admin/user?email=${encodedEmail}&token=${encodedToken}`;
|
||||
|
||||
try {
|
||||
const response = await fetch(url, {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"X-AUTH-TOKEN": token,
|
||||
},
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Network response was not ok");
|
||||
}
|
||||
|
||||
const data = (await response.json()) as UserDataResponse;
|
||||
if (data.subscription) {
|
||||
setUserID(data.subscription.userID); // Update userID state
|
||||
} else {
|
||||
throw new Error("Subscription data not found");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error fetching user ID:", error);
|
||||
}
|
||||
};
|
||||
|
||||
if (open) {
|
||||
fetchUserID().catch((error: unknown) =>
|
||||
console.error("Error in fetchUserID:", error),
|
||||
);
|
||||
}
|
||||
}, [open]);
|
||||
|
||||
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setNewEmail(event.target.value); // Update newEmail state on input change
|
||||
};
|
||||
|
||||
const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
|
||||
event.preventDefault();
|
||||
|
||||
const token = getToken();
|
||||
const url = `${apiOrigin}/admin/user/change-email?token=${token}`;
|
||||
|
||||
const body = {
|
||||
userID,
|
||||
email: newEmail,
|
||||
};
|
||||
|
||||
try {
|
||||
const response = await fetch(url, {
|
||||
method: "PUT",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"X-AUTH-TOKEN": token,
|
||||
},
|
||||
body: JSON.stringify(body),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
let errorData;
|
||||
try {
|
||||
errorData = (await response.json()) as ErrorResponse;
|
||||
} catch (error) {
|
||||
console.error("Error parsing error response:", error);
|
||||
}
|
||||
throw new Error(
|
||||
errorData?.message ?? "Network response was not ok",
|
||||
);
|
||||
}
|
||||
|
||||
console.log("Email updated successfully");
|
||||
onClose();
|
||||
} catch (error) {
|
||||
console.error("Error updating email:", error);
|
||||
}
|
||||
};
|
||||
const handleSubmitSync: React.FormEventHandler<HTMLFormElement> = (
|
||||
event,
|
||||
) => {
|
||||
handleSubmit(event).catch((error: unknown) => {
|
||||
console.error("Error in handleSubmit:", error);
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
open={open}
|
||||
onClose={onClose}
|
||||
BackdropProps={{
|
||||
style: {
|
||||
backdropFilter: "blur(5px)",
|
||||
backgroundColor: "rgba(255, 255, 255, 0.8)",
|
||||
},
|
||||
}}
|
||||
PaperProps={{
|
||||
style: {
|
||||
width: "444px",
|
||||
height: "300px",
|
||||
},
|
||||
}}
|
||||
>
|
||||
<DialogTitle style={{ marginBottom: "20px", marginTop: "20px" }}>
|
||||
Change Email
|
||||
<Button
|
||||
onClick={onClose}
|
||||
style={{ position: "absolute", right: 10, top: 10 }}
|
||||
>
|
||||
<CloseIcon style={{ color: "black" }} />
|
||||
</Button>
|
||||
</DialogTitle>
|
||||
<DialogContent>
|
||||
<form onSubmit={handleSubmitSync}>
|
||||
<div style={{ marginBottom: "16px" }}>
|
||||
<label
|
||||
htmlFor="newEmail"
|
||||
style={{
|
||||
textAlign: "left",
|
||||
display: "block",
|
||||
marginBottom: "4px",
|
||||
}}
|
||||
>
|
||||
Email
|
||||
</label>
|
||||
<TextField
|
||||
id="newEmail"
|
||||
name="newEmail"
|
||||
value={newEmail}
|
||||
onChange={handleChange}
|
||||
fullWidth
|
||||
/>
|
||||
</div>
|
||||
|
||||
<DialogActions
|
||||
style={{ justifyContent: "center", marginTop: "40px" }}
|
||||
>
|
||||
<Button
|
||||
type="submit"
|
||||
variant="contained"
|
||||
style={{
|
||||
backgroundColor: "#00B33C",
|
||||
color: "white",
|
||||
}}
|
||||
>
|
||||
Change Email
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</form>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
|
||||
export default ChangeEmail;
|
||||
@@ -1,100 +0,0 @@
|
||||
import {
|
||||
Button,
|
||||
Dialog,
|
||||
DialogActions,
|
||||
DialogContent,
|
||||
DialogContentText,
|
||||
DialogTitle,
|
||||
Paper,
|
||||
} from "@mui/material";
|
||||
import React from "react";
|
||||
import { getEmail, getToken } from "../App"; // Import getEmail and getToken functions
|
||||
import { apiOrigin } from "../services/support";
|
||||
|
||||
interface DeleteAccountProps {
|
||||
open: boolean;
|
||||
handleClose: () => void;
|
||||
}
|
||||
|
||||
const DeleteAccount: React.FC<DeleteAccountProps> = ({ open, handleClose }) => {
|
||||
const handleDelete = async () => {
|
||||
try {
|
||||
const encodedEmail = encodeURIComponent(getEmail());
|
||||
console.log(encodedEmail);
|
||||
const encodedToken = encodeURIComponent(getToken());
|
||||
console.log(encodedToken);
|
||||
const deleteUrl = `${apiOrigin}/admin/user/delete?email=${encodedEmail}&token=${encodedToken}`;
|
||||
const response = await fetch(deleteUrl, { method: "DELETE" });
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to delete user account");
|
||||
}
|
||||
handleClose(); // Close dialog on successful delete
|
||||
console.log("Account deleted successfully");
|
||||
} catch (error) {
|
||||
console.error("Error deleting user account:", error);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Dialog
|
||||
open={open}
|
||||
onClose={handleClose}
|
||||
aria-labelledby="alert-dialog-title"
|
||||
aria-describedby="alert-dialog-description"
|
||||
PaperComponent={Paper}
|
||||
sx={{
|
||||
width: "499px",
|
||||
height: "286px",
|
||||
margin: "auto",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
}}
|
||||
BackdropProps={{
|
||||
style: {
|
||||
backgroundColor: "rgba(255, 255, 255, 0.9)", // Semi-transparent backdrop
|
||||
},
|
||||
}}
|
||||
>
|
||||
<DialogTitle id="alert-dialog-title">
|
||||
{"Delete Account?"}
|
||||
</DialogTitle>
|
||||
<DialogContent>
|
||||
<DialogContentText id="alert-dialog-description">
|
||||
Are you sure you want to delete the account?
|
||||
</DialogContentText>
|
||||
</DialogContent>
|
||||
<DialogActions sx={{ justifyContent: "center" }}>
|
||||
<Button
|
||||
onClick={handleClose}
|
||||
sx={{
|
||||
bgcolor: "white",
|
||||
color: "black",
|
||||
"&:hover": { bgcolor: "#FAFAFA" },
|
||||
}}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => {
|
||||
handleDelete().catch((error: unknown) =>
|
||||
console.error("Fetch data error:", error),
|
||||
);
|
||||
}}
|
||||
sx={{
|
||||
bgcolor: "#F4473D",
|
||||
color: "white",
|
||||
"&:hover": { bgcolor: "#E53935" },
|
||||
}}
|
||||
>
|
||||
Delete{" "}
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default DeleteAccount;
|
||||
@@ -1,156 +0,0 @@
|
||||
import {
|
||||
Button,
|
||||
Dialog,
|
||||
DialogActions,
|
||||
DialogContent,
|
||||
DialogContentText,
|
||||
DialogTitle,
|
||||
Paper,
|
||||
} from "@mui/material";
|
||||
import React, { useState } from "react";
|
||||
import { getEmail, getToken } from "../App"; // Import getEmail and getToken functions
|
||||
import { apiOrigin } from "../services/support";
|
||||
|
||||
interface UserData {
|
||||
subscription?: {
|
||||
userID: string;
|
||||
// Add other properties as per your API response structure
|
||||
};
|
||||
// Add other properties as per your API response structure
|
||||
}
|
||||
|
||||
interface Disable2FAProps {
|
||||
open: boolean;
|
||||
handleClose: () => void;
|
||||
handleDisable2FA: () => void; // Callback to handle 2FA disablement
|
||||
}
|
||||
|
||||
const Disable2FA: React.FC<Disable2FAProps> = ({
|
||||
open,
|
||||
handleClose,
|
||||
handleDisable2FA,
|
||||
}) => {
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
const handleDisable = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
const email = getEmail();
|
||||
const token = getToken();
|
||||
|
||||
if (!email) {
|
||||
throw new Error("Email not found");
|
||||
}
|
||||
|
||||
if (!token) {
|
||||
throw new Error("Token not found");
|
||||
}
|
||||
|
||||
const encodedEmail = encodeURIComponent(email);
|
||||
const encodedToken = encodeURIComponent(token);
|
||||
|
||||
// Fetch user data
|
||||
const userUrl = `${apiOrigin}/admin/user?email=${encodedEmail}&token=${encodedToken}`;
|
||||
const userResponse = await fetch(userUrl);
|
||||
if (!userResponse.ok) {
|
||||
throw new Error("Failed to fetch user data");
|
||||
}
|
||||
const userData = (await userResponse.json()) as UserData;
|
||||
const userId = userData.subscription?.userID;
|
||||
|
||||
if (!userId) {
|
||||
throw new Error("User ID not found");
|
||||
}
|
||||
|
||||
// Disable 2FA
|
||||
const disableUrl = `${apiOrigin}/admin/user/disable-2fa?token=${encodedToken}`;
|
||||
const body = JSON.stringify({ userId });
|
||||
const disableResponse = await fetch(disableUrl, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: body,
|
||||
});
|
||||
|
||||
if (!disableResponse.ok) {
|
||||
const errorResponse = await disableResponse.text();
|
||||
throw new Error(`Failed to disable 2FA: ${errorResponse}`);
|
||||
}
|
||||
|
||||
handleDisable2FA(); // Notify parent component of successful disable
|
||||
handleClose(); // Close dialog on successful disable
|
||||
console.log("2FA disabled successfully");
|
||||
} catch (error) {
|
||||
console.error("Error disabling 2FA:", error);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleCancel = () => {
|
||||
handleClose(); // Close dialog
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Dialog
|
||||
open={open}
|
||||
onClose={handleClose}
|
||||
aria-labelledby="alert-dialog-title"
|
||||
aria-describedby="alert-dialog-description"
|
||||
PaperComponent={Paper}
|
||||
sx={{
|
||||
width: "499px",
|
||||
height: "286px",
|
||||
margin: "auto",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
}}
|
||||
BackdropProps={{
|
||||
style: {
|
||||
backgroundColor: "rgba(255, 255, 255, 0.9)", // Semi-transparent backdrop
|
||||
},
|
||||
}}
|
||||
>
|
||||
<DialogTitle id="alert-dialog-title">
|
||||
{"Disable 2FA?"}
|
||||
</DialogTitle>
|
||||
<DialogContent>
|
||||
<DialogContentText id="alert-dialog-description">
|
||||
Are you sure you want to disable 2FA for this account?
|
||||
</DialogContentText>
|
||||
</DialogContent>
|
||||
<DialogActions sx={{ justifyContent: "center" }}>
|
||||
<Button
|
||||
onClick={handleCancel}
|
||||
sx={{
|
||||
bgcolor: "white",
|
||||
color: "black",
|
||||
"&:hover": { bgcolor: "#FAFAFA" },
|
||||
}}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => {
|
||||
handleDisable().catch((error: unknown) =>
|
||||
console.error(error),
|
||||
);
|
||||
}}
|
||||
sx={{
|
||||
bgcolor: "#F4473D",
|
||||
color: "white",
|
||||
"&:hover": { bgcolor: "#E53935" },
|
||||
}}
|
||||
disabled={loading}
|
||||
>
|
||||
{loading ? "Disabling..." : "Disable"}
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Disable2FA;
|
||||
@@ -1,367 +0,0 @@
|
||||
import CalendarTodayIcon from "@mui/icons-material/CalendarToday";
|
||||
import CloseIcon from "@mui/icons-material/Close";
|
||||
import Button from "@mui/material/Button";
|
||||
import Dialog from "@mui/material/Dialog";
|
||||
import DialogActions from "@mui/material/DialogActions";
|
||||
import DialogContent from "@mui/material/DialogContent";
|
||||
import DialogTitle from "@mui/material/DialogTitle";
|
||||
import Grid from "@mui/material/Grid";
|
||||
import InputAdornment from "@mui/material/InputAdornment";
|
||||
import MenuItem from "@mui/material/MenuItem";
|
||||
import Select, { type SelectChangeEvent } from "@mui/material/Select";
|
||||
import TextField from "@mui/material/TextField";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import DatePicker from "react-datepicker";
|
||||
import "react-datepicker/dist/react-datepicker.css";
|
||||
import { getEmail, getToken } from "../App";
|
||||
import { apiOrigin } from "../services/support";
|
||||
interface Subscription {
|
||||
productID: string;
|
||||
paymentProvider: string;
|
||||
storage: number;
|
||||
originalTransactionID: string;
|
||||
expiryTime: number;
|
||||
userID: string;
|
||||
}
|
||||
|
||||
interface UserDataResponse {
|
||||
subscription: Subscription | null;
|
||||
}
|
||||
|
||||
interface UpdateSubscriptionProps {
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
}
|
||||
|
||||
interface FormValues {
|
||||
productId: string;
|
||||
provider: string;
|
||||
storage: number;
|
||||
transactionId: string;
|
||||
expiryTime: string | Date | null;
|
||||
userId: string;
|
||||
}
|
||||
|
||||
const UpdateSubscription: React.FC<UpdateSubscriptionProps> = ({
|
||||
open,
|
||||
onClose,
|
||||
}) => {
|
||||
const [values, setValues] = useState<FormValues>({
|
||||
productId: "",
|
||||
provider: "",
|
||||
storage: 0,
|
||||
transactionId: "",
|
||||
expiryTime: "",
|
||||
userId: "",
|
||||
});
|
||||
|
||||
const [isDatePickerOpen, setIsDatePickerOpen] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
const email = getEmail();
|
||||
const token = getToken();
|
||||
const encodedEmail = encodeURIComponent(email);
|
||||
const encodedToken = encodeURIComponent(token);
|
||||
const url = `${apiOrigin}/admin/user?email=${encodedEmail}&token=${encodedToken}`;
|
||||
|
||||
const response = await fetch(url);
|
||||
if (!response.ok) {
|
||||
throw new Error("Network response was not ok");
|
||||
}
|
||||
const userDataResponse =
|
||||
(await response.json()) as UserDataResponse;
|
||||
|
||||
if (!userDataResponse.subscription) {
|
||||
throw new Error("Subscription data not found");
|
||||
}
|
||||
|
||||
const expiryTime = new Date(
|
||||
userDataResponse.subscription.expiryTime / 1000,
|
||||
);
|
||||
|
||||
setValues({
|
||||
productId: userDataResponse.subscription.productID || "",
|
||||
provider:
|
||||
userDataResponse.subscription.paymentProvider || "",
|
||||
storage:
|
||||
userDataResponse.subscription.storage /
|
||||
(1024 * 1024 * 1024) || 0,
|
||||
transactionId:
|
||||
userDataResponse.subscription.originalTransactionID ||
|
||||
"",
|
||||
expiryTime: expiryTime,
|
||||
userId: userDataResponse.subscription.userID || "",
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Error fetching data:", error);
|
||||
}
|
||||
};
|
||||
|
||||
fetchData().catch((error: unknown) => {
|
||||
console.error("Unhandled promise rejection:", error);
|
||||
});
|
||||
}, []);
|
||||
|
||||
const handleCalendarClick = () => {
|
||||
setIsDatePickerOpen(true);
|
||||
};
|
||||
|
||||
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const { name, value } = event.target;
|
||||
setValues({
|
||||
...values,
|
||||
[name]: name === "storage" ? parseInt(value, 10) : value,
|
||||
});
|
||||
};
|
||||
|
||||
const handleChangeProvider = (event: SelectChangeEvent) => {
|
||||
const { name, value } = event.target;
|
||||
|
||||
if (name) {
|
||||
setValues({
|
||||
...values,
|
||||
[name]: value,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const handleDatePickerChange = (date: Date | null) => {
|
||||
setValues({
|
||||
...values,
|
||||
expiryTime: date,
|
||||
});
|
||||
setIsDatePickerOpen(false);
|
||||
};
|
||||
|
||||
const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
|
||||
event.preventDefault();
|
||||
(async () => {
|
||||
const token = getToken();
|
||||
const url = `${apiOrigin}/admin/user/subscription`;
|
||||
|
||||
let expiryTime = null;
|
||||
if (values.expiryTime instanceof Date) {
|
||||
const utcExpiryTime = new Date(values.expiryTime);
|
||||
expiryTime = utcExpiryTime.getTime() * 1000;
|
||||
}
|
||||
|
||||
const body = {
|
||||
userId: values.userId,
|
||||
storage: values.storage * (1024 * 1024 * 1024),
|
||||
expiryTime: expiryTime,
|
||||
productId: values.productId,
|
||||
paymentProvider: values.provider,
|
||||
transactionId: values.transactionId,
|
||||
};
|
||||
|
||||
try {
|
||||
const response = await fetch(url, {
|
||||
method: "PUT",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"X-AUTH-TOKEN": token,
|
||||
},
|
||||
body: JSON.stringify(body),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Network response was not ok");
|
||||
}
|
||||
console.log("Subscription updated successfully");
|
||||
onClose();
|
||||
} catch (error) {
|
||||
console.error("Error updating subscription:", error);
|
||||
}
|
||||
})().catch((error: unknown) => {
|
||||
console.error("Unhandled promise rejection:", error);
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
open={open}
|
||||
onClose={onClose}
|
||||
BackdropProps={{
|
||||
style: {
|
||||
backdropFilter: "blur(5px)",
|
||||
backgroundColor: "rgba(255, 255, 255, 0.8)",
|
||||
},
|
||||
}}
|
||||
>
|
||||
<DialogTitle style={{ marginBottom: "20px", marginTop: "20px" }}>
|
||||
Update Subscription
|
||||
<Button
|
||||
onClick={onClose}
|
||||
style={{ position: "absolute", right: 10, top: 10 }}
|
||||
>
|
||||
<CloseIcon style={{ color: "black" }} />
|
||||
</Button>
|
||||
</DialogTitle>
|
||||
<DialogContent>
|
||||
<form onSubmit={handleSubmit}>
|
||||
<Grid container spacing={4}>
|
||||
<Grid item xs={6}>
|
||||
<div style={{ marginBottom: "8px" }}>
|
||||
<label
|
||||
htmlFor="productId"
|
||||
style={{
|
||||
textAlign: "left",
|
||||
display: "block",
|
||||
marginBottom: "4px",
|
||||
}}
|
||||
>
|
||||
Product ID
|
||||
</label>
|
||||
<TextField
|
||||
id="productId"
|
||||
name="productId"
|
||||
value={values.productId}
|
||||
onChange={handleChange}
|
||||
fullWidth
|
||||
/>
|
||||
</div>
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
<div style={{ marginBottom: "8px" }}>
|
||||
<label
|
||||
htmlFor="provider"
|
||||
style={{
|
||||
textAlign: "left",
|
||||
display: "block",
|
||||
marginBottom: "4px",
|
||||
}}
|
||||
>
|
||||
Provider
|
||||
</label>
|
||||
<Select
|
||||
id="provider"
|
||||
name="provider"
|
||||
value={values.provider}
|
||||
onChange={handleChangeProvider}
|
||||
fullWidth
|
||||
style={{ textAlign: "left" }}
|
||||
>
|
||||
<MenuItem value="stripe">Stripe</MenuItem>
|
||||
<MenuItem value="paypal">PayPal</MenuItem>
|
||||
<MenuItem value="bitpay">BitPay</MenuItem>
|
||||
</Select>
|
||||
</div>
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
<div style={{ marginBottom: "8px" }}>
|
||||
<label
|
||||
htmlFor="storage"
|
||||
style={{
|
||||
textAlign: "left",
|
||||
display: "block",
|
||||
marginBottom: "4px",
|
||||
}}
|
||||
>
|
||||
Storage (GB)
|
||||
</label>
|
||||
<TextField
|
||||
id="storage"
|
||||
name="storage"
|
||||
type="number"
|
||||
value={values.storage}
|
||||
onChange={handleChange}
|
||||
fullWidth
|
||||
/>
|
||||
</div>
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
<div style={{ marginBottom: "8px" }}>
|
||||
<label
|
||||
htmlFor="transactionId"
|
||||
style={{
|
||||
textAlign: "left",
|
||||
display: "block",
|
||||
marginBottom: "4px",
|
||||
}}
|
||||
>
|
||||
Transaction ID
|
||||
</label>
|
||||
<TextField
|
||||
id="transactionId"
|
||||
name="transactionId"
|
||||
value={values.transactionId}
|
||||
onChange={handleChange}
|
||||
fullWidth
|
||||
/>
|
||||
</div>
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
<div style={{ marginBottom: "8px" }}>
|
||||
<label
|
||||
htmlFor="expiryTime"
|
||||
style={{
|
||||
textAlign: "left",
|
||||
display: "block",
|
||||
marginBottom: "4px",
|
||||
}}
|
||||
>
|
||||
Expiry Time
|
||||
</label>
|
||||
<TextField
|
||||
id="expiryTime"
|
||||
name="expiryTime"
|
||||
value={
|
||||
values.expiryTime instanceof Date
|
||||
? values.expiryTime.toLocaleDateString(
|
||||
"en-GB",
|
||||
)
|
||||
: ""
|
||||
}
|
||||
onClick={handleCalendarClick}
|
||||
InputProps={{
|
||||
endAdornment: (
|
||||
<InputAdornment position="end">
|
||||
<CalendarTodayIcon />
|
||||
</InputAdornment>
|
||||
),
|
||||
readOnly: true,
|
||||
}}
|
||||
fullWidth
|
||||
/>
|
||||
{isDatePickerOpen && (
|
||||
<DatePicker
|
||||
showYearDropdown
|
||||
scrollableYearDropdown
|
||||
yearDropdownItemNumber={15}
|
||||
selected={
|
||||
values.expiryTime instanceof Date
|
||||
? values.expiryTime
|
||||
: null
|
||||
}
|
||||
onChange={handleDatePickerChange}
|
||||
onClickOutside={() =>
|
||||
setIsDatePickerOpen(false)
|
||||
}
|
||||
withPortal
|
||||
inline
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<DialogActions style={{ justifyContent: "center" }}>
|
||||
<Button
|
||||
type="submit"
|
||||
variant="contained"
|
||||
style={{
|
||||
backgroundColor: "#00B33C",
|
||||
color: "white",
|
||||
}}
|
||||
>
|
||||
Update
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</form>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
|
||||
export default UpdateSubscription;
|
||||
@@ -1,335 +0,0 @@
|
||||
import DeleteIcon from "@mui/icons-material/Delete";
|
||||
import EditIcon from "@mui/icons-material/Edit";
|
||||
import Box from "@mui/material/Box";
|
||||
import Grid from "@mui/material/Grid";
|
||||
import IconButton from "@mui/material/IconButton";
|
||||
import Paper from "@mui/material/Paper";
|
||||
import Switch from "@mui/material/Switch";
|
||||
import Table from "@mui/material/Table";
|
||||
import TableBody from "@mui/material/TableBody";
|
||||
import TableCell from "@mui/material/TableCell";
|
||||
import TableContainer from "@mui/material/TableContainer";
|
||||
import TableRow from "@mui/material/TableRow";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import * as React from "react";
|
||||
import ChangeEmail from "./ChangeEmail";
|
||||
import DeleteAccount from "./DeleteAccont";
|
||||
import Disable2FA from "./Disable2FA";
|
||||
import UpdateSubscription from "./UpdateSubscription";
|
||||
|
||||
export interface UserData {
|
||||
User: Record<string, string>;
|
||||
Storage: Record<string, string>;
|
||||
Subscription: Record<string, string>;
|
||||
Security: Record<string, string>;
|
||||
}
|
||||
|
||||
interface UserComponentProps {
|
||||
userData: UserData | null;
|
||||
}
|
||||
|
||||
const UserComponent: React.FC<UserComponentProps> = ({ userData }) => {
|
||||
const [deleteAccountOpen, setDeleteAccountOpen] = React.useState(false);
|
||||
const [disable2FAOpen, setDisable2FAOpen] = React.useState(false);
|
||||
const [twoFactorEnabled, setTwoFactorEnabled] = React.useState(false);
|
||||
const [is2FADisabled, setIs2FADisabled] = React.useState(false);
|
||||
const [updateSubscriptionOpen, setUpdateSubscriptionOpen] =
|
||||
React.useState(false);
|
||||
const [changeEmailOpen, setChangeEmailOpen] = React.useState(false); // State for ChangeEmail dialog
|
||||
|
||||
React.useEffect(() => {
|
||||
if (userData?.Security["Two factor 2FA"] === "Enabled") {
|
||||
setTwoFactorEnabled(true);
|
||||
} else {
|
||||
setTwoFactorEnabled(false);
|
||||
}
|
||||
}, [userData]);
|
||||
|
||||
const handleEditEmail = () => {
|
||||
console.log("Edit Email clicked");
|
||||
setChangeEmailOpen(true);
|
||||
};
|
||||
|
||||
const handleCloseChangeEmail = () => {
|
||||
setChangeEmailOpen(false); // Close ChangeEmail dialog
|
||||
};
|
||||
|
||||
const handleDeleteAccountClick = () => {
|
||||
setDeleteAccountOpen(true);
|
||||
};
|
||||
|
||||
const handleCloseDeleteAccount = () => {
|
||||
setDeleteAccountOpen(false);
|
||||
};
|
||||
|
||||
const handleOpenDisable2FA = () => {
|
||||
setDisable2FAOpen(true);
|
||||
};
|
||||
|
||||
const handleCloseDisable2FA = () => {
|
||||
setDisable2FAOpen(false);
|
||||
};
|
||||
|
||||
const handleDisable2FA = () => {
|
||||
setIs2FADisabled(true);
|
||||
};
|
||||
|
||||
const handleCancelDisable2FA = () => {
|
||||
setTwoFactorEnabled(true);
|
||||
handleCloseDisable2FA();
|
||||
};
|
||||
|
||||
const handleEditSubscription = () => {
|
||||
setUpdateSubscriptionOpen(true);
|
||||
};
|
||||
|
||||
const handleCloseUpdateSubscription = () => {
|
||||
setUpdateSubscriptionOpen(false);
|
||||
};
|
||||
|
||||
if (!userData) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Grid container spacing={6} justifyContent="center">
|
||||
{Object.entries(userData).map(([title, data]) => (
|
||||
<Grid item xs={12} sm={10} md={6} key={title}>
|
||||
<TableContainer
|
||||
component={Paper}
|
||||
variant="outlined"
|
||||
sx={{
|
||||
minHeight: 300,
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
marginBottom: "20px",
|
||||
height: "100%",
|
||||
width: "100%",
|
||||
padding: "13px",
|
||||
"&:not(:last-child)": {
|
||||
marginBottom: "40px",
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
padding: "16px",
|
||||
width: "100%",
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
variant="h6"
|
||||
component="div"
|
||||
sx={{
|
||||
fontWeight: "bold",
|
||||
textAlign: "center",
|
||||
width: "100%",
|
||||
}}
|
||||
>
|
||||
{title}
|
||||
</Typography>
|
||||
{title === "User" && (
|
||||
<IconButton
|
||||
edge="start"
|
||||
aria-label="delete"
|
||||
onClick={handleDeleteAccountClick}
|
||||
>
|
||||
<DeleteIcon style={{ color: "" }} />
|
||||
</IconButton>
|
||||
)}
|
||||
{title === "Subscription" && (
|
||||
<IconButton
|
||||
edge="end"
|
||||
aria-label="edit"
|
||||
onClick={handleEditSubscription}
|
||||
>
|
||||
<EditIcon style={{ color: "black" }} />
|
||||
</IconButton>
|
||||
)}
|
||||
</Box>
|
||||
|
||||
<Table
|
||||
sx={{
|
||||
width: "100%",
|
||||
tableLayout: "fixed",
|
||||
height: "100%",
|
||||
borderBottom: "none",
|
||||
}}
|
||||
aria-label={title}
|
||||
>
|
||||
<TableBody>
|
||||
{Object.entries(
|
||||
data as Record<string, string>,
|
||||
).map(([label, value], index) => (
|
||||
<TableRow key={label}>
|
||||
<TableCell
|
||||
component="th"
|
||||
scope="row"
|
||||
style={{
|
||||
padding: "16px",
|
||||
borderBottom:
|
||||
index === 1 || index === 0
|
||||
? "1px solid rgba(224, 224, 224, 1)"
|
||||
: "none",
|
||||
}}
|
||||
>
|
||||
{label}
|
||||
</TableCell>
|
||||
<TableCell
|
||||
align="right"
|
||||
style={{
|
||||
padding: "10px",
|
||||
borderBottom:
|
||||
index === 1 || index === 0
|
||||
? "1px solid rgba(224, 224, 224, 1)"
|
||||
: "none",
|
||||
}}
|
||||
>
|
||||
{label === "Email" ? (
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent:
|
||||
"flex-end",
|
||||
}}
|
||||
>
|
||||
<Typography>
|
||||
{value}
|
||||
</Typography>
|
||||
<IconButton
|
||||
edge="end"
|
||||
aria-label="edit-email"
|
||||
onClick={
|
||||
handleEditEmail
|
||||
}
|
||||
>
|
||||
<EditIcon
|
||||
style={{
|
||||
color: "black",
|
||||
}}
|
||||
/>
|
||||
</IconButton>
|
||||
</Box>
|
||||
) : typeof value === "string" ? (
|
||||
label === "Two factor 2FA" ? (
|
||||
is2FADisabled ||
|
||||
value === "Disabled" ? (
|
||||
<Typography
|
||||
sx={{
|
||||
textAlign:
|
||||
"center",
|
||||
width: "100%",
|
||||
paddingLeft:
|
||||
"30px",
|
||||
}}
|
||||
>
|
||||
{value}
|
||||
</Typography>
|
||||
) : (
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
alignItems:
|
||||
"center",
|
||||
justifyContent:
|
||||
"center",
|
||||
width: "100%",
|
||||
}}
|
||||
>
|
||||
<Typography>
|
||||
{value}
|
||||
</Typography>
|
||||
{value ===
|
||||
"Enabled" && (
|
||||
<Switch
|
||||
checked={
|
||||
twoFactorEnabled
|
||||
}
|
||||
onChange={(
|
||||
e,
|
||||
) => {
|
||||
const isChecked =
|
||||
e
|
||||
.target
|
||||
.checked;
|
||||
setTwoFactorEnabled(
|
||||
isChecked,
|
||||
);
|
||||
if (
|
||||
!isChecked
|
||||
) {
|
||||
handleOpenDisable2FA();
|
||||
}
|
||||
}}
|
||||
sx={{
|
||||
"& .MuiSwitch-switchBase.Mui-checked":
|
||||
{
|
||||
color: "#00B33C",
|
||||
"&:hover":
|
||||
{
|
||||
backgroundColor:
|
||||
"rgba(0, 179, 60, 0.08)",
|
||||
},
|
||||
},
|
||||
"& .MuiSwitch-switchBase.Mui-checked + .MuiSwitch-track":
|
||||
{
|
||||
backgroundColor:
|
||||
"#00B33C",
|
||||
},
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
)
|
||||
) : (
|
||||
<Typography>
|
||||
{value}
|
||||
</Typography>
|
||||
)
|
||||
) : (
|
||||
<Typography>
|
||||
{String(value)}
|
||||
</Typography>
|
||||
)}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</Grid>
|
||||
))}
|
||||
|
||||
{/* Render DeleteAccount dialog */}
|
||||
<DeleteAccount
|
||||
open={deleteAccountOpen}
|
||||
handleClose={handleCloseDeleteAccount}
|
||||
/>
|
||||
|
||||
{/* Render Disable2FA dialog */}
|
||||
<Disable2FA
|
||||
open={disable2FAOpen}
|
||||
handleClose={handleCancelDisable2FA}
|
||||
handleDisable2FA={handleDisable2FA}
|
||||
/>
|
||||
|
||||
{/* Render UpdateSubscription dialog */}
|
||||
<UpdateSubscription
|
||||
open={updateSubscriptionOpen}
|
||||
onClose={handleCloseUpdateSubscription}
|
||||
/>
|
||||
|
||||
{/* Render ChangeEmail dialog */}
|
||||
<ChangeEmail
|
||||
open={changeEmailOpen}
|
||||
onClose={handleCloseChangeEmail}
|
||||
/>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
|
||||
export default UserComponent;
|
||||
|
Before Width: | Height: | Size: 6.5 KiB |
@@ -1,10 +1,10 @@
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom/client";
|
||||
import App from "./App";
|
||||
import { App } from "./App";
|
||||
import "./styles/globals.css";
|
||||
|
||||
const root = document.getElementById("root");
|
||||
if (!root) throw new Error("Could not load root element to qrender onto");
|
||||
if (!root) throw new Error("Could not load root element to render onto");
|
||||
|
||||
ReactDOM.createRoot(root).render(
|
||||
<React.StrictMode>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { z } from "zod";
|
||||
|
||||
export const apiOrigin =
|
||||
import.meta.env.VITE_ENTE_API_ORIGIN ?? "https://api.ente.io";
|
||||
export const apiOrigin = import.meta.env.VITE_ENTE_API_ORIGIN ?? "https://api.ente.io";
|
||||
|
||||
const UserDetails = z.object({}).passthrough();
|
||||
|
||||
|
||||
4
infra/staff/src/vite-env.d.ts
vendored
@@ -9,9 +9,7 @@ interface ImportMetaEnv {
|
||||
* Override the origin (scheme://host:port) of Ente's API to connect to.
|
||||
*
|
||||
* Default is "https://api.ente.io".
|
||||
|
||||
*/
|
||||
|
||||
*/
|
||||
readonly VITE_ENTE_API_ORIGIN: string | undefined;
|
||||
}
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ You can alternatively install the build from PlayStore or F-Droid.
|
||||
|
||||
## 🧑💻 Building from source
|
||||
|
||||
1. [Install Flutter v3.22.0](https://flutter.dev/docs/get-started/install).
|
||||
1. [Install Flutter v3.22.2](https://flutter.dev/docs/get-started/install).
|
||||
|
||||
2. Pull in all submodules with `git submodule update --init --recursive`
|
||||
|
||||
|
||||
BIN
mobile/android/app/src/dev/res/mipmap-hdpi/launcher_icon.png
Normal file
|
After Width: | Height: | Size: 8.2 KiB |
BIN
mobile/android/app/src/dev/res/mipmap-mdpi/launcher_icon.png
Normal file
|
After Width: | Height: | Size: 4.4 KiB |
BIN
mobile/android/app/src/dev/res/mipmap-xhdpi/launcher_icon.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
mobile/android/app/src/dev/res/mipmap-xxhdpi/launcher_icon.png
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
mobile/android/app/src/dev/res/mipmap-xxxhdpi/launcher_icon.png
Normal file
|
After Width: | Height: | Size: 38 KiB |
BIN
mobile/assets/launcher_icon/ente-icon-dev.png
Normal file
|
After Width: | Height: | Size: 1.0 MiB |
13
mobile/assets/video-editor/video-crop-free-action.svg
Normal file
@@ -0,0 +1,13 @@
|
||||
<svg width="40" height="41" viewBox="0 0 40 41" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_26160_90150)">
|
||||
<path d="M8.5 12.2266V11.9266C8.5 10.8065 8.5 10.2464 8.71799 9.81858C8.90973 9.44226 9.21569 9.1363 9.59202 8.94455C10.0198 8.72656 10.5799 8.72656 11.7 8.72656H12" stroke="white" stroke-linecap="round"/>
|
||||
<path d="M28 8.72656H28.3C29.4201 8.72656 29.9802 8.72656 30.408 8.94455C30.7843 9.1363 31.0903 9.44226 31.282 9.81858C31.5 10.2464 31.5 10.8065 31.5 11.9266V12.2266" stroke="white" stroke-linecap="round"/>
|
||||
<path d="M31.5 28.2266V28.5266C31.5 29.6467 31.5 30.2067 31.282 30.6345C31.0903 31.0109 30.7843 31.3168 30.408 31.5086C29.9802 31.7266 29.4201 31.7266 28.3 31.7266H28" stroke="white" stroke-linecap="round"/>
|
||||
<path d="M8.5 28.2266V28.5266C8.5 29.6467 8.5 30.2067 8.71799 30.6345C8.90973 31.0109 9.21569 31.3168 9.59202 31.5086C10.0198 31.7266 10.5799 31.7266 11.7 31.7266H12" stroke="white" stroke-linecap="round"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_26160_90150">
|
||||
<rect width="24" height="24" fill="white" transform="translate(8 8.22656)"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
10
mobile/assets/video-editor/video-crop-original-action.svg
Normal file
@@ -0,0 +1,10 @@
|
||||
<svg width="40" height="41" viewBox="0 0 40 41" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_26160_90098)">
|
||||
<path d="M23 16.2266V24.2266H13V16.2266H23ZM24 14.2266H12C11.45 14.2266 11 14.6766 11 15.2266V25.2266C11 25.7766 11.45 26.2266 12 26.2266H24C24.55 26.2266 25 25.7766 25 25.2266V21.7266L29 25.7266V14.7266L25 18.7266V15.2266C25 14.6766 24.55 14.2266 24 14.2266Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_26160_90098">
|
||||
<rect width="24" height="24" fill="white" transform="translate(8 8.22656)"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 562 B |
@@ -0,0 +1,7 @@
|
||||
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M6 12.5V12.2C6 11.0799 6 10.5198 6.21799 10.092C6.40973 9.71569 6.71569 9.40973 7.09202 9.21799C7.51984 9 8.07989 9 9.2 9H9.5" stroke="white" stroke-linecap="round"/>
|
||||
<path d="M30.5 9H30.8C31.9201 9 32.4802 9 32.908 9.21799C33.2843 9.40973 33.5903 9.71569 33.782 10.092C34 10.5198 34 11.0799 34 12.2V12.5" stroke="white" stroke-linecap="round"/>
|
||||
<path d="M34 28.5V28.8C34 29.9201 34 30.4802 33.782 30.908C33.5903 31.2843 33.2843 31.5903 32.908 31.782C32.4802 32 31.9201 32 30.8 32H30.5" stroke="white" stroke-linecap="round"/>
|
||||
<path d="M6 28.5V28.8C6 29.9201 6 30.4802 6.21799 30.908C6.40973 31.2843 6.71569 31.5903 7.09202 31.782C7.51984 32 8.07989 32 9.2 32H9.5" stroke="white" stroke-linecap="round"/>
|
||||
<path d="M11.8253 16.2727V25H10.2443V17.8111H10.1932L8.15199 19.1151V17.6662L10.321 16.2727H11.8253ZM17.2372 25.1193C16.8196 25.1165 16.4119 25.044 16.0142 24.902C15.6165 24.7571 15.2585 24.5227 14.9403 24.1989C14.6222 23.8722 14.3693 23.4389 14.1818 22.8991C13.9943 22.3565 13.902 21.6847 13.9048 20.8835C13.9048 20.1364 13.9844 19.4702 14.1435 18.8849C14.3026 18.2997 14.5312 17.8054 14.8295 17.402C15.1278 16.9957 15.4872 16.6861 15.9077 16.473C16.331 16.2599 16.804 16.1534 17.3267 16.1534C17.875 16.1534 18.3608 16.2614 18.7841 16.4773C19.2102 16.6932 19.554 16.9886 19.8153 17.3636C20.0767 17.7358 20.2386 18.1562 20.3011 18.625H18.7457C18.6662 18.2898 18.5028 18.0227 18.2557 17.8239C18.0114 17.6222 17.7017 17.5213 17.3267 17.5213C16.7216 17.5213 16.2557 17.7841 15.929 18.3097C15.6051 18.8352 15.4418 19.5568 15.4389 20.4744H15.4986C15.6378 20.2244 15.8182 20.0099 16.0398 19.831C16.2614 19.652 16.5114 19.5142 16.7898 19.4176C17.071 19.3182 17.3679 19.2685 17.6804 19.2685C18.1918 19.2685 18.6506 19.3906 19.0568 19.6349C19.4659 19.8793 19.7898 20.2159 20.0284 20.6449C20.267 21.071 20.3849 21.5597 20.3821 22.1108C20.3849 22.6847 20.2543 23.2003 19.9901 23.6577C19.7259 24.1122 19.358 24.4702 18.8864 24.7315C18.4148 24.9929 17.8651 25.1222 17.2372 25.1193ZM17.2287 23.8409C17.5384 23.8409 17.8153 23.7656 18.0597 23.6151C18.304 23.4645 18.4972 23.2614 18.6392 23.0057C18.7813 22.75 18.8509 22.4631 18.848 22.1449C18.8509 21.8324 18.7827 21.5497 18.6435 21.2969C18.5071 21.044 18.3182 20.8437 18.0767 20.696C17.8352 20.5483 17.5597 20.4744 17.25 20.4744C17.0199 20.4744 16.8054 20.5185 16.6065 20.6065C16.4077 20.6946 16.2344 20.8168 16.0866 20.973C15.9389 21.1264 15.8224 21.3054 15.7372 21.5099C15.6548 21.7116 15.6122 21.9276 15.6094 22.1577C15.6122 22.4616 15.6832 22.7415 15.8224 22.9972C15.9616 23.2528 16.1534 23.4574 16.3977 23.6108C16.642 23.7642 16.919 23.8409 17.2287 23.8409ZM22.7898 23.9517C22.5313 23.9517 22.3097 23.8608 22.125 23.679C21.9403 23.4943 21.8494 23.2727 21.8523 23.0142C21.8494 22.7585 21.9403 22.5398 22.125 22.358C22.3097 22.1761 22.5313 22.0852 22.7898 22.0852C23.0398 22.0852 23.2571 22.1761 23.4418 22.358C23.6293 22.5398 23.7244 22.7585 23.7273 23.0142C23.7244 23.1875 23.679 23.3452 23.5909 23.4872C23.5057 23.6293 23.392 23.7429 23.25 23.8281C23.1108 23.9105 22.9574 23.9517 22.7898 23.9517ZM22.7898 19.6264C22.5313 19.6264 22.3097 19.5355 22.125 19.3537C21.9403 19.169 21.8494 18.9474 21.8523 18.6889C21.8494 18.4332 21.9403 18.2145 22.125 18.0327C22.3097 17.848 22.5313 17.7557 22.7898 17.7557C23.0398 17.7557 23.2571 17.848 23.4418 18.0327C23.6293 18.2145 23.7244 18.4332 23.7273 18.6889C23.7244 18.8594 23.679 19.0156 23.5909 19.1577C23.5057 19.2997 23.392 19.4134 23.25 19.4986C23.1108 19.5838 22.9574 19.6264 22.7898 19.6264ZM28.3327 16.1534C28.7504 16.1562 29.1566 16.2301 29.5515 16.375C29.9492 16.517 30.3072 16.75 30.6254 17.0739C30.9435 17.3949 31.1964 17.8253 31.3839 18.3651C31.5714 18.9048 31.6651 19.5724 31.6651 20.3679C31.668 21.1179 31.5884 21.7884 31.4265 22.3793C31.2674 22.9673 31.0387 23.4645 30.7404 23.8707C30.4421 24.277 30.0827 24.5866 29.6623 24.7997C29.2418 25.0128 28.7688 25.1193 28.2433 25.1193C27.6921 25.1193 27.2035 25.0114 26.7773 24.7955C26.354 24.5795 26.0117 24.2841 25.7504 23.9091C25.489 23.5341 25.3285 23.1051 25.2688 22.6222H26.8242C26.9038 22.9687 27.0657 23.2443 27.31 23.4489C27.5572 23.6506 27.8683 23.7514 28.2433 23.7514C28.8484 23.7514 29.3143 23.4886 29.641 22.9631C29.9677 22.4375 30.131 21.7074 30.131 20.7727H30.0714C29.9322 21.0227 29.7518 21.2386 29.5302 21.4205C29.3086 21.5994 29.0572 21.7372 28.7759 21.8338C28.4975 21.9304 28.2021 21.9787 27.8896 21.9787C27.3782 21.9787 26.918 21.8565 26.5089 21.6122C26.1026 21.3679 25.7802 21.0327 25.5415 20.6065C25.3058 20.1804 25.1864 19.6932 25.1836 19.1449C25.1836 18.5767 25.3143 18.0668 25.5756 17.6151C25.8398 17.1605 26.2077 16.8026 26.6793 16.5412C27.1509 16.277 27.7021 16.1477 28.3327 16.1534ZM28.337 17.4318C28.0302 17.4318 27.7532 17.5071 27.506 17.6577C27.2617 17.8054 27.0685 18.0071 26.9265 18.2628C26.7873 18.5156 26.7177 18.7983 26.7177 19.1108C26.7205 19.4205 26.7901 19.7017 26.9265 19.9545C27.0657 20.2074 27.2546 20.4077 27.4933 20.5554C27.7347 20.7031 28.0103 20.777 28.32 20.777C28.5501 20.777 28.7646 20.733 28.9634 20.6449C29.1623 20.5568 29.3356 20.4347 29.4833 20.2784C29.6339 20.1193 29.7504 19.9389 29.8327 19.7372C29.918 19.5355 29.9592 19.3224 29.9563 19.098C29.9563 18.7997 29.8853 18.5241 29.7433 18.2713C29.604 18.0185 29.4123 17.8153 29.168 17.6619C28.9265 17.5085 28.6495 17.4318 28.337 17.4318Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.3 KiB |
14
mobile/assets/video-editor/video-crop-ratio_1_1-action.svg
Normal file
@@ -0,0 +1,14 @@
|
||||
<svg width="40" height="41" viewBox="0 0 40 41" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_26160_90104)">
|
||||
<path d="M8.5 12.2266V11.9266C8.5 10.8065 8.5 10.2464 8.71799 9.81858C8.90973 9.44226 9.21569 9.1363 9.59202 8.94455C10.0198 8.72656 10.5799 8.72656 11.7 8.72656H12" stroke="white" stroke-linecap="round"/>
|
||||
<path d="M28 8.72656H28.3C29.4201 8.72656 29.9802 8.72656 30.408 8.94455C30.7843 9.1363 31.0903 9.44226 31.282 9.81858C31.5 10.2464 31.5 10.8065 31.5 11.9266V12.2266" stroke="white" stroke-linecap="round"/>
|
||||
<path d="M31.5 28.2266V28.5266C31.5 29.6467 31.5 30.2067 31.282 30.6345C31.0903 31.0109 30.7843 31.3168 30.408 31.5086C29.9802 31.7266 29.4201 31.7266 28.3 31.7266H28" stroke="white" stroke-linecap="round"/>
|
||||
<path d="M8.5 28.2266V28.5266C8.5 29.6467 8.5 30.2067 8.71799 30.6345C8.90973 31.0109 9.21569 31.3168 9.59202 31.5086C10.0198 31.7266 10.5799 31.7266 11.7 31.7266H12" stroke="white" stroke-linecap="round"/>
|
||||
<path d="M16.3253 15.4993V24.2266H14.7443V17.0376H14.6932L12.652 18.3416V16.8928L14.821 15.4993H16.3253ZM19.5085 23.1783C19.25 23.1783 19.0284 23.0874 18.8438 22.9055C18.6591 22.7209 18.5682 22.4993 18.571 22.2408C18.5682 21.9851 18.6591 21.7663 18.8438 21.5845C19.0284 21.4027 19.25 21.3118 19.5085 21.3118C19.7585 21.3118 19.9759 21.4027 20.1605 21.5845C20.348 21.7663 20.4432 21.9851 20.446 22.2408C20.4432 22.4141 20.3977 22.5717 20.3097 22.7138C20.2244 22.8558 20.1108 22.9695 19.9688 23.0547C19.8295 23.1371 19.6761 23.1783 19.5085 23.1783ZM19.5085 18.853C19.25 18.853 19.0284 18.7621 18.8438 18.5803C18.6591 18.3956 18.5682 18.174 18.571 17.9155C18.5682 17.6598 18.6591 17.4411 18.8438 17.2592C19.0284 17.0746 19.25 16.9822 19.5085 16.9822C19.7585 16.9822 19.9759 17.0746 20.1605 17.2592C20.348 17.4411 20.4432 17.6598 20.446 17.9155C20.4432 18.0859 20.3977 18.2422 20.3097 18.3842C20.2244 18.5263 20.1108 18.6399 19.9688 18.7251C19.8295 18.8104 19.6761 18.853 19.5085 18.853ZM25.5714 15.4993V24.2266H23.9904V17.0376H23.9393L21.8981 18.3416V16.8928L24.0671 15.4993H25.5714Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_26160_90104">
|
||||
<rect width="24" height="24" fill="white" transform="translate(8 8.22656)"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
14
mobile/assets/video-editor/video-crop-ratio_3_4-action.svg
Normal file
@@ -0,0 +1,14 @@
|
||||
<svg width="40" height="41" viewBox="0 0 40 41" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_26160_90134)">
|
||||
<path d="M8.5 12.2266V11.9266C8.5 10.8065 8.5 10.2464 8.71799 9.81858C8.90973 9.44226 9.21569 9.1363 9.59202 8.94455C10.0198 8.72656 10.5799 8.72656 11.7 8.72656H12" stroke="white" stroke-linecap="round"/>
|
||||
<path d="M28 8.72656H28.3C29.4201 8.72656 29.9802 8.72656 30.408 8.94455C30.7843 9.1363 31.0903 9.44226 31.282 9.81858C31.5 10.2464 31.5 10.8065 31.5 11.9266V12.2266" stroke="white" stroke-linecap="round"/>
|
||||
<path d="M31.5 28.2266V28.5266C31.5 29.6467 31.5 30.2067 31.282 30.6345C31.0903 31.0109 30.7843 31.3168 30.408 31.5086C29.9802 31.7266 29.4201 31.7266 28.3 31.7266H28" stroke="white" stroke-linecap="round"/>
|
||||
<path d="M8.5 28.2266V28.5266C8.5 29.6467 8.5 30.2067 8.71799 30.6345C8.90973 31.0109 9.21569 31.3168 9.59202 31.5086C10.0198 31.7266 10.5799 31.7266 11.7 31.7266H12" stroke="white" stroke-linecap="round"/>
|
||||
<path d="M13.9077 25.1193C13.294 25.1193 12.7486 25.0142 12.2713 24.804C11.7969 24.5937 11.4219 24.3011 11.1463 23.9261C10.8707 23.5511 10.7244 23.1179 10.7074 22.6264H12.3097C12.3239 22.8622 12.402 23.0682 12.544 23.2443C12.6861 23.4176 12.875 23.5526 13.1108 23.6491C13.3466 23.7457 13.6108 23.794 13.9034 23.794C14.2159 23.794 14.4929 23.7401 14.7344 23.6321C14.9759 23.5213 15.1648 23.3679 15.3011 23.1719C15.4375 22.9759 15.5043 22.75 15.5014 22.4943C15.5043 22.2301 15.4361 21.9972 15.2969 21.7955C15.1577 21.5937 14.956 21.4361 14.6918 21.3224C14.4304 21.2088 14.1151 21.152 13.7457 21.152H12.9744V19.9332H13.7457C14.0497 19.9332 14.3153 19.8807 14.5426 19.7756C14.7727 19.6705 14.9531 19.5227 15.0838 19.3324C15.2145 19.1392 15.2784 18.9162 15.2756 18.6634C15.2784 18.4162 15.223 18.2017 15.1094 18.0199C14.9986 17.8352 14.8409 17.6918 14.6364 17.5895C14.4347 17.4872 14.1974 17.4361 13.9247 17.4361C13.6577 17.4361 13.4105 17.4844 13.1832 17.581C12.956 17.6776 12.7727 17.8153 12.6335 17.9943C12.4943 18.1705 12.4205 18.3807 12.4119 18.625H10.8906C10.902 18.1364 11.0426 17.7074 11.3125 17.3381C11.5852 16.9659 11.9489 16.6761 12.4034 16.4688C12.858 16.2585 13.3679 16.1534 13.9332 16.1534C14.5156 16.1534 15.0213 16.2628 15.4503 16.4815C15.8821 16.6974 16.2159 16.9886 16.4517 17.3551C16.6875 17.7216 16.8054 18.1264 16.8054 18.5696C16.8082 19.0611 16.6634 19.473 16.3707 19.8054C16.081 20.1378 15.7003 20.3551 15.2287 20.4574V20.5256C15.8423 20.6108 16.3125 20.8381 16.6392 21.2074C16.9688 21.5739 17.1321 22.0298 17.1293 22.5753C17.1293 23.0639 16.9901 23.5014 16.7116 23.8878C16.4361 24.2713 16.0554 24.5724 15.5696 24.7912C15.0866 25.0099 14.5327 25.1193 13.9077 25.1193ZM19.5593 23.9517C19.3008 23.9517 19.0792 23.8608 18.8945 23.679C18.7099 23.4943 18.619 23.2727 18.6218 23.0142C18.619 22.7585 18.7099 22.5398 18.8945 22.358C19.0792 22.1761 19.3008 22.0852 19.5593 22.0852C19.8093 22.0852 20.0266 22.1761 20.2113 22.358C20.3988 22.5398 20.494 22.7585 20.4968 23.0142C20.494 23.1875 20.4485 23.3452 20.3604 23.4872C20.2752 23.6293 20.1616 23.7429 20.0195 23.8281C19.8803 23.9105 19.7269 23.9517 19.5593 23.9517ZM19.5593 19.6264C19.3008 19.6264 19.0792 19.5355 18.8945 19.3537C18.7099 19.169 18.619 18.9474 18.6218 18.6889C18.619 18.4332 18.7099 18.2145 18.8945 18.0327C19.0792 17.848 19.3008 17.7557 19.5593 17.7557C19.8093 17.7557 20.0266 17.848 20.2113 18.0327C20.3988 18.2145 20.494 18.4332 20.4968 18.6889C20.494 18.8594 20.4485 19.0156 20.3604 19.1577C20.2752 19.2997 20.1616 19.4134 20.0195 19.4986C19.8803 19.5838 19.7269 19.6264 19.5593 19.6264ZM21.9148 23.3807V22.1236L25.6179 16.2727H26.6662V18.0625H26.027L23.5341 22.0128V22.081H28.7031V23.3807H21.9148ZM26.0781 25V22.9972L26.0952 22.4347V16.2727H27.5866V25H26.0781Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_26160_90134">
|
||||
<rect width="24" height="24" fill="white" transform="translate(8 8.22656)"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.8 KiB |
14
mobile/assets/video-editor/video-crop-ratio_4_3-action.svg
Normal file
@@ -0,0 +1,14 @@
|
||||
<svg width="40" height="41" viewBox="0 0 40 41" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_26160_90142)">
|
||||
<path d="M8.5 12.2266V11.9266C8.5 10.8065 8.5 10.2464 8.71799 9.81858C8.90973 9.44226 9.21569 9.1363 9.59202 8.94455C10.0198 8.72656 10.5799 8.72656 11.7 8.72656H12" stroke="white" stroke-linecap="round"/>
|
||||
<path d="M28 8.72656H28.3C29.4201 8.72656 29.9802 8.72656 30.408 8.94455C30.7843 9.1363 31.0903 9.44226 31.282 9.81858C31.5 10.2464 31.5 10.8065 31.5 11.9266V12.2266" stroke="white" stroke-linecap="round"/>
|
||||
<path d="M31.5 28.2266V28.5266C31.5 29.6467 31.5 30.2067 31.282 30.6345C31.0903 31.0109 30.7843 31.3168 30.408 31.5086C29.9802 31.7266 29.4201 31.7266 28.3 31.7266H28" stroke="white" stroke-linecap="round"/>
|
||||
<path d="M8.5 28.2266V28.5266C8.5 29.6467 8.5 30.2067 8.71799 30.6345C8.90973 31.0109 9.21569 31.3168 9.59202 31.5086C10.0198 31.7266 10.5799 31.7266 11.7 31.7266H12" stroke="white" stroke-linecap="round"/>
|
||||
<path d="M10.6179 23.3807V22.1236L14.321 16.2727H15.3693V18.0625H14.7301L12.2372 22.0128V22.081H17.4062V23.3807H10.6179ZM14.7812 25V22.9972L14.7983 22.4347V16.2727H16.2898V25H14.7812ZM19.7351 23.9517C19.4766 23.9517 19.255 23.8608 19.0703 23.679C18.8857 23.4943 18.7947 23.2727 18.7976 23.0142C18.7947 22.7585 18.8857 22.5398 19.0703 22.358C19.255 22.1761 19.4766 22.0852 19.7351 22.0852C19.9851 22.0852 20.2024 22.1761 20.3871 22.358C20.5746 22.5398 20.6697 22.7585 20.6726 23.0142C20.6697 23.1875 20.6243 23.3452 20.5362 23.4872C20.451 23.6293 20.3374 23.7429 20.1953 23.8281C20.0561 23.9105 19.9027 23.9517 19.7351 23.9517ZM19.7351 19.6264C19.4766 19.6264 19.255 19.5355 19.0703 19.3537C18.8857 19.169 18.7947 18.9474 18.7976 18.6889C18.7947 18.4332 18.8857 18.2145 19.0703 18.0327C19.255 17.848 19.4766 17.7557 19.7351 17.7557C19.9851 17.7557 20.2024 17.848 20.3871 18.0327C20.5746 18.2145 20.6697 18.4332 20.6726 18.6889C20.6697 18.8594 20.6243 19.0156 20.5362 19.1577C20.451 19.2997 20.3374 19.4134 20.1953 19.4986C20.0561 19.5838 19.9027 19.6264 19.7351 19.6264ZM25.3803 25.1193C24.7667 25.1193 24.2212 25.0142 23.744 24.804C23.2695 24.5937 22.8945 24.3011 22.619 23.9261C22.3434 23.5511 22.1971 23.1179 22.18 22.6264H23.7823C23.7965 22.8622 23.8746 23.0682 24.0167 23.2443C24.1587 23.4176 24.3477 23.5526 24.5835 23.6491C24.8192 23.7457 25.0835 23.794 25.3761 23.794C25.6886 23.794 25.9656 23.7401 26.207 23.6321C26.4485 23.5213 26.6374 23.3679 26.7738 23.1719C26.9102 22.9759 26.9769 22.75 26.9741 22.4943C26.9769 22.2301 26.9087 21.9972 26.7695 21.7955C26.6303 21.5937 26.4286 21.4361 26.1644 21.3224C25.9031 21.2088 25.5877 21.152 25.2184 21.152H24.4471V19.9332H25.2184C25.5224 19.9332 25.788 19.8807 26.0153 19.7756C26.2454 19.6705 26.4258 19.5227 26.5565 19.3324C26.6871 19.1392 26.7511 18.9162 26.7482 18.6634C26.7511 18.4162 26.6957 18.2017 26.582 18.0199C26.4712 17.8352 26.3136 17.6918 26.109 17.5895C25.9073 17.4872 25.6701 17.4361 25.3974 17.4361C25.1303 17.4361 24.8832 17.4844 24.6559 17.581C24.4286 17.6776 24.2454 17.8153 24.1062 17.9943C23.967 18.1705 23.8931 18.3807 23.8846 18.625H22.3633C22.3746 18.1364 22.5153 17.7074 22.7852 17.3381C23.0579 16.9659 23.4215 16.6761 23.8761 16.4688C24.3306 16.2585 24.8406 16.1534 25.4059 16.1534C25.9883 16.1534 26.494 16.2628 26.9229 16.4815C27.3548 16.6974 27.6886 16.9886 27.9244 17.3551C28.1602 17.7216 28.2781 18.1264 28.2781 18.5696C28.2809 19.0611 28.136 19.473 27.8434 19.8054C27.5536 20.1378 27.1729 20.3551 26.7013 20.4574V20.5256C27.315 20.6108 27.7852 20.8381 28.1119 21.2074C28.4414 21.5739 28.6048 22.0298 28.6019 22.5753C28.6019 23.0639 28.4627 23.5014 28.1843 23.8878C27.9087 24.2713 27.5281 24.5724 27.0423 24.7912C26.5593 25.0099 26.0053 25.1193 25.3803 25.1193Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_26160_90142">
|
||||
<rect width="24" height="24" fill="white" transform="translate(8 8.22656)"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.8 KiB |
10
mobile/assets/video-editor/video-crop-ratio_9_16-action.svg
Normal file
@@ -0,0 +1,10 @@
|
||||
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M32.5 11.1598L32.5 11.4454C32.5 11.6908 32.3009 11.8898 32.0553 11.8898C31.8097 11.8898 31.6106 11.6908 31.6106 11.4454L31.6106 11.1788C31.6106 10.6738 31.6103 10.3217 31.5879 10.0476C31.5659 9.77871 31.5249 9.62421 31.4652 9.50719C31.3373 9.25636 31.1333 9.05243 30.8822 8.92462C30.7651 8.865 30.6105 8.82404 30.3414 8.80207C30.0671 8.77967 29.7148 8.77933 29.2094 8.77933L28.9426 8.77933C28.697 8.77933 28.4979 8.58039 28.4979 8.33498C28.4979 8.08957 28.697 7.89063 28.9426 7.89063L29.2284 7.89062C29.7103 7.89062 30.0991 7.89062 30.4138 7.91632C30.7379 7.94278 31.0226 7.99868 31.286 8.13278C31.7044 8.34579 32.0445 8.68568 32.2577 9.10373C32.3919 9.36691 32.4478 9.65138 32.4743 9.97525C32.5 10.2898 32.5 10.6782 32.5 11.1598Z" fill="white"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M31.5879 31.5062C31.6103 31.2321 31.6106 30.8801 31.6106 30.375L31.6106 30.1084C31.6106 29.863 31.8097 29.6641 32.0553 29.6641C32.3009 29.6641 32.5 29.863 32.5 30.1084L32.5 30.394C32.5 30.8756 32.5 31.2641 32.4743 31.5786C32.4478 31.9025 32.3919 32.1869 32.2577 32.4501C32.0445 32.8682 31.7044 33.2081 31.286 33.4211C31.0226 33.5552 30.7379 33.6111 30.4138 33.6375C30.0991 33.6632 29.7103 33.6632 29.2284 33.6632L28.9426 33.6632C28.697 33.6632 28.4979 33.4643 28.4979 33.2189C28.4979 32.9735 28.697 32.7745 28.9426 32.7745L29.2094 32.7745C29.7148 32.7745 30.0671 32.7742 30.3414 32.7518C30.6105 32.7298 30.7651 32.6889 30.8822 32.6292C31.1333 32.5014 31.3373 32.2975 31.4652 32.0467C31.5249 31.9296 31.5659 31.7751 31.5879 31.5062Z" fill="white"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.5 33.2189C12.5 33.4643 12.3009 33.6632 12.0553 33.6632L11.7695 33.6632C11.2875 33.6632 10.8988 33.6632 10.584 33.6375C10.2599 33.6111 9.97526 33.5552 9.71188 33.4211C9.29352 33.2081 8.95338 32.8682 8.74022 32.4501C8.60602 32.1869 8.55007 31.9025 8.52359 31.5786C8.49787 31.2641 8.49788 30.8756 8.49788 30.394L8.49788 30.1084C8.49788 29.863 8.69697 29.6641 8.94256 29.6641C9.18815 29.6641 9.38724 29.863 9.38724 30.1084L9.38724 30.375C9.38724 30.8801 9.38759 31.2321 9.41 31.5062C9.43198 31.7751 9.47297 31.9296 9.53264 32.0467C9.66054 32.2975 9.86462 32.5014 10.1156 32.6292C10.2327 32.6889 10.3874 32.7298 10.6565 32.7518C10.9308 32.7742 11.2831 32.7745 11.7885 32.7745L12.0553 32.7745C12.3009 32.7745 12.5 32.9735 12.5 33.2189Z" fill="white"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.5 8.33498C12.5 8.58039 12.3009 8.77933 12.0553 8.77933L11.7885 8.77933C11.2831 8.77933 10.9308 8.77967 10.6565 8.80207C10.3874 8.82404 10.2327 8.865 10.1156 8.92462C9.86462 9.05243 9.66054 9.25636 9.53264 9.50719C9.47297 9.62421 9.43198 9.77871 9.41 10.0476C9.38759 10.3217 9.38724 10.6738 9.38724 11.1788L9.38724 11.4454C9.38724 11.6908 9.18815 11.8898 8.94256 11.8898C8.69697 11.8898 8.49788 11.6908 8.49788 11.4454L8.49788 11.1598C8.49788 10.6782 8.49787 10.2898 8.52359 9.97525C8.55007 9.65138 8.60602 9.36691 8.74022 9.10373C8.95338 8.68568 9.29352 8.34579 9.71188 8.13278C9.97526 7.99868 10.2599 7.94278 10.584 7.91632C10.8988 7.89062 11.2875 7.89062 11.7695 7.89063L12.0553 7.89063C12.3009 7.89063 12.5 8.08957 12.5 8.33498Z" fill="white"/>
|
||||
<path d="M27.972 24.6926C27.6005 24.69 27.2379 24.6256 26.8841 24.4993C26.5304 24.3704 26.212 24.162 25.9289 23.874C25.6459 23.5834 25.421 23.1981 25.2542 22.7181C25.0875 22.2355 25.0053 21.638 25.0079 20.9255C25.0079 20.261 25.0786 19.6685 25.2201 19.148C25.3616 18.6276 25.5651 18.1879 25.8304 17.8292C26.0957 17.4679 26.4154 17.1925 26.7894 17.003C27.1659 16.8135 27.5866 16.7188 28.0516 16.7188C28.5393 16.7188 28.9714 16.8148 29.3479 17.0068C29.7269 17.1988 30.0327 17.4616 30.2652 17.7951C30.4977 18.126 30.6417 18.5 30.6973 18.9169H29.3138C29.243 18.6187 29.0977 18.3812 28.8779 18.2044C28.6606 18.025 28.3851 17.9353 28.0516 17.9353C27.5133 17.9353 27.0989 18.169 26.8083 18.6364C26.5202 19.1038 26.3749 19.7456 26.3724 20.5616H26.4255C26.5493 20.3393 26.7098 20.1486 26.9069 19.9894C27.104 19.8302 27.3263 19.7077 27.574 19.6218C27.8242 19.5333 28.0882 19.4891 28.3662 19.4891C28.821 19.4891 29.2291 19.5978 29.5905 19.815C29.9544 20.0323 30.2424 20.3317 30.4547 20.7132C30.667 21.0922 30.7718 21.5268 30.7693 22.0169C30.7718 22.5273 30.6556 22.9859 30.4206 23.3927C30.1856 23.7969 29.8583 24.1153 29.4389 24.3477C29.0194 24.5801 28.5304 24.6951 27.972 24.6926ZM27.9644 23.5556C28.2398 23.5556 28.4862 23.4887 28.7035 23.3548C28.9208 23.2209 29.0927 23.0402 29.219 22.8128C29.3454 22.5854 29.4073 22.3302 29.4048 22.0473C29.4073 21.7693 29.3466 21.518 29.2228 21.2931C29.1015 21.0682 28.9335 20.8901 28.7187 20.7587C28.5039 20.6273 28.2588 20.5616 27.9833 20.5616C27.7787 20.5616 27.5879 20.6008 27.411 20.6791C27.2341 20.7575 27.08 20.8661 26.9486 21.0051C26.8172 21.1415 26.7136 21.3007 26.6378 21.4826C26.5645 21.662 26.5266 21.854 26.524 22.0586C26.5266 22.329 26.5897 22.5778 26.7136 22.8052C26.8374 23.0326 27.0079 23.2145 27.2253 23.351C27.4426 23.4874 27.689 23.5556 27.9644 23.5556Z" fill="white"/>
|
||||
<path d="M23.1711 16.8203V24.5844H21.7659V18.1889H21.7205L19.9062 19.3489V18.06L21.8341 16.8203H23.1711Z" fill="white"/>
|
||||
<path d="M17.7316 23.6433C17.5019 23.6433 17.3049 23.5623 17.1409 23.4004C16.9768 23.2359 16.896 23.0386 16.8985 22.8083C16.896 22.5806 16.9768 22.3858 17.1409 22.2238C17.3049 22.0619 17.5019 21.9809 17.7316 21.9809C17.9538 21.9809 18.1469 22.0619 18.311 22.2238C18.4776 22.3858 18.5622 22.5806 18.5647 22.8083C18.5622 22.9626 18.5218 23.1031 18.4435 23.2296C18.3678 23.3561 18.2668 23.4573 18.1406 23.5332C18.0169 23.6066 17.8805 23.6433 17.7316 23.6433ZM17.7316 19.7911C17.5019 19.7911 17.3049 19.7101 17.1409 19.5482C16.9768 19.3837 16.896 19.1864 16.8985 18.9562C16.896 18.7284 16.9768 18.5336 17.1409 18.3717C17.3049 18.2072 17.5019 18.125 17.7316 18.125C17.9538 18.125 18.1469 18.2072 18.311 18.3717C18.4776 18.5336 18.5622 18.7284 18.5647 18.9562C18.5622 19.108 18.5218 19.2471 18.4435 19.3736C18.3678 19.5001 18.2668 19.6013 18.1406 19.6772C18.0169 19.7532 17.8805 19.7911 17.7316 19.7911Z" fill="white"/>
|
||||
<path d="M12.6136 16.7189C12.9851 16.7214 13.3464 16.7871 13.6977 16.916C14.0515 17.0423 14.3698 17.2495 14.6529 17.5375C14.9359 17.823 15.1608 18.2058 15.3276 18.6858C15.4943 19.1659 15.5777 19.7596 15.5777 20.4671C15.5803 21.1341 15.5095 21.7303 15.3655 22.2559C15.224 22.7789 15.0205 23.221 14.7552 23.5823C14.4899 23.9436 14.1702 24.219 13.7962 24.4085C13.4222 24.598 13.0015 24.6927 12.534 24.6927C12.0438 24.6927 11.6092 24.5967 11.2301 24.4047C10.8536 24.2127 10.5491 23.9499 10.3166 23.6164C10.0841 23.2829 9.94137 22.9014 9.88831 22.4719H11.2718C11.3426 22.7801 11.4866 23.0252 11.7039 23.2071C11.9238 23.3865 12.2005 23.4762 12.534 23.4762C13.0723 23.4762 13.4867 23.2425 13.7773 22.7751C14.0679 22.3077 14.2132 21.6583 14.2132 20.8271H14.1601C14.0363 21.0494 13.8758 21.2415 13.6787 21.4032C13.4816 21.5623 13.258 21.6849 13.0078 21.7708C12.7602 21.8567 12.4974 21.8996 12.2194 21.8996C11.7646 21.8996 11.3552 21.791 10.9913 21.5737C10.63 21.3564 10.3432 21.0583 10.1309 20.6793C9.92116 20.3003 9.81503 19.867 9.8125 19.3794C9.8125 18.8741 9.92874 18.4205 10.1612 18.0188C10.3962 17.6146 10.7235 17.2962 11.1429 17.0638C11.5624 16.8288 12.0526 16.7139 12.6136 16.7189ZM12.6174 17.8559C12.3445 17.8559 12.0981 17.9228 11.8783 18.0567C11.661 18.1881 11.4891 18.3675 11.3628 18.5949C11.239 18.8197 11.1771 19.0711 11.1771 19.3491C11.1796 19.6245 11.2415 19.8746 11.3628 20.0994C11.4866 20.3243 11.6546 20.5024 11.8669 20.6338C12.0817 20.7652 12.3268 20.8309 12.6022 20.8309C12.8069 20.8309 12.9977 20.7917 13.1746 20.7134C13.3515 20.6351 13.5056 20.5264 13.637 20.3875C13.771 20.246 13.8746 20.0856 13.9478 19.9062C14.0237 19.7268 14.0603 19.5373 14.0578 19.3377C14.0578 19.0724 13.9946 18.8273 13.8682 18.6025C13.7444 18.3776 13.5739 18.1969 13.3565 18.0605C13.1418 17.9241 12.8954 17.8559 12.6174 17.8559Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 7.8 KiB |
4
mobile/assets/video-editor/video-editor-crop-action.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg width="41" height="41" viewBox="0 0 41 41" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M14.5 10.2266V24.2266C14.5 24.757 14.7107 25.2657 15.0858 25.6408C15.4609 26.0158 15.9696 26.2266 16.5 26.2266H30.5" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M26.5 30.2266V16.2266C26.5 15.6961 26.2893 15.1874 25.9142 14.8123C25.5391 14.4373 25.0304 14.2266 24.5 14.2266H10.5" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 518 B |
@@ -0,0 +1,3 @@
|
||||
<svg width="41" height="41" viewBox="0 0 41 41" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M17.5 9.22656H11.5C10.9696 9.22656 10.4609 9.43728 10.0858 9.81235C9.71071 10.1874 9.5 10.6961 9.5 11.2266V24.2266C9.5 24.757 9.71071 25.2657 10.0858 25.6408C10.4609 26.0158 10.9696 26.2266 11.5 26.2266H12.5V23.2266H11.5V11.2266H17.5V19.2266H19.5V11.2266C19.5 10.6961 19.2893 10.1874 18.9142 9.81235C18.5391 9.43728 18.0304 9.22656 17.5 9.22656ZM31.5 29.2266V23.2266C31.5 22.6961 31.2893 22.1874 30.9142 21.8123C30.5391 21.4373 30.0304 21.2266 29.5 21.2266H16.5C15.9696 21.2266 15.4609 21.4373 15.0858 21.8123C14.7107 22.1874 14.5 22.6961 14.5 23.2266V29.2266C14.5 29.757 14.7107 30.2657 15.0858 30.6408C15.4609 31.0158 15.9696 31.2266 16.5 31.2266H29.5C30.0304 31.2266 30.5391 31.0158 30.9142 30.6408C31.2893 30.2657 31.5 29.757 31.5 29.2266ZM17.5 29.2266V23.2266H29.5V29.2266H17.5ZM31.5 18.2266H30C30 15.2266 28.19 12.4966 25.42 11.3166L24.5 13.2266L22.5 9.22656C24.8869 9.22656 27.1761 10.1748 28.864 11.8626C30.5518 13.5504 31.5 15.8396 31.5 18.2266Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
3
mobile/assets/video-editor/video-editor-trim-action.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="41" height="41" viewBox="0 0 41 41" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M27.8816 28.7689L20.5736 21.4609L17.4536 24.5799C17.6003 24.8299 17.7083 25.0932 17.7776 25.3699C17.847 25.6465 17.8816 25.9332 17.8816 26.2299C17.8816 27.1399 17.558 27.9185 16.9106 28.5659C16.2633 29.2139 15.485 29.5379 14.5756 29.5379C13.6663 29.5379 12.8873 29.2142 12.2386 28.5669C11.59 27.9195 11.2656 27.1412 11.2656 26.2319C11.2656 25.3225 11.5896 24.5439 12.2376 23.8959C12.8856 23.2465 13.6643 22.9219 14.5736 22.9219C14.8696 22.9219 15.1563 22.9565 15.4336 23.0259C15.7103 23.0952 15.9736 23.2029 16.2236 23.3489L19.3436 20.2299L16.2236 17.1099C15.9736 17.2565 15.7103 17.3645 15.4336 17.4339C15.157 17.5032 14.8703 17.5379 14.5736 17.5379C13.6643 17.5379 12.8856 17.2142 12.2376 16.5669C11.5896 15.9195 11.2656 15.1412 11.2656 14.2319C11.2656 13.3225 11.5893 12.5439 12.2366 11.8959C12.884 11.2465 13.6623 10.9219 14.5716 10.9219C15.481 10.9219 16.2596 11.2459 16.9076 11.8939C17.557 12.5419 17.8816 13.3205 17.8816 14.2299C17.8816 14.5259 17.847 14.8125 17.7776 15.0899C17.7083 15.3665 17.6006 15.6299 17.4546 15.8799L29.7266 28.1529V28.7689H27.8816ZM23.1116 18.9219L21.8816 17.6919L27.8816 11.6919H29.7276V12.3069L23.1116 18.9219ZM14.5746 16.5379C15.2093 16.5379 15.7526 16.3119 16.2046 15.8599C16.6566 15.4079 16.882 14.8645 16.8806 14.2299C16.8793 13.5952 16.6536 13.0519 16.2036 12.5999C15.7536 12.1479 15.2103 11.9219 14.5736 11.9219C13.937 11.9219 13.3936 12.1479 12.9436 12.5999C12.4936 13.0519 12.2676 13.5952 12.2656 14.2299C12.2636 14.8645 12.4896 15.4079 12.9436 15.8599C13.3976 16.3119 13.942 16.5379 14.5746 16.5379ZM14.5736 28.5379C15.2083 28.5379 15.7516 28.3119 16.2036 27.8599C16.6556 27.4079 16.8813 26.8645 16.8806 26.2299C16.88 25.5952 16.6543 25.0519 16.2036 24.5999C15.753 24.1479 15.2096 23.9219 14.5736 23.9219C13.9376 23.9219 13.3943 24.1479 12.9436 24.5999C12.493 25.0519 12.267 25.5952 12.2656 26.2299C12.2643 26.8645 12.4903 27.4079 12.9436 27.8599C13.397 28.3119 13.9403 28.5379 14.5736 28.5379Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.0 KiB |
4
mobile/flutter_launcher_icons-dev.yaml
Normal file
@@ -0,0 +1,4 @@
|
||||
flutter_launcher_icons:
|
||||
android: "launcher_icon"
|
||||
ios: true
|
||||
image_path: "assets/launcher_icon/ente-icon-dev.png"
|
||||
@@ -1,5 +1,5 @@
|
||||
# Uncomment this line to define a global platform for your project
|
||||
platform :ios, '12.0'
|
||||
platform :ios, '12.1'
|
||||
|
||||
|
||||
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
|
||||
|
||||
@@ -10,6 +10,13 @@ PODS:
|
||||
- Flutter
|
||||
- device_info_plus (0.0.1):
|
||||
- Flutter
|
||||
- ffmpeg-kit-ios-min (6.0)
|
||||
- ffmpeg_kit_flutter_min (6.0.3):
|
||||
- ffmpeg_kit_flutter_min/min (= 6.0.3)
|
||||
- Flutter
|
||||
- ffmpeg_kit_flutter_min/min (6.0.3):
|
||||
- ffmpeg-kit-ios-min (= 6.0)
|
||||
- Flutter
|
||||
- file_saver (0.0.1):
|
||||
- Flutter
|
||||
- Firebase/CoreOnly (10.24.0):
|
||||
@@ -105,6 +112,8 @@ PODS:
|
||||
- Flutter
|
||||
- image_editor_common (1.0.0):
|
||||
- Flutter
|
||||
- image_picker_ios (0.0.1):
|
||||
- Flutter
|
||||
- in_app_purchase_storekit (0.0.1):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
@@ -230,6 +239,7 @@ DEPENDENCIES:
|
||||
- connectivity_plus (from `.symlinks/plugins/connectivity_plus/darwin`)
|
||||
- dart_ui_isolate (from `.symlinks/plugins/dart_ui_isolate/ios`)
|
||||
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
|
||||
- ffmpeg_kit_flutter_min (from `.symlinks/plugins/ffmpeg_kit_flutter_min/ios`)
|
||||
- file_saver (from `.symlinks/plugins/file_saver/ios`)
|
||||
- firebase_core (from `.symlinks/plugins/firebase_core/ios`)
|
||||
- firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`)
|
||||
@@ -245,6 +255,7 @@ DEPENDENCIES:
|
||||
- fluttertoast (from `.symlinks/plugins/fluttertoast/ios`)
|
||||
- home_widget (from `.symlinks/plugins/home_widget/ios`)
|
||||
- image_editor_common (from `.symlinks/plugins/image_editor_common/ios`)
|
||||
- image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`)
|
||||
- in_app_purchase_storekit (from `.symlinks/plugins/in_app_purchase_storekit/darwin`)
|
||||
- integration_test (from `.symlinks/plugins/integration_test/ios`)
|
||||
- local_auth_darwin (from `.symlinks/plugins/local_auth_darwin/darwin`)
|
||||
@@ -277,6 +288,7 @@ DEPENDENCIES:
|
||||
|
||||
SPEC REPOS:
|
||||
trunk:
|
||||
- ffmpeg-kit-ios-min
|
||||
- Firebase
|
||||
- FirebaseCore
|
||||
- FirebaseCoreInternal
|
||||
@@ -309,6 +321,8 @@ EXTERNAL SOURCES:
|
||||
:path: ".symlinks/plugins/dart_ui_isolate/ios"
|
||||
device_info_plus:
|
||||
:path: ".symlinks/plugins/device_info_plus/ios"
|
||||
ffmpeg_kit_flutter_min:
|
||||
:path: ".symlinks/plugins/ffmpeg_kit_flutter_min/ios"
|
||||
file_saver:
|
||||
:path: ".symlinks/plugins/file_saver/ios"
|
||||
firebase_core:
|
||||
@@ -339,6 +353,8 @@ EXTERNAL SOURCES:
|
||||
:path: ".symlinks/plugins/home_widget/ios"
|
||||
image_editor_common:
|
||||
:path: ".symlinks/plugins/image_editor_common/ios"
|
||||
image_picker_ios:
|
||||
:path: ".symlinks/plugins/image_picker_ios/ios"
|
||||
in_app_purchase_storekit:
|
||||
:path: ".symlinks/plugins/in_app_purchase_storekit/darwin"
|
||||
integration_test:
|
||||
@@ -404,6 +420,8 @@ SPEC CHECKSUMS:
|
||||
connectivity_plus: ddd7f30999e1faaef5967c23d5b6d503d10434db
|
||||
dart_ui_isolate: d5bcda83ca4b04f129d70eb90110b7a567aece14
|
||||
device_info_plus: c6fb39579d0f423935b0c9ce7ee2f44b71b9fce6
|
||||
ffmpeg-kit-ios-min: 4e9a088f4ee9629435960b9d68e54848975f1931
|
||||
ffmpeg_kit_flutter_min: 5eff47f4965bf9d1150e98961eb6129f5ae3f28c
|
||||
file_saver: 503e386464dbe118f630e17b4c2e1190fa0cf808
|
||||
Firebase: 91fefd38712feb9186ea8996af6cbdef41473442
|
||||
firebase_core: 66b99b4fb4e5d7cc4e88d4c195fe986681f3466a
|
||||
@@ -426,6 +444,7 @@ SPEC CHECKSUMS:
|
||||
GoogleUtilities: d053d902a8edaa9904e1bd00c37535385b8ed152
|
||||
home_widget: 0434835a4c9a75704264feff6be17ea40e0f0d57
|
||||
image_editor_common: d6f6644ae4a6de80481e89fe6d0a8c49e30b4b43
|
||||
image_picker_ios: c560581cceedb403a6ff17f2f816d7fea1421fc1
|
||||
in_app_purchase_storekit: 0e4b3c2e43ba1e1281f4f46dd71b0593ce529892
|
||||
integration_test: ce0a3ffa1de96d1a89ca0ac26fca7ea18a749ef4
|
||||
libwebp: 1786c9f4ff8a279e4dac1e8f385004d5fc253009
|
||||
@@ -469,6 +488,6 @@ SPEC CHECKSUMS:
|
||||
volume_controller: 531ddf792994285c9b17f9d8a7e4dcdd29b3eae9
|
||||
wakelock_plus: 8b09852c8876491e4b6d179e17dfe2a0b5f60d47
|
||||
|
||||
PODFILE CHECKSUM: c1a8f198a245ed1f10e40b617efdb129b021b225
|
||||
PODFILE CHECKSUM: 3c51755c77077d1aa4ef23d06c621f6e2569214c
|
||||
|
||||
COCOAPODS: 1.15.2
|
||||
|
||||
@@ -307,6 +307,7 @@
|
||||
"${BUILT_PRODUCTS_DIR}/fluttertoast/fluttertoast.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/home_widget/home_widget.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/image_editor_common/image_editor_common.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/image_picker_ios/image_picker_ios.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/in_app_purchase_storekit/in_app_purchase_storekit.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/integration_test/integration_test.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/libwebp/libwebp.framework",
|
||||
@@ -337,6 +338,14 @@
|
||||
"${BUILT_PRODUCTS_DIR}/video_thumbnail/video_thumbnail.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/volume_controller/volume_controller.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/wakelock_plus/wakelock_plus.framework",
|
||||
"${PODS_XCFRAMEWORKS_BUILD_DIR}/ffmpeg-kit-ios-min/ffmpegkit.framework/ffmpegkit",
|
||||
"${PODS_XCFRAMEWORKS_BUILD_DIR}/ffmpeg-kit-ios-min/libavcodec.framework/libavcodec",
|
||||
"${PODS_XCFRAMEWORKS_BUILD_DIR}/ffmpeg-kit-ios-min/libavdevice.framework/libavdevice",
|
||||
"${PODS_XCFRAMEWORKS_BUILD_DIR}/ffmpeg-kit-ios-min/libavfilter.framework/libavfilter",
|
||||
"${PODS_XCFRAMEWORKS_BUILD_DIR}/ffmpeg-kit-ios-min/libavformat.framework/libavformat",
|
||||
"${PODS_XCFRAMEWORKS_BUILD_DIR}/ffmpeg-kit-ios-min/libavutil.framework/libavutil",
|
||||
"${PODS_XCFRAMEWORKS_BUILD_DIR}/ffmpeg-kit-ios-min/libswresample.framework/libswresample",
|
||||
"${PODS_XCFRAMEWORKS_BUILD_DIR}/ffmpeg-kit-ios-min/libswscale.framework/libswscale",
|
||||
"${PODS_XCFRAMEWORKS_BUILD_DIR}/media_kit_libs_ios_video/Ass.framework/Ass",
|
||||
"${PODS_XCFRAMEWORKS_BUILD_DIR}/media_kit_libs_ios_video/Avcodec.framework/Avcodec",
|
||||
"${PODS_XCFRAMEWORKS_BUILD_DIR}/media_kit_libs_ios_video/Avfilter.framework/Avfilter",
|
||||
@@ -389,6 +398,7 @@
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/fluttertoast.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/home_widget.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/image_editor_common.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/image_picker_ios.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/in_app_purchase_storekit.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/integration_test.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/libwebp.framework",
|
||||
@@ -419,6 +429,14 @@
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/video_thumbnail.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/volume_controller.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/wakelock_plus.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ffmpegkit.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/libavcodec.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/libavdevice.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/libavfilter.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/libavformat.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/libavutil.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/libswresample.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/libswscale.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Ass.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Avcodec.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Avfilter.framework",
|
||||
|
||||
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 6.0 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 5.7 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 9.2 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 4.7 KiB |