Compare commits

...

384 Commits

Author SHA1 Message Date
Neeraj Gupta
a5c28f1a8e [cli] Add support for handling passkey based MFA (#2195)
## Description
- Print help docs when no input is passed.

## Tests
Tested locally
2024-06-18 14:38:09 +05:30
Neeraj Gupta
dd3d9c8d51 [cli] Bump version 0.1.16 2024-06-18 14:37:38 +05:30
Neeraj Gupta
58b9121e52 Add support to handle passkey verification 2024-06-18 14:36:15 +05:30
Manav Rathi
429d9fdbe5 [pk] Whitelist ente-cli's custom protocol (#2194) 2024-06-18 14:26:45 +05:30
Neeraj Gupta
dcbdeca64e [cli] Print help when no command is specified 2024-06-18 14:25:21 +05:30
Manav Rathi
32faa7f4f8 [pk] Whitelist ente-cli's custom protocol 2024-06-18 14:24:02 +05:30
Neeraj Gupta
ecb0d47055 [cli] Helper method to open url in browser 2024-06-18 14:15:31 +05:30
Manav Rathi
6645bd59b0 [web] Allow user to update subscriptions after cancel (#2192)
This fixes the issue reported by a user where they cancelled their
subscription, then later on tried to upgrade, but were then redirected
to the new subscription flow instead of the upgrade flow.

**Tested (on localhost):**

- [x] Buy new plan
- [x] Change existing plan
- [x] Change existing plan after cancelling
2024-06-18 13:43:46 +05:30
Manav Rathi
34f92f93e5 [docs] Add sidebar link to missing thumbs troubleshooting page (#2191) 2024-06-18 13:07:37 +05:30
Manav Rathi
00a293df02 [docs] Add sidebar link to missing thumbs troubleshooting page 2024-06-18 13:07:06 +05:30
Manav Rathi
8ebdab291c [docs] Mention Firefox's privacy.resistFingerprinting issue (#2190) 2024-06-18 13:05:28 +05:30
Manav Rathi
148ee3f2c4 lf 2024-06-18 13:03:04 +05:30
Manav Rathi
4428996541 Fix 2024-06-18 13:02:28 +05:30
Manav Rathi
fdd2bffc07 [docs] Mention Firefox's privacy.resistFingerprinting issue 2024-06-18 13:00:52 +05:30
Manav Rathi
dbf737092b [web] Allow user to update subscriptions after cancel
This fixes the issue reported by a user where they cancelled their subscription,
then later on tried to upgrade, but were then redirected to the new subscription
flow instead of the upgrade flow.
2024-06-18 11:30:39 +05:30
Manav Rathi
5506652179 [web-ish] yarn 1.22.21 => 1.22.22 (#2188) 2024-06-18 11:00:01 +05:30
Manav Rathi
d1c9033866 [web-ish] yarn 1.22.21 => 1.22.22 2024-06-18 10:56:37 +05:30
Manav Rathi
795767b2cb [worker] Log on all non-200 responses from upstream +1 (#2187)
- Allow albums.ente.io/sh
- Log on all non-200 responses from upstream
- Use an easier to grep label
2024-06-18 10:08:16 +05:30
Manav Rathi
544a1df21b Log on all non-200 responses from upstream 2024-06-18 09:58:36 +05:30
Manav Rathi
1dffe49069 Apparently shared albums code also uses the upload URL
Need to understand more why this is happening, but it is.
2024-06-18 09:55:44 +05:30
Manav Rathi
64dedb7edd thumb 2024-06-18 09:50:20 +05:30
Manav Rathi
7566702569 Allow albums.ente.io/sh 2024-06-18 09:38:45 +05:30
Manav Rathi
d006f74cd4 add human readable upload result to log file output (#2183)
## Description

Make the logfile more user friendly by adding a readable upload result
string instead of just a number.

Before the logfile showed only a not human understandable number for the
upload result:
`"Uploaded xyz.jpg with result 3"` 

This PR adds the key from the enum UPLOAD_RESULT to make it easy for a
human to understand the result:
`"Uploaded xyz.jpg with result 3 (BLOCKED)"`
2024-06-18 09:32:15 +05:30
Manav Rathi
27191d777a [web] Faster and noUncheckedIndexedAccess compliant uint8array merging (#2186)
The script I used for testing - 10-100x faster, and the faster the
longer the arrays. Note that speed was not the primary motivator for
this change, I just wanted to enable `noUncheckedIndexedAccess`

```js
//zs = [...Array(10).keys()].map(() => Uint8Array.from(Array(100000).keys()));                                                    
zs = [...Array(100).keys()].map(() => Uint8Array.from(Array(1000).keys()));

const m0 = (as) => new Uint8Array(as.reduce((acc, x) => acc.concat(...x), []));

const mergeUint8Arrays = (as) => {
    const len = as.reduce((len, xs) => len + xs.length, 0);
    const result = new Uint8Array(len);
    as.reduce((n, xs) => (result.set(xs, n), n + xs.length), 0);
    return result;
};

s = performance.now();
a = m0(zs);
e = performance.now();
console.log(e - s, "ms", a.length, "m0");
//console.log(a);                                                                                                                 

s = performance.now();
b = mergeUint8Arrays(zs);
e = performance.now();
console.log(e - s, "ms", b.length, "merge");
//console.log(b);                                                                                                                 

console.log(JSON.stringify(a) === JSON.stringify(b))
```
2024-06-18 09:28:25 +05:30
Manav Rathi
c68a16a9a9 Enable 2024-06-18 09:25:35 +05:30
Manav Rathi
ed1e6df967 Faster and noUncheckedIndexedAccess compliant 2024-06-18 09:19:43 +05:30
Joachim Weinbrenner
93f9848d02 add human readable upload result to log 2024-06-17 21:17:15 +02:00
Manav Rathi
aa0325d72c Faster method that doesn't trip up noUncheckedIndexedAccess 2024-06-17 20:29:28 +05:30
Manav Rathi
4510c14af2 Add a merge function 2024-06-17 19:58:46 +05:30
Manav Rathi
dc709e7649 [workers] Ignore case when comparing allowed headers (#2179) 2024-06-17 18:37:54 +05:30
Manav Rathi
b7fdf6c66b Log on errors 2024-06-17 18:35:59 +05:30
Manav Rathi
9f5115cc08 [workers] Ignore case when comparing allowed headers 2024-06-17 18:31:45 +05:30
Manav Rathi
a9bace7781 [desktop] Continue iterating of the pre-release process (#2177)
Ref:
https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#filter-pattern-cheat-sheet
2024-06-17 16:47:56 +05:30
Manav Rathi
014fbfe0eb lf 2024-06-17 16:42:36 +05:30
Manav Rathi
38cdfcf0a4 [desktop] Continue iterating of the pre-release process 2024-06-17 16:40:35 +05:30
Manav Rathi
3f9107c497 [server] Stop making 32 bit ARM images (#2175)
The code doesn't get tested or run and is likely not safe for 32 bits

> 941.0 pkg/utils/billing/billing.go:117:13: cannot use
ente.FreePlanStorage
(untyped int constant 5368709120) as int value in struct literal
(overflows)
>
>
https://github.com/ente-io/ente/actions/runs/9546167833/job/26308448952
2024-06-17 16:28:17 +05:30
Manav Rathi
8870738330 [server] Stop making 32 bit ARM images
The code doesn't get tested or run and is likely not safe for 32 bits

> 941.0 pkg/utils/billing/billing.go:117:13: cannot use ente.FreePlanStorage
  (untyped int constant 5368709120) as int value in struct literal (overflows)
>
> https://github.com/ente-io/ente/actions/runs/9546167833/job/26308448952
2024-06-17 16:26:55 +05:30
Manav Rathi
38cae5c3d9 [docs] Passkeys: mention blog post (#2173) 2024-06-17 16:10:07 +05:30
Manav Rathi
e133e6272a [docs] Passkeys: mention blog post 2024-06-17 16:09:13 +05:30
Manav Rathi
c486b8f2c1 [desktop] Next RC (#2172) 2024-06-17 14:25:03 +05:30
Manav Rathi
f6cbbbead6 [docs] Mark passkeys as released (#2171) 2024-06-17 14:24:41 +05:30
Manav Rathi
3ecef5e751 [desktop] Next RC 2024-06-17 14:23:38 +05:30
Manav Rathi
ef64ce065b [docs] Mark passkeys as released 2024-06-17 14:09:56 +05:30
Manav Rathi
99fdbd8d40 photosd-v1.7.1 (#2170) 2024-06-17 13:57:28 +05:30
Manav Rathi
ac4a68d64e photosd-v1.7.1 2024-06-17 13:55:31 +05:30
Manav Rathi
dae5b29ef1 [docs] Add a border to help differentiate the image from the subsequent text (#2169)
Nb: black works fine in dark mode too
2024-06-17 12:24:14 +05:30
Manav Rathi
4451b489e4 Add a border to help differentiate the image from the subsequent text
black works fine in dark mode too
2024-06-17 12:22:47 +05:30
Manav Rathi
b19281ea2b [web] Update cast to use the tsconfig we want (#2168) 2024-06-17 12:08:41 +05:30
Manav Rathi
8e923fe443 All 2024-06-17 11:46:34 +05:30
Manav Rathi
fe47186ace tsc 2024-06-17 11:45:28 +05:30
Manav Rathi
326704a605 tsc 2024-06-17 11:38:13 +05:30
Manav Rathi
d560ed9a33 Reduce state 2024-06-17 11:35:19 +05:30
Manav Rathi
0a8f51832a tsc 2024-06-17 11:34:16 +05:30
Neeraj Gupta
d2112b984d Added coindcx icon (#2148)
## Description
Added coindcx icon
uploaded coindcx svg and updated json file.
2024-06-17 11:24:48 +05:30
Neeraj Gupta
50aad0c5d1 [Auth] Passkey fix for linux (#2154)
## Description

- Updated url to enteauth://passkey
- Support mimetype in appimage so redirection is done properly

## Tests
2024-06-17 11:24:09 +05:30
Manav Rathi
e6e721f0ba [workers] Import upload worker (#2164) 2024-06-17 09:12:15 +05:30
Manav Rathi
80b34f1aef Reduce spurious logs for headers our clients send 2024-06-17 09:03:27 +05:30
Manav Rathi
d5a8586152 Import functionality
Rewritten but referencing the code imported from dashboard
2024-06-17 03:40:20 +05:30
Manav Rathi
bfcd84c940 Whitelist the necessary one 2024-06-16 20:56:28 +05:30
Manav Rathi
a4bc5fa0df OPTIONS 2024-06-16 20:49:44 +05:30
Manav Rathi
ed406e7eb0 Sketch 2024-06-16 20:33:56 +05:30
Manav Rathi
b4dc49ef2f [workers] Import health check worker (#2162) 2024-06-16 19:43:31 +05:30
Manav Rathi
483e3be682 Improvements 2024-06-16 19:40:03 +05:30
Manav Rathi
17f0d77a31 Reorder to fix errors 2024-06-16 19:18:39 +05:30
Manav Rathi
c6f644ef8a [workers] Import health check worker 2024-06-16 19:12:52 +05:30
Prateek Sunal
01b566698f fix(workflow/auth): revert back flutter_distributor to pub.dev source 2024-06-16 17:03:45 +05:30
Manav Rathi
469f884d8c [workers] Import files worker (#2161) 2024-06-16 15:01:26 +05:30
Manav Rathi
9e4412cbee Correct place 2024-06-16 14:52:15 +05:30
Manav Rathi
f4bab262ca Import 2024-06-16 14:47:35 +05:30
Manav Rathi
73fd63616d Sketch 2024-06-16 14:39:05 +05:30
Manav Rathi
9362a4b9d3 Reduce log noise 2024-06-16 14:29:54 +05:30
Manav Rathi
6c5ea59506 [workers] Import thumbnails worker (#2160) 2024-06-16 14:19:02 +05:30
Manav Rathi
90845bdb02 Rename 2024-06-16 14:12:16 +05:30
Manav Rathi
f6729be5ab Fix typo 2024-06-16 14:09:20 +05:30
Manav Rathi
344c5cc399 Desktop origin includes scheme 2024-06-16 14:06:20 +05:30
Manav Rathi
6e1ea29c39 Implement
Rewritten, but referencing the existing worker imported from the dashboard
2024-06-16 13:51:42 +05:30
Manav Rathi
d76c6dd63c Sketch 2024-06-16 13:24:56 +05:30
Manav Rathi
f69daa4608 [workers] Import public albums worker (#2158) 2024-06-16 10:19:42 +05:30
Manav Rathi
290564c973 x-client-package
Albums app is using the old axios layer which is passing "x-client-package",
will also allow that for now
2024-06-16 10:06:22 +05:30
Manav Rathi
b781f33e4b ditto 2024-06-16 09:57:44 +05:30
Manav Rathi
b8bc01561d GET
Rewritten, but referencing the existing worker imported from the dashboard
2024-06-16 09:55:49 +05:30
Manav Rathi
734cb798d3 Handle options
Rewritten, but referencing the existing worker imported from the dashboard
2024-06-16 09:27:59 +05:30
Manav Rathi
ac8ebd0ed3 Skeleton 2024-06-16 08:56:07 +05:30
Manav Rathi
fc5eb296d2 Disable default route 2024-06-16 08:39:59 +05:30
Manav Rathi
c05d8a8e44 [worker] Use tail worker for logging (#2153) 2024-06-15 22:59:50 +05:30
Manav Rathi
24845a4735 Update README 2024-06-15 22:56:32 +05:30
Manav Rathi
2b490fe131 Cleanup 2024-06-15 22:49:35 +05:30
Manav Rathi
07f0cc9342 Need to pass creds in authorization header 2024-06-15 22:35:38 +05:30
Manav Rathi
49ddd287d0 Only log interesting events 2024-06-15 20:18:10 +05:30
Manav Rathi
bffcd11100 console.log 2024-06-15 19:47:20 +05:30
Manav Rathi
25d6ebdb19 Add a check for an upcoming restriction 2024-06-15 19:42:10 +05:30
Manav Rathi
64a539adb0 Hook it up 2024-06-15 19:23:05 +05:30
Manav Rathi
3646809f06 Promise<void>
Ref: https://dev.to/krasun/pushing-cloudflare-worker-logs-to-grafana-loki-1elg
2024-06-15 19:18:39 +05:30
Manav Rathi
fb0e857514 Push the entire event (it contains the worker name too) 2024-06-15 19:16:17 +05:30
Manav Rathi
a1059c543b Fill in 2024-06-15 19:09:42 +05:30
Manav Rathi
8fe2b9cb27 The protocol 2024-06-15 18:27:44 +05:30
Manav Rathi
5e080a90e3 Skeletal tail worker 2024-06-15 17:51:46 +05:30
Vishnu Mohandas
08255b3f8a ente -> Ente (#2151) 2024-06-15 16:21:45 +05:30
vishnukvmd
f032739461 ente -> Ente 2024-06-15 16:21:10 +05:30
Manav Rathi
841da80c97 [workers] Minor cleanup, in prep for moving more of their siblings here (#2149) 2024-06-15 12:28:34 +05:30
Manav Rathi
60b1c32567 Note 2024-06-15 12:09:21 +05:30
Manav Rathi
bd6ac2c4fc Sync 2024-06-15 12:03:32 +05:30
Manav Rathi
eaccba5f22 Explicit header whitelist 2024-06-15 12:02:29 +05:30
Manav Rathi
562313b218 Tweaks 2024-06-15 11:54:26 +05:30
Manav Rathi
0650d176ee Latest yarn
Corepack will automatically install the latest one
2024-06-15 11:44:39 +05:30
Manav Rathi
6bbd944de4 Update compt date
> When you start your project, you should always set compatibility_date to the
> current date. You should occasionally update the compatibility_date field.
>
> https://developers.cloudflare.com/workers/configuration/compatibility-dates/
2024-06-15 11:41:09 +05:30
Manav Rathi
8aaad79897 yarn add --dev '@cloudflare/workers-types@latest' 2024-06-15 11:39:56 +05:30
Manav Rathi
d499549734 Use syntax recommended in docs
https://developers.cloudflare.com/workers/configuration/routing/custom-domains
2024-06-15 11:26:54 +05:30
Nikunj Kumar Nakum
db22c5bc97 Update custom-icons.json
updated coindcx icon
2024-06-15 10:51:25 +05:30
Nikunj Kumar Nakum
34f49362fd Added CoinDCX icon
Uploaded coindcx svg file
2024-06-15 10:46:49 +05:30
Manav Rathi
af21ff640d (CF's) fetch can return a promise 2024-06-15 10:03:39 +05:30
Manav Rathi
69e69c2e0f Formatting and other minor tweaks 2024-06-15 09:54:28 +05:30
Vishnu Mohandas
a0445fb4f6 v901 (#2142) 2024-06-15 00:42:56 +05:30
Prateek Sunal
8161403d84 fix(workflow/auth): use custom distributor repo for appimage 2024-06-15 00:39:51 +05:30
Prateek Sunal
0713e34aec chore(auth): bump packages 2024-06-15 00:35:46 +05:30
Prateek Sunal
b504f554b3 fix(auth): add mimetype to appimage 2024-06-15 00:35:27 +05:30
vishnukvmd
3d6af698b6 v901 2024-06-15 00:00:07 +05:30
Prateek Sunal
ff3ddb3d8d fix(auth): update deep link for linux 2024-06-14 22:52:29 +05:30
Neeraj Gupta
16817eceac [photos] Update bundle name from ente Photos -> Ente Photos (#2141)
## Description

## Tests
2024-06-14 16:02:15 +05:30
Neeraj Gupta
500e40035f [photos] Update bundle name from ente Photos -> Ente Photos 2024-06-14 15:59:44 +05:30
Neeraj Gupta
366da2c328 [photos] Bump version v0.9.0 (#2140)
## Description

## Tests
2024-06-14 15:59:21 +05:30
Neeraj Gupta
203d46b2cf [photos] Bump version v0.9.0 2024-06-14 15:56:15 +05:30
Manav Rathi
0e772fcfb7 [desktop] Fix duplicate file uploads when initializing a folder watch (#2138)
This didn't happen always, it was a race condition dependending on when
the `this.eventQueue = []` in `syncWithDisk` happened.
2024-06-14 15:25:58 +05:30
Manav Rathi
bbd6745372 Add CHANGELOG entries 2024-06-14 15:18:57 +05:30
Manav Rathi
dd1e0a9b1d Fix duplicate file uploads when initializing a folder watch
This didn't happen always, it was a race condition dependending on when the
`this.eventQueue = []` in `syncWithDisk` happened.
2024-06-14 15:11:36 +05:30
Neeraj Gupta
940231e38d [mob][auth] Fix handling of passkey when email verification is turned on (#2137)
## Description

## Tests
2024-06-14 14:41:39 +05:30
Neeraj Gupta
4c8db02de5 [auth] Bump version to v3.0.12 2024-06-14 14:39:51 +05:30
Neeraj Gupta
8af5aadd1b [mob] Bump photos version to v0.8.139 2024-06-14 14:39:25 +05:30
Neeraj Gupta
205feab4c2 [mob][auth] Fix passkey authn flow when emailVerification is enabled 2024-06-14 14:38:44 +05:30
Manav Rathi
60ab2b4427 [web] New translations (#2128)
New translations from
[Crowdin](https://crowdin.com/project/ente-photos-web)
2024-06-14 14:37:35 +05:30
Crowdin Bot
612329f584 New Crowdin translations by GitHub Action 2024-06-14 09:06:18 +00:00
Manav Rathi
a5f4a676a7 [web] Passkeys misc loose ends (#2136) 2024-06-14 14:35:32 +05:30
Manav Rathi
9608cfaa4e Don't show retry button if trying to use an already claimed session 2024-06-14 14:30:10 +05:30
Manav Rathi
ddd4d3e16c "Scripts may only close windows that were opened by them" 2024-06-14 14:04:42 +05:30
Manav Rathi
df0d48af73 [desktop] Add a check status button to the passkey waiting page (#2132) 2024-06-14 13:55:54 +05:30
Manav Rathi
c82193cae6 Enable passkeys for everyone 2024-06-14 13:51:21 +05:30
Manav Rathi
2c0928bd02 Change to photos favicon
he accounts favicon does not show on a white background (second image is the
hover state showing that the icon is actually there). For now, changing it to
the photos favicon, until we have an app neutral favicon.
2024-06-14 13:49:45 +05:30
Manav Rathi
8c8ffa9397 Add a hint to retry on other devices 2024-06-14 13:42:30 +05:30
Manav Rathi
3689ecb6e7 Add a message 2024-06-14 13:26:05 +05:30
Manav Rathi
ca080ad6b2 Split the flow 2024-06-14 13:07:00 +05:30
Neeraj Gupta
48d9ac63bb [auth] Bump version to v3.0.11 (#2135)
## Description

## Tests
2024-06-14 12:58:28 +05:30
Neeraj Gupta
887066962f [auth] Bump version to v3.0.11 2024-06-14 12:57:54 +05:30
Neeraj Gupta
cb2615b083 [auth] Fix url scheme for auth windows app (#2134)
## Description

## Tests
2024-06-14 12:57:07 +05:30
Neeraj Gupta
de459e68eb [auth] Fix url scheme for auth windows app 2024-06-14 12:42:41 +05:30
Neeraj Gupta
9cc559870c [auth] New translations (#2129)
New translations from
[Crowdin](https://crowdin.com/project/ente-authenticator-app)
2024-06-14 12:29:53 +05:30
Neeraj Gupta
395774c0e4 [auth] Fix twoFas import with missing issuerName (#2133)
## Description

## Tests
2024-06-14 12:29:32 +05:30
Neeraj Gupta
b3a7aebf95 [auth] Fix twoFas import with missing issuerName 2024-06-14 12:25:47 +05:30
Manav Rathi
b2e56fc01e Lint fix 2024-06-14 12:23:09 +05:30
Neeraj Gupta
0e0761bac7 Change log (#2131)
## Description

## Tests
2024-06-14 12:22:58 +05:30
Neeraj Gupta
79d7fe18ea [photos] Add change log for release 2024-06-14 12:20:34 +05:30
Manav Rathi
228dd90bce Make the retry code (almost) exactly the same as it was before
in an attempt at superstition (since rationality doesn't seem to work with
Safari).
2024-06-14 12:11:43 +05:30
Manav Rathi
93380d05b4 Add TODO 2024-06-14 12:04:34 +05:30
Manav Rathi
4123197c6d Use 2024-06-14 11:46:55 +05:30
Manav Rathi
cc3f398a78 Happy path 2024-06-14 11:41:50 +05:30
Neeraj Gupta
48155692ff Extract string 2024-06-14 11:37:30 +05:30
Manav Rathi
dd0f7d3142 Handle errors 2024-06-14 11:17:51 +05:30
Manav Rathi
325c963b7a Mix 2024-06-14 11:03:13 +05:30
Manav Rathi
fbf29585eb UI 2024-06-14 10:51:58 +05:30
Manav Rathi
8a2cc858ae API method 2024-06-14 10:10:09 +05:30
Crowdin Bot
b931825d3b New Crowdin translations by GitHub Action 2024-06-14 02:09:16 +00:00
Neeraj Gupta
2dc9b015a6 Add monochrome icon support for android (#2118)
## Description
Add monochrome icon support for android

## Tests
not tested
2024-06-14 06:04:55 +05:30
Neeraj Gupta
32c2456f03 [Passkey] Add check status option + other fixes (#2123)
## Description

## Tests
2024-06-14 06:03:51 +05:30
Neeraj Gupta
084027df31 Bump version for auth and photo 2024-06-13 18:15:58 +05:30
Neeraj Gupta
852878e3f4 [server] Reduce passkey JWT duration + API to get token via sessionID (#2111)
## Description

## Tests
Monkey tested locally
2024-06-13 18:07:37 +05:30
Neeraj Gupta
f07e88b2dc [mob] Lint fixes 2024-06-13 18:06:33 +05:30
Neeraj Gupta
d2e526769d Reject passkey verification for already claimed session 2024-06-13 17:52:27 +05:30
Neeraj Gupta
867fdb7e2c [passkey][mob] Validate sessionID 2024-06-13 17:50:02 +05:30
Neeraj Gupta
a830b771f8 Merge branch 'main' into auth_testing 2024-06-13 17:16:22 +05:30
Manav Rathi
cc21f1a36d [passkeys] Add a passkeySessionID check (#2125) 2024-06-13 17:07:17 +05:30
Manav Rathi
9ff8469a54 Pass as a query param instead
Mobile prefers it this way
2024-06-13 16:51:04 +05:30
Neeraj Gupta
cfafcf8278 make linter happy 2024-06-13 16:44:16 +05:30
Neeraj Gupta
1829bcfdcf [passkey] Enable for all users on mobile 2024-06-13 16:42:31 +05:30
Manav Rathi
608fec9129 logSet the inflight session 2024-06-13 16:41:09 +05:30
Neeraj Gupta
f5c9fa3d6c [passkey][mob] Minor fixes 2024-06-13 16:39:16 +05:30
Manav Rathi
4a21ee0fa9 Add a sessionID check 2024-06-13 16:29:30 +05:30
Manav Rathi
da853fdfde Rename 2024-06-13 16:21:13 +05:30
Manav Rathi
f2928c8ab8 Return the passkey session id in the redirect data 2024-06-13 16:18:01 +05:30
Manav Rathi
d34bcffafd [photosd] Add a "What's new" dialog (#2124) 2024-06-13 16:13:06 +05:30
Manav Rathi
67028a072c Fix 2024-06-13 16:05:53 +05:30
Manav Rathi
2bbf33287b Handle nightly builds (or versions without changelogs) 2024-06-13 16:00:57 +05:30
Neeraj Gupta
e60df5c54a Merge branch 'main' into auth_testing 2024-06-13 15:25:00 +05:30
Neeraj Gupta
b100392d7e [photos] Passkey changes 2024-06-13 15:24:29 +05:30
Manav Rathi
b2154429f3 Mention pk 2024-06-13 14:49:16 +05:30
Manav Rathi
e9f10f77d9 Fix condition 2024-06-13 14:39:36 +05:30
Neeraj Gupta
1d3452a1f0 [auth] Update copy 2024-06-13 14:35:46 +05:30
Manav Rathi
4e9ff3024c Hook it up 2024-06-13 14:26:53 +05:30
Neeraj Gupta
c193377640 [auth] Add endpoint to check passkey status 2024-06-13 13:54:31 +05:30
Manav Rathi
6f4b20ad6f Link 2024-06-13 13:44:26 +05:30
Manav Rathi
ee86de6b30 Move to gallery
Doesn't make much sense to show it to logged out users
2024-06-13 13:28:01 +05:30
Neeraj Gupta
7930e95f4a [auth] Update copy 2024-06-13 13:16:01 +05:30
Manav Rathi
2c3f82023c [mob] Passkeys: Don't show recover option on accounts page (#2122)
Mobile app shows it on the waiting screen instead (accounts web app
shows the recover option only when the recover query param is passed to
it).

(Did not verify by running on mobile)

/cc @ua741
2024-06-13 13:16:00 +05:30
Neeraj Gupta
1f6c5d9782 [auth] Change primary button color 2024-06-13 13:14:44 +05:30
Manav Rathi
b4640935a8 [mob] Passkeys: Don't show recover option on accounts page
Mobile app shows it on the waiting screen instead (accounts web app shows the
recover option only when the recover query param is passed to it).
2024-06-13 13:11:24 +05:30
Manav Rathi
e64ef1a7d8 [web] New translations (#2114)
New translations from
[Crowdin](https://crowdin.com/project/ente-photos-web)
2024-06-13 13:08:53 +05:30
Crowdin Bot
346e205001 New Crowdin translations by GitHub Action 2024-06-13 07:36:17 +00:00
Manav Rathi
8193379fad [web] Passkey verification waiting screen (#2121) 2024-06-13 13:05:40 +05:30
Manav Rathi
d3b589e622 Comment out for now 2024-06-13 12:56:01 +05:30
Manav Rathi
ec68a11ec3 Accomodate (future) check status button 2024-06-13 12:54:24 +05:30
Manav Rathi
ca949ac077 Sigh
It happens even without the console
2024-06-13 12:47:27 +05:30
Neeraj Gupta
54092c8fba [auth] update flutter submodule v3.22.2 2024-06-13 12:37:23 +05:30
Ashil
4b3f5e4cca [mob][photos] Remove internal user flag (#2120) 2024-06-13 12:35:09 +05:30
ashilkn
aebe483d80 [mob][photos] Remove internal user flag 2024-06-13 12:33:44 +05:30
Manav Rathi
ea5cd4a7d0 Use correct app name 2024-06-13 12:24:20 +05:30
Manav Rathi
15a745266d Use 2024-06-13 12:19:18 +05:30
Manav Rathi
fdde16e76c Update key 2024-06-13 12:18:29 +05:30
Ashil
39adba94dd [Mobile] Add Video Editor (#1748)
## Description

Add the much demanded video editor for photos mobile app, made with the
help of [video_editor](https://pub.dev/packages/video_editor) package
with features like Trim, Crop and Rotate.
2024-06-13 12:02:55 +05:30
Manav Rathi
ef33065c5b Fix URL (again) 2024-06-13 12:00:11 +05:30
Manav Rathi
dab15b2429 Conditional recover 2024-06-13 11:51:38 +05:30
Neeraj Gupta
c0367729a7 Merge branch 'main' into mobile-videoeditor 2024-06-13 11:46:06 +05:30
Neeraj Gupta
fa3d3bceed Added multiple custom icons to Ente Auth (#2117)
Icons added:

- Bitstamp
- ChangeNOW
- Itch.io
- Migros
- Name.com
2024-06-13 11:42:44 +05:30
Manav Rathi
26051985d5 Redirect to correct page 2024-06-13 11:38:56 +05:30
Manav Rathi
fe2f30a92c Improve more 2024-06-13 11:33:34 +05:30
Manav Rathi
af3f2280d6 Improve UX on web 2024-06-13 11:30:20 +05:30
Manav Rathi
d513019e1b Reuse 2024-06-13 11:25:31 +05:30
Manav Rathi
c611d43204 Allow reuse 2024-06-13 11:20:34 +05:30
Manav Rathi
cd76da836d Handle retrying redirects 2024-06-13 11:17:04 +05:30
Manav Rathi
9086d37a7c wip 2024-06-13 11:04:44 +05:30
Ashil
7234aef6c7 [mob][photos] Bump up to v0.8.137 (#2119) 2024-06-13 11:02:55 +05:30
ashilkn
20a4e78998 [mob][photos] Bump up to v0.8.137 2024-06-13 10:48:04 +05:30
Ashil
280fa9a171 [mob][photos] Discovery (behind feature flag) (#2115)
Show Magic search examples on search tab for internal users.
2024-06-13 10:20:37 +05:30
Prateek Sunal
13e0cf1826 fix(mobile): 9:16 crop ratio svg size 2024-06-12 20:15:56 +05:30
Prateek Sunal
498e651d6d fix(mobile): 9:16 crop ratio svg size 2024-06-12 20:06:18 +05:30
Prateek Sunal
66d58d1538 Merge branch 'main' into mobile-videoeditor 2024-06-12 19:57:50 +05:30
Prateek Sunal
27f95e433a chore(mobile): update locals 2024-06-12 19:56:54 +05:30
Prateek Sunal
9053717699 chore(mobile): update locals 2024-06-12 19:55:57 +05:30
Bl4ckspell7
82b6187e26 Add monochrome icon support for android 2024-06-12 15:59:06 +02:00
Christopher Romano
b7bf4e7015 Added Ubuntu One icon 2024-06-12 16:40:36 +03:00
Christopher Romano
fbd572f23a Added Name.com icon 2024-06-12 16:40:36 +03:00
Christopher Romano
92d017a701 Added Migros icon 2024-06-12 16:40:36 +03:00
Christopher Romano
422adf0a62 Added Itch.io icon 2024-06-12 16:40:36 +03:00
Christopher Romano
f85a1da9c2 Added ChangeNOW icon 2024-06-12 16:40:36 +03:00
Christopher Romano
afffcec3f2 Added Bitstamp icon 2024-06-12 16:40:10 +03:00
Prateek Sunal
77715e4d05 chore(mobile): bump version 2024-06-12 17:35:27 +05:30
Prateek Sunal
34eb9d7fba fix(mobile): 9:16 crop ratio svg 2024-06-12 17:21:54 +05:30
Prateek Sunal
01c3308019 [Auth] Disable search suggestions and sort tags (#2112)
## Description

Same as title.

## Tests
2024-06-12 17:09:44 +05:30
Manav Rathi
2f699365fb [web] Passkey - Show a redirect again option on passkeys (#2113) 2024-06-12 16:54:27 +05:30
Manav Rathi
622c4e7258 Fix the check (protocol includes colon) 2024-06-12 16:50:45 +05:30
Ashil
68003e203b [mob][photos] Add logs for debugging stuck at splash screen issue (#2099) 2024-06-12 16:46:10 +05:30
Prateek Sunal
b273ac3cf0 fix(auth): disable autocorrect and it's suggestions 2024-06-12 16:45:20 +05:30
Prateek Sunal
3d46b015e1 fix(auth): sort tags 2024-06-12 16:44:22 +05:30
Manav Rathi
523317eb71 Separate handling for web / app 2024-06-12 16:43:49 +05:30
ashilkn
4ce913cda6 Merge branch 'main' into discovery-3 2024-06-12 16:41:54 +05:30
ashilkn
7fdf52309a [mob][photos] Keep showing of magic examples on search tab behind feature flag 2024-06-12 16:40:39 +05:30
Neeraj Gupta
186981014e Fix typo 2024-06-12 16:40:12 +05:30
Manav Rathi
0bde1ab22d L11n keys 2024-06-12 16:35:55 +05:30
Prateek Sunal
b2f9c6ff6b [Auth] Bump flutter to 3.22 (#2108)
## Description

Black screen issue was caused by
https://github.com/leanflutter/window_manager/issues/460, till then I
have used a workaround from
https://github.com/leanflutter/window_manager/issues/460#issuecomment-2110180143.

Also update plugins.

## Tests
2024-06-12 16:34:51 +05:30
Manav Rathi
6aa810b500 [web] Redirect again button 2024-06-12 16:25:07 +05:30
Neeraj Gupta
cf4d407f39 Add API to get token data for given passkey session 2024-06-12 16:16:48 +05:30
ashilkn
ac05f085c1 [mob][photos] Get magic prompt data from remote 2024-06-12 16:14:09 +05:30
Neeraj Gupta
7e48953b6a Store token data on passkey auth 2024-06-12 15:56:54 +05:30
Manav Rathi
6f4bb6bf95 Update README 2024-06-12 15:37:38 +05:30
Neeraj Gupta
0666fc0ac2 [auth] Register url scheme for macos (#2107)
## Description

## Tests
2024-06-12 15:34:17 +05:30
Manav Rathi
6f304cb7a1 [docs] Add a note about AppImage desktop integration (#2110) 2024-06-12 15:15:30 +05:30
Manav Rathi
30c368d99f [docs] Add a note about AppImage desktop integration 2024-06-12 15:13:32 +05:30
Manav Rathi
adaa81f50c [photosd] Handle passkey deeplinks on Linux and Windows (#2109)
Tested on an Ubuntu 24 VM, with deb it works out of the box, with
AppImage I needed to install `appimaged` as recommended by
https://docs.appimage.org/user-guide/run-appimages.html#integrating-appimages-into-the-desktop.
2024-06-12 15:02:44 +05:30
Prateek Sunal
c8a5ca41a2 fix(workflow/auth): bump flutter versito 3.22 2024-06-12 14:59:09 +05:30
Prateek Sunal
dce84c4262 fix(auth): update for flutter 3.22 2024-06-12 14:57:39 +05:30
Manav Rathi
f529460eda Handle deeplinks on Linux 2024-06-12 14:33:07 +05:30
Neeraj Gupta
ae170acb30 Schema update to enable tokenData fetch for passkey session 2024-06-12 14:27:37 +05:30
Manav Rathi
bfca0730b2 Rearrange in reading order 2024-06-12 14:25:36 +05:30
Neeraj Gupta
c95260a228 Reduce account jwt token validity to 30mins 2024-06-12 14:13:52 +05:30
Prateek Sunal
da43e27688 fix(mobile): update locals for video editor 2024-06-12 14:05:11 +05:30
Neeraj Gupta
2e442c2152 Handle case when account is already logged in 2024-06-12 14:02:17 +05:30
Neeraj Gupta
d15d2437fb Minor refactor 2024-06-12 14:00:58 +05:30
Neeraj Gupta
860ca9852b Show dialog when passkey verification response is processed 2024-06-12 12:23:11 +05:30
Neeraj Gupta
eb8ce32acb Register enteauth url for macos 2024-06-12 12:22:41 +05:30
Prateek Sunal
05327bb028 fix(mobile): background of video editor on light theme 2024-06-12 12:00:20 +05:30
Manav Rathi
47a965f0a1 [web] Passkeys - Fix exhaustive-deps lints (#2106)
Refs: https://legacy.reactjs.org/docs/hooks-reference.html#usestate

> React guarantees that setState function identity is stable and won't
change on
rerenders. This is why it's safe to omit from the useEffect or
useCallback
  dependency list.
2024-06-12 11:31:41 +05:30
Manav Rathi
f7a500b811 [web] Fix exhaustive-deps lints
Refs: https://legacy.reactjs.org/docs/hooks-reference.html#usestate

> React guarantees that setState function identity is stable and won't change on
  rerenders. This is why it's safe to omit from the useEffect or useCallback
  dependency list.
2024-06-12 11:16:24 +05:30
Manav Rathi
0ce25916e6 [docs] Passkeys (#2105) 2024-06-12 10:47:09 +05:30
Manav Rathi
504bae5dd8 [docs] Passkeys 2024-06-12 10:45:25 +05:30
Manav Rathi
8bb748ae22 doc-add link to delete page (#2104) 2024-06-12 10:15:10 +05:30
Jay
e5bc7b218d doc-addlink 2024-06-12 10:12:38 +05:30
Manav Rathi
29ea968408 [docs] Mention yarn pretty (#2103) 2024-06-12 09:47:55 +05:30
Manav Rathi
07cd9be3f4 [docs] Mention yarn pretty 2024-06-12 09:46:45 +05:30
Prateek Sunal
946605554c fix(mobile): sync edited video properly 2024-06-11 23:23:08 +05:30
Prateek Sunal
2b00418695 fix(mobile): move all colors to theme data 2024-06-11 21:27:42 +05:30
Manav Rathi
1a43c0feb2 [web] Upgrade eslint ruleset for accounts app (#2102)
Only one workaround remains.
2024-06-11 21:24:30 +05:30
Manav Rathi
309d3321b9 Fix lint 2024-06-11 21:21:01 +05:30
Manav Rathi
25f2fc46a9 Fix 2024-06-11 20:59:47 +05:30
Manav Rathi
48fc966457 Fix 2024-06-11 20:52:43 +05:30
Manav Rathi
d2fd7dea97 Add an exception 2024-06-11 20:40:36 +05:30
Manav Rathi
a2e93489f2 Fix lints 2024-06-11 20:28:31 +05:30
Manav Rathi
5150dc00e1 Fix lint 2024-06-11 20:25:53 +05:30
Manav Rathi
68ebd1ef69 Fix more lints 2024-06-11 20:24:23 +05:30
Manav Rathi
1d1fa29239 Fix lint 2024-06-11 20:17:02 +05:30
ashilkn
04b3e0c7fb Merge branch 'main' into discovery-3 2024-06-11 18:06:14 +05:30
Neeraj Gupta
624a8bf6a9 [mobile] New translations (#2089)
New translations from
[Crowdin](https://crowdin.com/project/ente-photos-app)
2024-06-11 17:47:31 +05:30
Neeraj Gupta
2bebd2ead7 [auth] New translations (#2090)
New translations from
[Crowdin](https://crowdin.com/project/ente-authenticator-app)
2024-06-11 17:47:17 +05:30
Neeraj Gupta
e7deb0fb94 [mobile] Update passkeys URLs (#2101)
We now explicitly pass a recover URL to the accounts app, and I've added
some placeholder values. This URL will be opened when the user selects
the "Recover passkey" option on the authentication failure screen.
2024-06-11 17:46:47 +05:30
Manav Rathi
d37cb971aa [mobile] Update passkeys URLs
We now explicitly pass a recover URL to the accounts app, and I've added some
placeholder values. This URL will be opened when the user selects the "Recover
passkey" option on the authentication failure screen.
2024-06-11 17:00:00 +05:30
ashilkn
4470e039eb [mob][photos] Add more logs for debugging 2024-06-11 16:48:44 +05:30
ashilkn
564222b3f0 [mob][photos] Remove delay added for testing 2024-06-11 16:43:02 +05:30
Manav Rathi
2e1c5d7684 [web] Make the accounts pages stateless (#2100)
This allows user to copy paste the URLs if their passkeys are in a
different browser than the one which got opened when we asked the system
to open the browser (from the desktop / mobile apps).
2024-06-11 16:42:19 +05:30
Manav Rathi
b5e3bf8d4b Lint fix 2024-06-11 16:38:52 +05:30
Manav Rathi
fbff908c90 Remove unused header setting 2024-06-11 16:36:27 +05:30
ashilkn
3cb9b12f26 [mob][photos] Log heartbeats on app init for debugging 2024-06-11 16:34:26 +05:30
Manav Rathi
c4d5bc5aa7 Add a note 2024-06-11 16:31:25 +05:30
Manav Rathi
237fc3cdb1 Dear React, 2024-06-11 16:10:58 +05:30
Manav Rathi
96386e8f9e Clean 2024-06-11 16:04:02 +05:30
Manav Rathi
8df19efc1a Trim 2024-06-11 15:57:17 +05:30
Manav Rathi
a0f7c6f302 Pass token 2024-06-11 15:55:18 +05:30
ashilkn
fdef3dc439 [mob][photos] Add logs for debugging 2024-06-11 15:45:00 +05:30
Manav Rathi
3285ccdb3a Directly 2024-06-11 15:39:40 +05:30
Manav Rathi
a27da1de31 Towards a stateless accounts 2024-06-11 15:26:56 +05:30
Ashil
d6885d66c3 [mob][photos] Mention OS with subject of logs sent when app is stuck on lockscreen for more than 15 seconds. This will let us identify OS when logs are not attached (#2077)
Tested if this breaks logs from getting sent. Good to go.
2024-06-11 15:23:38 +05:30
Manav Rathi
15b2b05487 [desktop] Fix passkey recovery redirect (#2097) 2024-06-11 15:21:59 +05:30
Manav Rathi
03c4d42a03 [auth] Add icons: BitSkins, DMarket, Marketplace.tf & Skinport (#2055) 2024-06-11 15:19:22 +05:30
Manav Rathi
621d58ec0e Pass recovery URL explicitly instead of trying various string mainps 2024-06-11 15:13:58 +05:30
Manav Rathi
e51f9f1e08 Allow /passkeys/recover redirect 2024-06-11 14:46:53 +05:30
Vishnu Mohandas
3517050c23 Increase grace period of Stripe subscriptions to 14 days (#2096)
SEPA in certain instances is taking 10+ days to go through.
2024-06-11 14:28:29 +05:30
vishnukvmd
4561c8f85c Increase grace period of Stripe subscriptions to 14 days 2024-06-11 14:09:57 +05:30
Manav Rathi
48d0e250c6 [desktop] Handle passkey redirect (#2095)
Tested on macOS
2024-06-11 13:06:13 +05:30
Manav Rathi
632224b94c Ignore query params in comparison 2024-06-11 12:58:52 +05:30
Manav Rathi
8ecb88cbb4 Don't reload the app, use the router 2024-06-11 12:53:39 +05:30
Manav Rathi
330600543e window.location.origin will be in the correct place 2024-06-11 12:28:32 +05:30
Manav Rathi
4a9fe006d5 Forward 2024-06-11 12:20:29 +05:30
Ashil
e50ae02dbb [mob][photos] Modify the code to use XFile.fromData(bytes) instead of saving the image to a file for share link placeholder (#2073)
1. Modified the` _createPlaceholder` function to return the image bytes
instead of the image path, changed the return type to
`Future<Uint8List?>`
2. Remove the call to `saveImage` on saving the image to a temporary
directory
3. Modified the `shareImageAndUrl` function:
4. Replaced the usage of XFile(imagePath) with
XFile.fromData(imageBytes).
5. Added metadata to the `XFile.fromData` method call, specifying the
name and mimeType for better file identification during sharing.
2024-06-11 12:04:57 +05:30
Neeraj Gupta
bc7075f81a [cli] Fix: Retry on all 5xx errors (#2094)
## Description

## Tests
2024-06-11 11:59:14 +05:30
Manav Rathi
f8d2fda602 iso 2024-06-11 11:58:15 +05:30
Neeraj Gupta
896d7402b4 [cli] Bump version 2024-06-11 11:58:01 +05:30
Neeraj Gupta
55a16d053a [cli] Inc wait time for retry 2024-06-11 11:57:37 +05:30
Neeraj Gupta
9a1254b745 [cli] Log selected headers on download failure 2024-06-11 11:57:22 +05:30
Manav Rathi
afe5809cb2 Take 1 2024-06-11 11:51:17 +05:30
Neeraj Gupta
d6c4d5f87f [cli] Fix: retry download on 500 2024-06-11 11:37:17 +05:30
Manav Rathi
9de5f01727 Add protocol 2024-06-11 11:33:48 +05:30
Manav Rathi
4569ae01df Outline 2024-06-11 10:58:04 +05:30
Manav Rathi
896001100c [desktop][docs] Remove outdated desktop/rc branch name (#2093) 2024-06-11 10:42:07 +05:30
Manav Rathi
332c8d9695 [desktop][docs] Remove outdated desktop/rc branch name 2024-06-11 10:41:28 +05:30
Ashil
6df8a2204f Upgrade to flutter 3.22.2 (#2076) 2024-06-11 10:38:08 +05:30
Manav Rathi
4a16fa8701 [photosd] Fix automatic move to uncategorized on watch folder deletions (#2092)
This was a regression introduced in 1.7.0. On deleting a file on disk,
the corresponding items are supposed to move to uncategorized.

> And if a file is deleted locally, then the corresponding Ente file
will also be automatically moved to uncategorized.
>
> https://help.ente.io/photos/features/watch-folders
2024-06-11 10:14:54 +05:30
Manav Rathi
92dc6cacfa Add a CHANGELOG entry 2024-06-11 10:09:09 +05:30
Manav Rathi
b40419bcea [photosd] Fix automatic move to uncategorized on watch folder deletions
This was a regression introduced in 1.7.0. On deleting a file on disk, the
corresponding items are supposed to move to uncategorized.

> And if a file is deleted locally, then the corresponding Ente file will also
> be automatically moved to uncategorized.
>
> https://help.ente.io/photos/features/watch-folders
2024-06-11 09:54:25 +05:30
Manav Rathi
f84b2b5ad3 Update SECURITY.md (#2091)
Format using prettier (same config as used by docs/web etc).
2024-06-11 08:52:34 +05:30
Manav Rathi
2da32c3193 Update SECURITY.md 2024-06-11 08:51:09 +05:30
Manav Rathi
3011248017 Update SECURITY.md (#2086)
I made these changes:
- Corrected grammar and punctuation errors.
- Formatted headings, links, and lists properly using Markdown.
- Simplified wording for clarity.
2024-06-11 08:49:05 +05:30
Manav Rathi
54be100830 [web] New translations (#2088)
New translations from
[Crowdin](https://crowdin.com/project/ente-photos-web)
2024-06-11 08:47:46 +05:30
Crowdin Bot
c37b6e0441 New Crowdin translations by GitHub Action 2024-06-11 02:09:20 +00:00
Crowdin Bot
c113e09204 New Crowdin translations by GitHub Action 2024-06-11 01:59:36 +00:00
Crowdin Bot
19f93087db New Crowdin translations by GitHub Action 2024-06-11 01:43:38 +00:00
Prateek Sunal
3f736e82ae fix(mobile): dispose dialog correctly 2024-06-11 02:24:12 +05:30
Prateek Sunal
4f6e97eafd fix(mobile): create dialog at start of exporting video 2024-06-11 02:21:06 +05:30
Prateek Sunal
8c75a2324c fix(mobile): update light mode ui 2024-06-11 02:14:38 +05:30
Sooraj Sathyanarayanan
91a4b1143f Update SECURITY.md
I made these changes:
- Corrected grammar and punctuation errors.
- Formatted headings, links, and lists properly using Markdown.
- Simplified wording for clarity.
2024-06-10 15:55:06 -04:00
Prateek Sunal
79b37f16f5 [Auth] Update windows icon (#2067)
## Description

## Tests
2024-06-10 22:35:25 +05:30
Manav Rathi
e45792ad09 Passkeys: mobile and server changes (#2082)
Tests
- [x] Create passkey on localhost using web app
- [x] Verify passkey on localhost using web app
- [x] Test running on the default configuration.

The third test is pending on the library update which makes the RPID
optional.
2024-06-10 21:33:48 +05:30
Manav Rathi
00769bdd7a Use 2 min timeout, no need to override on the client 2024-06-10 21:26:38 +05:30
Manav Rathi
89f58236fc Use the default of yarn dev:accounts 2024-06-10 20:48:38 +05:30
Manav Rathi
eca48a4cc3 [server] Update go [1.20 -> 1.21] & passkey dependencies (#2084)
## Description

## Tests
2024-06-10 20:25:48 +05:30
Neeraj Gupta
fe324c3124 Add rpi id and origin for localhost 2024-06-10 18:25:44 +05:30
Neeraj Gupta
c0ac43b6c8 Upgrade webauthn + go from 1.20 -> 1.21 2024-06-10 18:25:18 +05:30
Manav Rathi
af60ae46c1 Fix qp name 2024-06-10 16:52:00 +05:30
Manav Rathi
d47287095d Document webauthn keys 2024-06-10 16:44:15 +05:30
Manav Rathi
b9d4f9ff10 /passkeys/registration/begin GET => POST 2024-06-10 16:35:10 +05:30
Manav Rathi
fc826e8acb Pass the X-Client-Package explicitly for the endpoint which needs it 2024-06-10 16:33:29 +05:30
Manav Rathi
f6377b98cb Update mobile URLs 2024-06-10 16:18:42 +05:30
Aman Raj Singh Mourya
b8c6a67faa [mob][photos] remove null check from non-nullabe variables 2024-06-10 16:00:57 +05:30
Aman Raj Singh Mourya
e18c79c895 [mob][photos] removed unnecessary delay 2024-06-10 15:33:19 +05:30
ashilkn
f9c6151482 Mention OS with subject of logs sent when app is stuck on lockscreen for more than 15 seconds. This will let us identify OS when logs are not attached 2024-06-10 11:59:22 +05:30
ashilkn
fb28b4ca28 [mob][photos] Bump up version to 0.8.135 2024-06-10 11:33:02 +05:30
ashilkn
a10f278d44 [mob][photos] Upgrade to flutter v3.22.2 to potentially fix the blank screen issue when resuming app from BG 2024-06-10 11:29:08 +05:30
Aman Raj Singh Mourya
9c1ae27a21 [mob][photos] increased delay form 100ms to 200ms for widget to image 2024-06-10 11:05:47 +05:30
Prateek Sunal
37fa4ba7b6 fix(auth): update icon on windows 2024-06-09 22:47:05 +05:30
Aman Raj Singh Mourya
6bd307a2cd Optimize image upload by using XFile.fromData instead of saving to file 2024-06-08 14:09:00 +05:30
dunny1g
2b34cfc688 Optimized SVG icon for BitSkins 2024-06-08 02:24:41 +01:00
dunny1g
bb957685b3 Update custom-icons.json 2024-06-08 01:43:00 +01:00
dunny1g
445f8c4635 Add files via upload 2024-06-08 01:30:31 +01:00
dunny1g
f2bb1430fe Add files via upload 2024-06-08 00:35:14 +01:00
Prateek Sunal
eddb774b19 Merge remote-tracking branch 'origin' into mobile-videoeditor 2024-06-08 01:21:51 +05:30
ashilkn
fabd6351d9 [mob][photos] SectionType.content -> SectionType.magic 2024-06-07 17:28:13 +05:30
ashilkn
637f3522a9 [mob][photos] Polish magic section UI 2024-06-06 19:16:20 +05:30
ashilkn
5dda37a192 [mob][photos] Use correct naming + remove unnecessary field 2024-06-06 18:10:50 +05:30
ashilkn
6b3c9ee19c [mob][photos] Surface magic section results in UI, using moments section's widget 2024-06-06 17:34:48 +05:30
ashilkn
a3ebd4c062 [mob][photos] Make score threshold configurable 2024-06-06 11:32:33 +05:30
ashilkn
3d3588e64e Merge branch 'main' into rediscovery-3 2024-06-06 10:59:59 +05:30
Neeraj Gupta
017cb7eb96 [photos] Bump version to 0.8.133+653 2024-06-05 12:30:50 +05:30
Neeraj Gupta
bf36f415db Enable video editor for internal users 2024-06-05 12:30:11 +05:30
Neeraj Gupta
24ea4374cf Merge branch 'main' into mobile-videoeditor 2024-06-05 12:28:50 +05:30
ashilkn
33656c8206 [mob][photos] perf improvement when computing score on magic search 2024-06-01 13:12:29 +05:30
Prateek Sunal
5448ca116c fix(mobile): update video editor trimmer color 2024-05-30 22:40:48 +05:30
Prateek Sunal
bfa652df36 feat(mobile): add all pages for video editor 2024-05-30 22:38:05 +05:30
Prateek Sunal
fae54faffc fix(icons): update dev flavor icon 2024-05-26 17:29:04 +05:30
Prateek Sunal
d4f781bf35 fix(auth): update video editor 2024-05-20 20:57:44 +05:30
Prateek Sunal
9c4e72aa0f feat(mobile): init video editor 2024-05-17 01:32:13 +05:30
306 changed files with 5953 additions and 1279 deletions

View File

@@ -9,7 +9,7 @@ on:
- ".github/workflows/auth-lint.yml"
env:
FLUTTER_VERSION: "3.19.3"
FLUTTER_VERSION: "3.22.2"
jobs:
lint:

View File

@@ -29,7 +29,7 @@ on:
- "auth-v*"
env:
FLUTTER_VERSION: "3.19.3"
FLUTTER_VERSION: "3.22.2"
jobs:
build-ubuntu:

View File

@@ -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:

View File

@@ -10,7 +10,7 @@ on:
env:
FLUTTER_VERSION: "3.22.1"
FLUTTER_VERSION: "3.22.2"
jobs:
lint:

View File

@@ -9,7 +9,7 @@ on:
- "photos-v*"
env:
FLUTTER_VERSION: "3.22.1"
FLUTTER_VERSION: "3.22.2"
jobs:
build:

View File

@@ -33,7 +33,7 @@ jobs:
registry: ghcr.io
enableBuildKit: true
multiPlatform: true
platform: linux/amd64,linux/arm64,linux/arm/v7
platform: linux/amd64,linux/arm64
buildArgs: GIT_COMMIT=${{ inputs.commit }}
tags: ${{ inputs.commit }}, latest
username: ${{ github.actor }}

View File

@@ -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!

View File

@@ -6,7 +6,7 @@ FEATURES
- Secure Backups
Auth provides end-to-end encrypted cloud backups so that you don't have to worry
about losing your tokens. We use the same protocols ente Photos uses to encrypt
about losing your tokens. We use the same protocols Ente Photos uses to encrypt
and preserve your data.
- Multi Device Synchronization

View File

@@ -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>

View File

@@ -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",
@@ -58,6 +67,9 @@
{
"title": "Cloudflare"
},
{
"title": "CoinDCX"
},
{
"title": "ConfigCat"
},
@@ -83,6 +95,9 @@
{
"title": "Discourse"
},
{
"title": "DMarket"
},
{
"title": "Doppler"
},
@@ -154,6 +169,10 @@
{
"title": "INWX"
},
{
"title": "Itch.io",
"slug": "itch_io"
},
{
"title": "IVPN",
"slug": "IVPN"
@@ -202,6 +221,10 @@
"slug": "local_wp",
"altNames": ["LocalWP", "Local WP", "Local Wordpress"]
},
{
"title": "Marketplace.tf",
"slug": "marketplacedottf"
},
{
"title": "Mastodon",
"altNames": ["mstdn", "fediscience", "mathstodon", "fosstodon"],
@@ -216,6 +239,9 @@
{
"title": "Microsoft"
},
{
"title": "Migros"
},
{
"title": "Mintos"
},
@@ -231,6 +257,10 @@
"title": "MyFRITZ!Net",
"slug": "myfritz"
},
{
"title": "Name.com",
"slug": "name_com"
},
{
"title": "NextDNS"
},
@@ -341,6 +371,9 @@
"title": "Skiff",
"hex": "EF5A3C"
},
{
"title": "Skinport"
},
{
"title": "Snapchat"
},
@@ -397,6 +430,10 @@
"title": "Ubisoft",
"hex": "4285f4"
},
{
"title": "Ubuntu One",
"slug": "ubuntu_one"
},
{
"title": "Unity",
"hex": "858585"
@@ -423,9 +460,7 @@
{
"title": "WorkOS",
"slug": "workos",
"altNames": [
"Work OS"
]
"altNames": ["Work OS"]
},
{
"title": "X",

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 19 KiB

View 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

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 9.8 KiB

View File

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 500 500">
<path fill="#182954" d="m75.705 269.386 12.606 10.812a40.902 40.902 0 0 1-8.642 8.853 53.365 53.365 0 0 1-13.599 7.73 45.769 45.769 0 0 1-16.998 3.094 49.02 49.02 0 0 1-25.212-6.466A45.84 45.84 0 0 1 6.72 275.84a50.83 50.83 0 0 1-6.212-25.287 52.621 52.621 0 0 1 3.525-19.394 49.28 49.28 0 0 1 10.2-16.022 46.603 46.603 0 0 1 15.44-10.812 49.626 49.626 0 0 1 19.969-3.938 45.9 45.9 0 0 1 23.51 5.48A49.016 49.016 0 0 1 88.308 219.5l-12.744 11.244A39.368 39.368 0 0 0 64.938 220.2a27.358 27.358 0 0 0-15.296-3.933 27.636 27.636 0 0 0-16.147 4.632 30.695 30.695 0 0 0-10.478 12.508 38.957 38.957 0 0 0-3.688 16.879 36.724 36.724 0 0 0 3.684 16.442 29.719 29.719 0 0 0 10.184 11.793 27.208 27.208 0 0 0 15.44 4.358c4.608.197 9.203-.62 13.456-2.391a27.765 27.765 0 0 0 8.214-5.622l5.381-5.481M93.275 264.047a35.477 35.477 0 0 1 4.535-17.71 34.84 34.84 0 0 1 12.748-12.929 39.497 39.497 0 0 1 18.838-4.778 39.497 39.497 0 0 1 18.838 4.778 34.846 34.846 0 0 1 12.749 12.928 36.889 36.889 0 0 1 4.532 17.709 36.891 36.891 0 0 1-4.532 17.708 36.519 36.519 0 0 1-13.365 13.153 36.875 36.875 0 0 1-18.181 4.837 36.88 36.88 0 0 1-18.203-4.756 36.513 36.513 0 0 1-13.424-13.092 35.479 35.479 0 0 1-4.535-17.707v-.141zm35.979 21.224a16.949 16.949 0 0 0 10.623-3.23c2.804-2.121 5-4.93 6.375-8.151a24.848 24.848 0 0 0 2.124-9.698 24.293 24.293 0 0 0-2.124-9.697 20.265 20.265 0 0 0-6.375-8.15 19.056 19.056 0 0 0-10.623-3.233 19.057 19.057 0 0 0-10.625 3.233 20.118 20.118 0 0 0-6.231 8.009 24.296 24.296 0 0 0-2.125 9.697 24.713 24.713 0 0 0 2.125 9.839 19.985 19.985 0 0 0 6.374 8.15 16.949 16.949 0 0 0 10.624 3.231M168.905 202.628h16.856v17.71h-16.856v-17.71zm0 28.11h16.856v66.758h-16.856v-66.758zM192.416 297.495V230.88h16.147l.42 7.589a35.937 35.937 0 0 1 7.505-5.905 23.656 23.656 0 0 1 12.749-3.094 24.38 24.38 0 0 1 10.396 1.612 24.22 24.22 0 0 1 8.726 5.836 29.047 29.047 0 0 1 6.66 20.097v40.477H238.02v-40.335a13.257 13.257 0 0 0-.76-5.278 13.337 13.337 0 0 0-2.78-4.561 12.19 12.19 0 0 0-4.164-2.694 12.27 12.27 0 0 0-4.902-.82 14.974 14.974 0 0 0-6.377 1.24 14.87 14.87 0 0 0-5.236 3.82 18.046 18.046 0 0 0-4.534 12.51v36.118l-16.851.004z"/>
<path fill="#FA4A29" d="m463.25 246.618 29.754-44.007h-28.187l-15.44 24.596-15.883-24.596h-31.163l1.416 1.967-.993-.416a63.329 63.329 0 0 0-23.083-4.046 50.453 50.453 0 0 0-25.92 6.607 46.609 46.609 0 0 0-14.308 12.929 40.334 40.334 0 0 0-15.582-11.806 65.028 65.028 0 0 0-26.344-5.077h-36.686v94.727h36.544a64.026 64.026 0 0 0 26.344-5.202A41.612 41.612 0 0 0 339.3 280.63c3.87 5.299 8.846 9.709 14.59 12.928a51.44 51.44 0 0 0 25.777 6.325 55.023 55.023 0 0 0 24.646-5.34l-1.982 2.953h27.76l18.558-29.108 19.122 29.108h31.73l-36.252-50.878zm-147.452 21.624a25.772 25.772 0 0 1-8.902 5.504 25.916 25.916 0 0 1-10.376 1.523h-10.334v-50.573h10.338c3.62-.305 7.264.165 10.685 1.378a25.427 25.427 0 0 1 9.147 5.65 26.146 26.146 0 0 1 6.374 18.271 24.821 24.821 0 0 1-1.597 9.836 24.965 24.965 0 0 1-5.343 8.436l.008-.025zm101.549 6.911-12.04-11.228a38.572 38.572 0 0 1-10.197 9.149 27.09 27.09 0 0 1-13.6 2.952 25.509 25.509 0 0 1-13.314-3.372 22.838 22.838 0 0 1-8.8-9.415 29.459 29.459 0 0 1-3.118-13.63c-.091-4.623.929-9.2 2.975-13.353a23.258 23.258 0 0 1 8.642-9.415 25.653 25.653 0 0 1 13.738-3.513 24.798 24.798 0 0 1 12.748 3.23 32.061 32.061 0 0 1 9.639 8.733l12.606-12.508 18.415 26.28-17.694 26.09z"/>
</svg>

After

Width:  |  Height:  |  Size: 3.4 KiB

View 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

View 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

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 22 KiB

View 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

View 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

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 34 KiB

View 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

View File

@@ -6,7 +6,7 @@ FEATURES
- Secure Backups
ente provides end-to-end encrypted cloud backups so that you don't have to worry
about losing your tokens. We use the same protocols ente Photos uses to encrypt
about losing your tokens. We use the same protocols Ente Photos uses to encrypt
and preserve your data.
- Multi Device Synchronization

View File

@@ -42,3 +42,7 @@ class InvalidStateError extends AssertionError {
class SrpSetupNotCompleteError extends Error {}
class AuthenticatorKeyNotFound extends Error {}
class PassKeySessionNotVerifiedError extends Error {}
class PassKeySessionExpiredError extends Error {}

View File

@@ -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",

View File

@@ -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"
}

View File

@@ -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",

View File

@@ -0,0 +1 @@
{}

View File

@@ -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()

View File

@@ -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,

View File

@@ -266,32 +266,77 @@ 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();
await _saveConfiguration(response);
if (userPassword == null) {
await dialog.hide();
// ignore: unawaited_futures
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(
builder: (BuildContext context) {
return const PasswordReentryPage();
},
),
(route) => route.isFirst,
);
} else {
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(
@@ -316,9 +361,12 @@ class UserService {
await dialog.hide();
if (response.statusCode == 200) {
Widget page;
final String passkeySessionID = response.data["passkeySessionID"];
final String twoFASessionID = response.data["twoFactorSessionID"];
if (twoFASessionID.isNotEmpty) {
page = TwoFactorAuthenticationPage(twoFASessionID);
} else if (passkeySessionID.isNotEmpty) {
page = PasskeyPage(passkeySessionID);
} else {
await _saveConfiguration(response);
if (Configuration.instance.getEncryptedToken() != null) {

View File

@@ -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 {

View File

@@ -33,7 +33,7 @@ enum ButtonType {
Color defaultButtonColor(EnteColorScheme colorScheme) {
if (isPrimary) {
return colorScheme.primary500;
return colorScheme.primary400;
}
if (isSecondary) {
return colorScheme.fillFaint;

View File

@@ -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,

View File

@@ -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,

View File

@@ -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'];

View File

@@ -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(

View File

@@ -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")

View File

@@ -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;
}

View File

@@ -27,3 +27,6 @@ include:
- libffi.so.8
- libtiff.so.5
- libjpeg.so.8
supported_mime_type:
- x-scheme-handler/enteauth

View File

@@ -31,4 +31,4 @@ categories:
startup_notify: false
supported_mime_type:
- x-scheme-handler/ente
- x-scheme-handler/enteauth

View File

@@ -28,4 +28,4 @@ categories:
startup_notify: false
supported_mime_type:
- x-scheme-handler/ente
- x-scheme-handler/enteauth

View File

@@ -38,6 +38,7 @@
<key>CFBundleURLSchemes</key>
<array>
<string>otpauth</string>
<string>enteauth</string>
</array>
</dict>
</array>

View File

@@ -45,10 +45,10 @@ packages:
dependency: "direct main"
description:
name: archive
sha256: "0763b45fa9294197a2885c8567927e2830ade852e5c896fd4ab7e0e348d0f373"
sha256: cb6a278ef2dbb298455e1a713bda08524a175630ec643a242c399c932a0a1f7d
url: "https://pub.dev"
source: hosted
version: "3.5.0"
version: "3.6.1"
args:
dependency: transitive
description:
@@ -117,10 +117,10 @@ packages:
dependency: transitive
description:
name: build_daemon
sha256: "0343061a33da9c5810b2d6cee51945127d8f4c060b7fbdd9d54917f0a3feaaa1"
sha256: "79b2aef6ac2ed00046867ed354c88778c9c0f029df8a20fe10b5436826721ef9"
url: "https://pub.dev"
source: hosted
version: "4.0.1"
version: "4.0.2"
build_resolvers:
dependency: transitive
description:
@@ -133,18 +133,18 @@ packages:
dependency: "direct dev"
description:
name: build_runner
sha256: "3ac61a79bfb6f6cc11f693591063a7f19a7af628dc52f141743edac5c16e8c22"
sha256: "644dc98a0f179b872f612d3eb627924b578897c629788e858157fa5e704ca0c7"
url: "https://pub.dev"
source: hosted
version: "2.4.9"
version: "2.4.11"
build_runner_core:
dependency: transitive
description:
name: build_runner_core
sha256: "4ae8ffe5ac758da294ecf1802f2aff01558d8b1b00616aa7538ea9a8a5d50799"
sha256: e3c79f69a64bdfcd8a776a3c28db4eb6e3fb5356d013ae5eb2e52007706d5dbe
url: "https://pub.dev"
source: hosted
version: "7.3.0"
version: "7.3.1"
built_collection:
dependency: transitive
description:
@@ -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:
@@ -415,10 +415,10 @@ packages:
dependency: "direct main"
description:
name: file_saver
sha256: bdebc720e17b3e01aba59da69b6d47020a7e5ba7d5c75bd9194f9618d5f16ef4
sha256: d375b351e3331663abbaf99747abd72f159260c58fbbdbca9f926f02c01bdc48
url: "https://pub.dev"
source: hosted
version: "0.2.12"
version: "0.2.13"
fixnum:
dependency: "direct main"
description:
@@ -444,10 +444,10 @@ packages:
dependency: "direct main"
description:
name: flutter_bloc
sha256: f0ecf6e6eb955193ca60af2d5ca39565a86b8a142452c5b24d96fb477428f4d2
sha256: b594505eac31a0518bdcb4b5b79573b8d9117b193cc80cc12e17d639b10aa27a
url: "https://pub.dev"
source: hosted
version: "8.1.5"
version: "8.1.6"
flutter_context_menu:
dependency: "direct main"
description:
@@ -586,59 +586,59 @@ packages:
dependency: transitive
description:
name: flutter_plugin_android_lifecycle
sha256: "8cf40eebf5dec866a6d1956ad7b4f7016e6c0cc69847ab946833b7d43743809f"
sha256: c6b0b4c05c458e1c01ad9bcc14041dd7b1f6783d487be4386f793f47a8a4d03e
url: "https://pub.dev"
source: hosted
version: "2.0.19"
version: "2.0.20"
flutter_secure_storage:
dependency: "direct main"
description:
name: flutter_secure_storage
sha256: ffdbb60130e4665d2af814a0267c481bcf522c41ae2e43caf69fa0146876d685
sha256: "165164745e6afb5c0e3e3fcc72a012fb9e58496fb26ffb92cf22e16a821e85d0"
url: "https://pub.dev"
source: hosted
version: "9.0.0"
version: "9.2.2"
flutter_secure_storage_linux:
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:
name: flutter_secure_storage_macos
sha256: bd33935b4b628abd0b86c8ca20655c5b36275c3a3f5194769a7b3f37c905369c
sha256: "1693ab11121a5f925bbea0be725abfcfbbcf36c1e29e571f84a0c0f436147a81"
url: "https://pub.dev"
source: hosted
version: "3.0.1"
version: "3.1.2"
flutter_secure_storage_platform_interface:
dependency: transitive
description:
name: flutter_secure_storage_platform_interface
sha256: "0d4d3a5dd4db28c96ae414d7ba3b8422fd735a8255642774803b2532c9a61d7e"
sha256: cf91ad32ce5adef6fba4d736a542baca9daf3beac4db2d04be350b87f69ac4a8
url: "https://pub.dev"
source: hosted
version: "1.0.2"
version: "1.1.2"
flutter_secure_storage_web:
dependency: transitive
description:
name: flutter_secure_storage_web
sha256: "30f84f102df9dcdaa2241866a958c2ec976902ebdaa8883fbfe525f1f2f3cf20"
sha256: f4ebff989b4f07b2656fb16b47852c0aab9fed9b4ec1c70103368337bc1886a9
url: "https://pub.dev"
source: hosted
version: "1.1.2"
version: "1.2.1"
flutter_secure_storage_windows:
dependency: transitive
description:
name: flutter_secure_storage_windows
sha256: "5809c66f9dd3b4b93b0a6e2e8561539405322ee767ac2f64d084e2ab5429d108"
sha256: b20b07cb5ed4ed74fc567b78a72936203f587eba460af1df11281c9326cd3709
url: "https://pub.dev"
source: hosted
version: "3.0.0"
version: "3.1.2"
flutter_slidable:
dependency: "direct main"
description:
@@ -685,10 +685,10 @@ packages:
dependency: "direct main"
description:
name: fluttertoast
sha256: "81b68579e23fcbcada2db3d50302813d2371664afe6165bc78148050ab94bf66"
sha256: "7eae679e596a44fdf761853a706f74979f8dd3cd92cf4e23cae161fda091b847"
url: "https://pub.dev"
source: hosted
version: "8.2.5"
version: "8.2.6"
freezed_annotation:
dependency: transitive
description:
@@ -725,10 +725,10 @@ packages:
dependency: "direct main"
description:
name: gradient_borders
sha256: "69eeaff519d145a4c6c213ada1abae386bcc8981a4970d923e478ce7ba19e309"
sha256: b1cd969552c83f458ff755aa68e13a0327d09f06c3f42f471b423b01427f21f8
url: "https://pub.dev"
source: hosted
version: "1.0.0"
version: "1.0.1"
graphs:
dependency: transitive
description:
@@ -757,10 +757,10 @@ packages:
dependency: transitive
description:
name: hashlib_codecs
sha256: "49e2a471f74b15f1854263e58c2ac11f2b631b5b12c836f9708a35397d36d626"
sha256: a1c7b5d89ff29e81fd8e8c0b35966db4c935e149fc4ebe1ebf71e358c15863ab
url: "https://pub.dev"
source: hosted
version: "2.2.0"
version: "2.4.0"
hex:
dependency: transitive
description:
@@ -805,18 +805,18 @@ packages:
dependency: transitive
description:
name: image
sha256: "4c68bfd5ae83e700b5204c1e74451e7bf3cf750e6843c6e158289cf56bda018e"
sha256: "2237616a36c0d69aef7549ab439b833fb7f9fb9fc861af2cc9ac3eedddd69ca8"
url: "https://pub.dev"
source: hosted
version: "4.1.7"
version: "4.2.0"
intl:
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:
@@ -893,18 +893,18 @@ packages:
dependency: "direct main"
description:
name: local_auth_android
sha256: e0e5b1ea247c5a0951c13a7ee13dc1beae69750e6a2e1910d1ed6a3cd4d56943
sha256: "48dfb2d954da8ef6a77adfc93a29998f7729e9308eaa817e91dea4500317b2c8"
url: "https://pub.dev"
source: hosted
version: "1.0.38"
version: "1.0.39"
local_auth_darwin:
dependency: "direct main"
description:
name: local_auth_darwin
sha256: "33381a15b0de2279523eca694089393bb146baebdce72a404555d03174ebc1e9"
sha256: e424ebf90d5233452be146d4a7da4bcd7a70278b67791592f3fde1bda8eef9e2
url: "https://pub.dev"
source: hosted
version: "1.2.2"
version: "1.3.1"
local_auth_platform_interface:
dependency: transitive
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:
@@ -973,10 +973,10 @@ packages:
dependency: "direct dev"
description:
name: mocktail
sha256: c4b5007d91ca4f67256e720cb1b6d704e79a510183a12fa551021f652577dce6
sha256: "890df3f9688106f25755f26b1c60589a92b3ab91a22b8b224947ad041bf172d8"
url: "https://pub.dev"
source: hosted
version: "1.0.3"
version: "1.0.4"
modal_bottom_sheet:
dependency: "direct main"
description:
@@ -1085,18 +1085,18 @@ packages:
dependency: transitive
description:
name: path_provider_android
sha256: a248d8146ee5983446bf03ed5ea8f6533129a12b11f12057ad1b4a67a2b3b41d
sha256: "9c96da072b421e98183f9ea7464898428e764bc0ce5567f27ec8693442e72514"
url: "https://pub.dev"
source: hosted
version: "2.2.4"
version: "2.2.5"
path_provider_foundation:
dependency: transitive
description:
name: path_provider_foundation
sha256: "5a7999be66e000916500be4f15a3633ebceb8302719b47b9cc49ce924125350f"
sha256: f234384a3fdd67f989b4d54a5d73ca2a6c422fa55ae694381ae0f4375cd1ea16
url: "https://pub.dev"
source: hosted
version: "2.3.2"
version: "2.4.0"
path_provider_linux:
dependency: transitive
description:
@@ -1141,10 +1141,10 @@ packages:
dependency: transitive
description:
name: platform
sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec"
sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65"
url: "https://pub.dev"
source: hosted
version: "3.1.4"
version: "3.1.5"
plugin_platform_interface:
dependency: transitive
description:
@@ -1157,10 +1157,10 @@ packages:
dependency: "direct main"
description:
name: pointycastle
sha256: "79fbafed02cfdbe85ef3fd06c7f4bc2cbcba0177e61b765264853d4253b21744"
sha256: "4be0097fcf3fd3e8449e53730c631200ebc7b88016acecab2b0da2f0149222fe"
url: "https://pub.dev"
source: hosted
version: "3.9.0"
version: "3.9.1"
pool:
dependency: transitive
description:
@@ -1205,10 +1205,10 @@ packages:
dependency: transitive
description:
name: pubspec_parse
sha256: c63b2876e58e194e4b0828fcb080ad0e06d051cb607a6be51a9e084f47cb9367
sha256: c799b721d79eb6ee6fa56f00c04b472dcd44a30d258fac2174a6ec57302678f8
url: "https://pub.dev"
source: hosted
version: "1.2.3"
version: "1.3.0"
qr:
dependency: transitive
description:
@@ -1245,18 +1245,18 @@ packages:
dependency: "direct main"
description:
name: sentry
sha256: e572d33a3ff1d69549f33ee828a8ff514047d43ca8eea4ab093d72461205aa3e
sha256: "57514bc72d441ffdc463f498d6886aa586a2494fa467a1eb9d649c28010d7ee3"
url: "https://pub.dev"
source: hosted
version: "7.20.1"
version: "7.20.2"
sentry_flutter:
dependency: "direct main"
description:
name: sentry_flutter
sha256: ac8cf6bb849f3560353ae33672e17b2713809a4e8de0d3cf372e9e9c42013757
sha256: "9723d58470ca43a360681ddd26abb71ca7b815f706bc8d3747afd054cf639ded"
url: "https://pub.dev"
source: hosted
version: "7.20.1"
version: "7.20.2"
share_plus:
dependency: "direct main"
description:
@@ -1285,18 +1285,18 @@ packages:
dependency: transitive
description:
name: shared_preferences_android
sha256: "1ee8bf911094a1b592de7ab29add6f826a7331fb854273d55918693d5364a1f2"
sha256: "93d0ec9dd902d85f326068e6a899487d1f65ffcd5798721a95330b26c8131577"
url: "https://pub.dev"
source: hosted
version: "2.2.2"
version: "2.2.3"
shared_preferences_foundation:
dependency: transitive
description:
name: shared_preferences_foundation
sha256: "7708d83064f38060c7b39db12aefe449cb8cdc031d6062280087bc4cdb988f5c"
sha256: "0a8a893bf4fd1152f93fec03a415d11c27c74454d96e2318a7ac38dd18683ab7"
url: "https://pub.dev"
source: hosted
version: "2.3.5"
version: "2.4.0"
shared_preferences_linux:
dependency: transitive
description:
@@ -1341,10 +1341,10 @@ packages:
dependency: transitive
description:
name: shelf_web_socket
sha256: "9ca081be41c60190ebcb4766b2486a7d50261db7bd0f5d9615f2d653637a84c1"
sha256: "073c147238594ecd0d193f3456a5fe91c4b0abbcc68bf5cd95b36c4e194ac611"
url: "https://pub.dev"
source: hosted
version: "1.0.4"
version: "2.0.0"
shortid:
dependency: transitive
description:
@@ -1370,10 +1370,10 @@ packages:
dependency: transitive
description:
name: sodium_libs
sha256: f7f6719b7ab3e8512ce7a5ecd7bc8d865482431cdd5a07a46b55b13c152b54e1
sha256: "441444f6f433032bae3444c2ef5ed2cf5bc0def77f104abdff20aedcf79a7c7a"
url: "https://pub.dev"
source: hosted
version: "2.2.1+1"
version: "2.2.1+5"
source_gen:
dependency: transitive
description:
@@ -1411,10 +1411,10 @@ packages:
description:
path: sqflite
ref: HEAD
resolved-ref: f281785e12e8b1abf2f9d41a587fc83d810724cf
resolved-ref: "3309d399dd7d695bbfa7c05f643bb16765cef4ee"
url: "https://github.com/tekartik/sqflite"
source: git
version: "2.3.3"
version: "2.3.3+1"
sqflite_common:
dependency: transitive
description:
@@ -1435,18 +1435,18 @@ packages:
dependency: "direct main"
description:
name: sqlite3
sha256: "1abbeb84bf2b1a10e5e1138c913123c8aa9d83cd64e5f9a0dd847b3c83063202"
sha256: b384f598b813b347c5a7e5ffad82cbaff1bec3d1561af267041e66f6f0899295
url: "https://pub.dev"
source: hosted
version: "2.4.2"
version: "2.4.3"
sqlite3_flutter_libs:
dependency: "direct main"
description:
name: sqlite3_flutter_libs
sha256: fb2a106a2ea6042fe57de2c47074cc31539a941819c91e105b864744605da3f5
sha256: "9f89a7e7dc36eac2035808427eba1c3fbd79e59c3a22093d8dace6d36b1fe89e"
url: "https://pub.dev"
source: hosted
version: "0.5.21"
version: "0.5.23"
stack_trace:
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:
@@ -1547,10 +1547,10 @@ packages:
dependency: "direct main"
description:
name: tray_manager
sha256: e0ac9a88b2700f366b8629b97e8663b6ef450a2f169560a685dc167bfe9c9c29
sha256: c9a63fd88bd3546287a7eb8ccc978d707eef82c775397af17dda3a4f4c039e64
url: "https://pub.dev"
source: hosted
version: "0.2.2"
version: "0.2.3"
tuple:
dependency: "direct main"
description:
@@ -1579,26 +1579,26 @@ packages:
dependency: "direct main"
description:
name: url_launcher
sha256: "6ce1e04375be4eed30548f10a315826fd933c1e493206eab82eed01f438c8d2e"
sha256: "21b704ce5fa560ea9f3b525b43601c678728ba46725bab9b01187b4831377ed3"
url: "https://pub.dev"
source: hosted
version: "6.2.6"
version: "6.3.0"
url_launcher_android:
dependency: transitive
description:
name: url_launcher_android
sha256: "360a6ed2027f18b73c8d98e159dda67a61b7f2e0f6ec26e86c3ada33b0621775"
sha256: ceb2625f0c24ade6ef6778d1de0b2e44f2db71fded235eb52295247feba8c5cf
url: "https://pub.dev"
source: hosted
version: "6.3.1"
version: "6.3.3"
url_launcher_ios:
dependency: transitive
description:
name: url_launcher_ios
sha256: "9149d493b075ed740901f3ee844a38a00b33116c7c5c10d7fb27df8987fb51d5"
sha256: "7068716403343f6ba4969b4173cbf3b84fc768042124bc2c011e5d782b24fe89"
url: "https://pub.dev"
source: hosted
version: "6.2.5"
version: "6.3.0"
url_launcher_linux:
dependency: transitive
description:
@@ -1611,10 +1611,10 @@ packages:
dependency: transitive
description:
name: url_launcher_macos
sha256: b7244901ea3cf489c5335bdacda07264a6e960b1c1b1a9f91e4bc371d9e68234
sha256: "9a1a42d5d2d95400c795b2914c36fdcb525870c752569438e4ebb09a2b5d90de"
url: "https://pub.dev"
source: hosted
version: "3.1.0"
version: "3.2.0"
url_launcher_platform_interface:
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:
@@ -1703,22 +1703,30 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.5.1"
web_socket:
dependency: transitive
description:
name: web_socket
sha256: "24301d8c293ce6fe327ffe6f59d8fd8834735f0ec36e4fd383ec7ff8a64aa078"
url: "https://pub.dev"
source: hosted
version: "0.1.5"
web_socket_channel:
dependency: transitive
description:
name: web_socket_channel
sha256: "58c6666b342a38816b2e7e50ed0f1e261959630becd4c879c4f26bfa14aa5a42"
sha256: a2d56211ee4d35d9b344d9d4ce60f362e4f5d1aafb988302906bd732bc731276
url: "https://pub.dev"
source: hosted
version: "2.4.5"
version: "3.0.0"
win32:
dependency: "direct main"
description:
name: win32
sha256: "0eaf06e3446824099858367950a813472af675116bf63f008a4c2a75ae13e9cb"
sha256: a79dbe579cb51ecd6d30b17e0cae4e0ea15e2c0e66f69ad4198f22a6789e94f4
url: "https://pub.dev"
source: hosted
version: "5.5.0"
version: "5.5.1"
win32_registry:
dependency: transitive
description:
@@ -1731,10 +1739,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:
@@ -1768,5 +1776,5 @@ packages:
source: hosted
version: "3.1.2"
sdks:
dart: ">=3.3.0 <4.0.0"
flutter: ">=3.19.0"
dart: ">=3.4.0 <4.0.0"
flutter: ">=3.22.0"

View File

@@ -1,6 +1,6 @@
name: ente_auth
description: ente two-factor authenticator
version: 3.0.8+308
version: 3.0.12+312
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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 133 KiB

View File

@@ -5,6 +5,8 @@
endpoint:
api: "http://localhost:8080"
# Endpoint for the account service for passkey
accounts: "http://localhost:3001"
log:
http: false # log status code & time taken by requests

View File

@@ -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
}),

View File

@@ -161,3 +161,22 @@ func (c *Client) VerifyTotp(
}
return &res, nil
}
func (c *Client) CheckPasskeyStatus(ctx context.Context,
sessionID string) (*AuthorizationResponse, error) {
var res AuthorizationResponse
r, err := c.restClient.R().
SetContext(ctx).
SetResult(&res).
Get("/users/two-factor/passkeys/get-token?sessionID=" + sessionID)
if err != nil {
return nil, err
}
if r.IsError() {
return nil, &ApiError{
StatusCode: r.StatusCode(),
Message: r.String(),
}
}
return &res, nil
}

View File

@@ -37,6 +37,7 @@ type AuthorizationResponse struct {
EncryptedToken string `json:"encryptedToken,omitempty"`
Token string `json:"token,omitempty"`
TwoFactorSessionID string `json:"twoFactorSessionID"`
PassKeySessionID string `json:"passkeySessionID"`
// SrpM2 is sent only if the user is logging via SRP
// SrpM2 is the SRP M2 value aka the proof that the server has the verifier
SrpM2 *string `json:"srpM2,omitempty"`
@@ -45,3 +46,7 @@ type AuthorizationResponse struct {
func (a *AuthorizationResponse) IsMFARequired() bool {
return a.TwoFactorSessionID != ""
}
func (a *AuthorizationResponse) IsPasskeyRequired() bool {
return a.PassKeySessionID != ""
}

View File

@@ -38,6 +38,17 @@ func GetUserInput(label string) (string, error) {
return input, nil
}
func WaitForEnter(prompt string) error {
fmt.Println(prompt)
// Create a new reader from standard input.
reader := bufio.NewReader(os.Stdin)
_, err := reader.ReadString('\n')
if err != nil {
return err
}
return nil
}
func GetAppType() api.App {
for {
app, err := GetUserInput("Enter app type (default: photos)")

View File

@@ -15,7 +15,7 @@ import (
"strings"
)
var AppVersion = "0.1.14"
var AppVersion = "0.1.16"
func main() {
cliDBPath, err := GetCLIConfigPath()
@@ -75,6 +75,10 @@ func main() {
}
return
}
if len(os.Args) == 1 {
// If no arguments are passed, show help
os.Args = append(os.Args, "help")
}
cmd.Execute(&ctrl, AppVersion)
}
@@ -85,6 +89,7 @@ func initConfig(cliConfigPath string) {
viper.AddConfigPath(".") // optionally look for config in the working directory
viper.SetDefault("endpoint.api", constants.EnteApiUrl)
viper.SetDefault("endpoint.accounts", constants.EnteAccountUrl)
viper.SetDefault("log.http", false)
if err := viper.ReadInConfig(); err != nil {
if _, ok := err.(viper.ConfigFileNotFoundError); ok {

View File

@@ -58,6 +58,10 @@ func (c *ClICtrl) AddAccount(cxt context.Context) {
if authResponse.IsMFARequired() {
authResponse, flowErr = c.validateTOTP(cxt, authResponse)
}
if authResponse.IsPasskeyRequired() {
authResponse, flowErr = c.verifyPassKey(cxt, authResponse)
}
if authResponse.EncryptedToken == "" || authResponse.KeyAttributes == nil {
log.Fatalf("missing key attributes or token.\nNote: Please use the mobile,web or desktop app to create a new account.\nIf you are trying to login to an existing account, report a bug.")
}

View File

@@ -7,7 +7,9 @@ import (
"github.com/ente-io/cli/internal/api"
eCrypto "github.com/ente-io/cli/internal/crypto"
"github.com/ente-io/cli/pkg/model"
"github.com/ente-io/cli/utils/browser"
"github.com/ente-io/cli/utils/encoding"
"github.com/spf13/viper"
"log"
"github.com/kong/go-srp"
@@ -139,6 +141,31 @@ func (c *ClICtrl) validateTOTP(ctx context.Context, authResp *api.AuthorizationR
}
}
func (c *ClICtrl) verifyPassKey(ctx context.Context, authResp *api.AuthorizationResponse) (*api.AuthorizationResponse, error) {
if !authResp.IsPasskeyRequired() {
return authResp, nil
}
baseAccountUrl := viper.GetString("endpoint.accounts")
passkeyAuthUrl := fmt.Sprintf("%s/passkeys/verify?passkeySessionID=%s&redirect=ente-cli://passkey&clientPackage=io.ente.photos", baseAccountUrl, authResp.PassKeySessionID)
fmt.Printf("Open this url in browser to verify passkey: %s\n", passkeyAuthUrl)
err := browser.OpenURL(passkeyAuthUrl)
if err != nil {
fmt.Printf("Failed to open browser: %v\n", err)
}
for {
err = internal.WaitForEnter("Press enter once you have completed the passkey verification")
if err != nil {
return nil, err
}
totpResp, err := c.Client.CheckPasskeyStatus(ctx, authResp.PassKeySessionID)
if err != nil {
log.Printf("failed to verify %v", err)
continue
}
return totpResp, nil
}
}
func (c *ClICtrl) validateEmail(ctx context.Context, email string) (*api.AuthorizationResponse, error) {
err := c.Client.SendEmailOTP(ctx, email)
if err != nil {

View File

@@ -0,0 +1,48 @@
package browser
import (
"os/exec"
"runtime"
"strings"
)
// https://stackoverflow.com/questions/39320371/how-start-web-server-to-open-page-in-browser-in-golang
// openURL opens the specified URL in the default browser of the user.
func OpenURL(url string) error {
var cmd string
var args []string
switch runtime.GOOS {
case "windows":
cmd = "cmd"
args = []string{"/c", "start"}
case "darwin":
cmd = "open"
args = []string{url}
default: // "linux", "freebsd", "openbsd", "netbsd"
// Check if running under WSL
if isWSL() {
// Use 'cmd.exe /c start' to open the URL in the default Windows browser
cmd = "cmd.exe"
args = []string{"/c", "start", url}
} else {
// Use xdg-open on native Linux environments
cmd = "xdg-open"
args = []string{url}
}
}
if len(args) > 1 {
// args[0] is used for 'start' command argument, to prevent issues with URLs starting with a quote
args = append(args[:1], append([]string{""}, args[1:]...)...)
}
return exec.Command(cmd, args...).Start()
}
// isWSL checks if the Go program is running inside Windows Subsystem for Linux
func isWSL() bool {
releaseData, err := exec.Command("uname", "-r").Output()
if err != nil {
return false
}
return strings.Contains(strings.ToLower(string(releaseData)), "microsoft")
}

View File

@@ -1,4 +1,6 @@
package constants
const CliDataPath = "/cli-data/"
const EnteApiUrl = "https://api.ente.io"
const EnteAccountUrl = "https://account.ente.io"

View File

@@ -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.
@@ -17,9 +17,10 @@ on:
#
- cron: "45 2 * * 1-6"
push:
# Run when a tag matching the pattern "v*"" is pushed.
# Run when a tag matching the pattern "vd.d.d"" is pushed. Crucially for
# us, this excludes the "-rc" tags.
tags:
- "v*"
- "v[0-9]+.[0-9]+.[0-9]+"
jobs:
release:

View File

@@ -1,9 +1,17 @@
# CHANGELOG
## v1.7.1 (Unreleased)
## v1.7.2 (Unreleased)
- .
## v1.7.1
- Support for passkeys as a second factor authentication mechanism.
- Remember the window size across app restarts.
- Revert changes to the Linux icon.
- Fix an issue causing deleted items in watched folders to not move to
uncategorized.
- Fix duplicate file uploads when initializing a folder watch (sometimes).
## v1.7.0

View File

@@ -53,23 +53,24 @@ This'll trigger the workflow and create a new pre-release. We can edit this to
add the release notes, convert it to a release. Once it is marked as latest, the
release goes live.
We are done at this point, and can now create a new pre-release to host
We are done at this point, and can now update the other pre-release that hosts
subsequent nightly builds.
1. Update `package.json` in the source repo to use version `1.x.x-rc`, and
merge these changes into `main`.
2. In the release repo:
2. In the release repo, delete the existing _nightly_ pre-release, then:
```sh
git tag 1.x.x-rc
git push origin 1.x.x-rc
```
3. Once the workflow finishes and the pre-release is created, edit its
description to "Nightly builds".
3. Start a new run of the workflow (`gh workflow run desktop-release.yml`).
4. Delete the pre-release for the previous (already released) version.
Once the workflow finishes and the 1.x.x-rc pre-release is created, edit its
description to "Nightly builds". Subsequent scheduled nightly builds will update
this pre-release.
## Workflow - Extra pre-releases

View File

@@ -6,6 +6,9 @@ files:
extraFiles:
- from: build
to: resources
protocols:
- name: Ente
schemes: ["ente"]
win:
target:
- target: nsis

View File

@@ -1,6 +1,6 @@
{
"name": "ente",
"version": "1.7.1-rc",
"version": "1.7.2-rc",
"private": true,
"description": "Desktop client for Ente Photos",
"repository": "github:ente-io/photos-desktop",
@@ -55,6 +55,6 @@
"typescript": "^5",
"typescript-eslint": "8.0.0-alpha.10"
},
"packageManager": "yarn@1.22.21",
"packageManager": "yarn@1.22.22",
"productName": "ente"
}

View File

@@ -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();

View File

@@ -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

View File

@@ -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);

View File

@@ -23,6 +23,12 @@ export const createWatcher = (mainWindow: BrowserWindow) => {
const folderPaths = folderWatches().map((watch) => watch.folderPath);
const watcher = chokidar.watch(folderPaths, {
// Don't emit "add" events for matching paths when instantiating the
// watch (we do a full disk scan on launch on our own, and also getting
// the same events from the watcher causes duplicates).
ignoreInitial: true,
// Ask the watcher to wait for a the file size to stabilize before
// telling us about a new file. By default, it waits for 2 seconds.
awaitWriteFinish: true,
});

View File

@@ -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" },

View File

@@ -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

View File

@@ -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!

View File

@@ -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",
@@ -131,6 +135,10 @@ export const sidebar = [
text: "Files not uploading",
link: "/photos/troubleshooting/files-not-uploading",
},
{
text: "Missing thumbnails",
link: "/photos/troubleshooting/thumbnails",
},
{
text: "Sharing debug logs",
link: "/photos/troubleshooting/sharing-logs",

View File

@@ -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/.

View File

@@ -0,0 +1,61 @@
---
title: Passkeys
description: Using passkeys as a second factor for your Ente account
---
# Passkeys
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.
>
> - More details about why and how are in the Passkeys announcement
> [blog post](https://ente.io/blog/introducing-passkeys-on-ente/).
> - And 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.

View File

@@ -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
@@ -17,12 +20,35 @@ start it, then you might need to install the VC++ runtime from Microsoft.
This is what the error looks like:
<div style="border: 1px solid black">
![Error when VC++ runtime is not installed](windows-vc.png){width=500px}
</div>
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 +68,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 +79,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:

View File

@@ -8,10 +8,18 @@ description:
## Network Issue
If you are using VPN, please try disabling the VPN or switching provider.
If you are using VPN, please try disabling the VPN or switching your provider.
## Web / Desktop
### Disable "Faster uploads"
We use a Cloudflare proxy to speed up uploads
([blog post](https://ente.io/blog/tech/making-uploads-faster/)). However, in
some network configurations (depending on the ISP) this might prevent uploads
from going through, so if you're having trouble with uploads please try after
disabling the "Faster uploads" setting in _Preferences > Advanced_.
### Certain file types are not uploading
The desktop/web app tries to detect if a particular file is video or image. If

View File

@@ -0,0 +1,16 @@
---
title: Missing thumbnails
description:
Troubleshooting when thumbnails are not being generated when uploading
images in Ente Photos
---
# Missing thumbnails
## Black thumbnails
Users have reported an issue with Firefox which prevents the app from generating
thumbnails if the "block canvas fingerprinting" setting in Firefox is enabled
(i.e. `privacy.resistFingerprinting` is set to true in `about:config`). That
feature blocks access to the canvas, and the app needs the canvas to generate
thumbnails.

View File

@@ -11,5 +11,5 @@
"prettier": "^3",
"vitepress": "^1.0.0-rc.45"
},
"packageManager": "yarn@1.22.21"
"packageManager": "yarn@1.22.22"
}

View File

@@ -31,5 +31,5 @@
"typescript": "^5",
"vite": "^5.2"
},
"packageManager": "yarn@1.22.21"
"packageManager": "yarn@1.22.22"
}

View File

@@ -1,3 +1,4 @@
{
"tabWidth": 4
"tabWidth": 4,
"proseWrap": "always"
}

View File

@@ -1,23 +1,26 @@
# Cloudflare Workers
Source code for our [Cloudflare
Workers](https://developers.cloudflare.com/workers/).
Source code for our
[Cloudflare Workers](https://developers.cloudflare.com/workers/).
Each worker is a self contained directory with its each `package.json`.
## Deploying
* Switch to a worker directory, e.g. `cd github-discord-notifier`.
- Switch to a worker directory, e.g. `cd github-discord-notifier`.
* Install dependencies (if needed) with `yarn`
- Install dependencies (if needed) with `yarn`
* Login into wrangler (if needed) using `yarn wrangler login`
> If you have previously deployed, then you will have an old `yarn.lock`. In
> this case it is safe to delete and recreate using `rm yarn.lock && yarn`.
* Deploy! `yarn wrangler deploy`
- Login into wrangler (if needed) using `yarn wrangler login`
- Deploy! `yarn wrangler deploy`
Wrangler is the CLI provided by Cloudflare to manage workers. Apart from
deploying, it also allows us to stream logs from running workers by using `yarn
wrangler tail`.
deploying, it also allows us to stream logs from running workers by using
`yarn wrangler tail`.
## Creating a new worker
@@ -30,3 +33,12 @@ To import an existing worker from the Cloudflare dashboard, use
```sh
npm create cloudflare@2 existing-worker-name -- --type pre-existing --existing-script existing-worker-name
```
## Logging
Attach the tail worker to your worker by adding
tail_consumers = [{ service = "tail" }]
in its `wrangler.toml`. Then any `console.(log|warn|error)` statements and
uncaught exceptions in your worker will be logged to Grafana.

View File

@@ -2,8 +2,9 @@
"name": "cast-albums",
"private": true,
"devDependencies": {
"@cloudflare/workers-types": "^4.20240314.0",
"@cloudflare/workers-types": "^4.20240614.0",
"typescript": "^5",
"wrangler": "^3"
}
},
"packageManager": "yarn@1.22.22"
}

View File

@@ -1,50 +1,72 @@
/** Proxy file and thumbnail requests from the cast web app */
/** Proxy file and thumbnail requests for the cast web app. */
export default {
async fetch(request: Request) {
switch (request.method) {
case "GET":
return handleGET(request);
case "OPTIONS":
return handleOPTIONS(request);
case "GET":
return handleGET(request);
default:
throw new Error(
`HTTP 405 Method Not Allowed: ${request.method}`
);
console.log(`Unsupported HTTP method ${request.method}`);
return new Response(null, { status: 405 });
}
},
} satisfies ExportedHandler;
const handleOPTIONS = (request: Request) => {
const origin = request.headers.get("Origin");
if (!isAllowedOrigin(origin)) console.warn("Unknown origin", origin);
return new Response("", {
headers: {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, OPTIONS",
"Access-Control-Max-Age": "86400",
"Access-Control-Allow-Headers": "X-Cast-Access-Token",
},
});
};
const isAllowedOrigin = (origin: string | null) => {
const allowed = ["cast.ente.io", "cast.ente.sh", "localhost"];
if (!origin) return false;
try {
const url = new URL(origin);
return allowed.includes(url.hostname);
} catch {
// origin is likely an invalid URL
return false;
}
};
const handleGET = async (request: Request) => {
const url = new URL(request.url);
const urlParams = new URLSearchParams(url.search);
const token =
request.headers.get("X-Cast-Access-Token") ??
urlParams.get("castToken");
const fileID = urlParams.get("fileID");
const fileID = url.searchParams.get("fileID");
if (!fileID) return new Response(null, { status: 400 });
let castToken = request.headers.get("X-Cast-Access-Token");
if (!castToken) {
console.warn("Using deprecated castToken query param");
castToken = url.searchParams.get("castToken");
}
if (!castToken) {
console.error("No cast token provided");
return new Response(null, { status: 400 });
}
const pathname = url.pathname;
const params = new URLSearchParams({ castToken });
let response = await fetch(
`https://api.ente.io/cast/files${pathname}${fileID}?castToken=${token}`
`https://api.ente.io/cast/files${pathname}${fileID}?${params.toString()}`
);
if (!response.ok) console.log("Upstream error", response.status);
response = new Response(response.body, response);
response.headers.set("Access-Control-Allow-Origin", "*");
return response;
};
const handleOPTIONS = (request: Request) => {
let corsHeaders: Record<string, string> = {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET,OPTIONS",
"Access-Control-Max-Age": "86400",
};
const acrh = request.headers.get("Access-Control-Request-Headers");
if (acrh) {
corsHeaders["Access-Control-Allow-Headers"] = acrh;
}
return new Response("", { headers: corsHeaders });
};

View File

@@ -1 +1 @@
{ "extends": "../tsconfig.base.json", "include": ["src/**/*.ts"] }
{ "extends": "../tsconfig.base.json", "include": ["src"] }

View File

@@ -1,8 +1,11 @@
name = "cast-albums"
main = "src/index.ts"
compatibility_date = "2024-03-14"
compatibility_date = "2024-06-14"
[[routes]]
pattern = "cast-albums.ente.io"
zone_name = "ente.io"
custom_domain = true
routes = [
{ pattern = "cast-albums.ente.io", custom_domain = true }
]
tail_consumers = [
{ service = "tail" }
]

View File

@@ -0,0 +1,10 @@
{
"name": "files",
"private": true,
"devDependencies": {
"@cloudflare/workers-types": "^4.20240614.0",
"typescript": "^5",
"wrangler": "^3"
},
"packageManager": "yarn@1.22.22"
}

View File

@@ -0,0 +1,102 @@
/** Proxy requests for files. */
export default {
async fetch(request: Request) {
switch (request.method) {
case "OPTIONS":
return handleOPTIONS(request);
case "GET":
return handleGET(request);
default:
console.log(`Unsupported HTTP method ${request.method}`);
return new Response(null, { status: 405 });
}
},
} satisfies ExportedHandler;
const handleOPTIONS = (request: Request) => {
const origin = request.headers.get("Origin");
if (!isAllowedOrigin(origin)) console.warn("Unknown origin", origin);
const headers = request.headers.get("Access-Control-Request-Headers");
if (!areAllowedHeaders(headers))
console.warn("Unknown header in list", headers);
return new Response("", {
headers: {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, OPTIONS",
"Access-Control-Max-Age": "86400",
// "Access-Control-Allow-Headers": "X-Auth-Token, X-Client-Package",
"Access-Control-Allow-Headers": "*",
},
});
};
const isAllowedOrigin = (origin: string | null) => {
if (!origin) return false;
try {
const url = new URL(origin);
const hostname = url.hostname;
return (
origin == "ente://app" /* desktop app */ ||
hostname.endsWith("ente.io") ||
hostname.endsWith("ente.sh") ||
hostname == "localhost"
);
} catch {
// `origin` is likely an invalid URL.
return false;
}
};
const areAllowedHeaders = (headers: string | null) => {
const allowed = ["x-auth-token", "x-client-package"];
if (!headers) return true;
for (const header of headers.split(",")) {
if (!allowed.includes(header.trim().toLowerCase())) return false;
}
return true;
};
const handleGET = async (request: Request) => {
const url = new URL(request.url);
// Random bots keep trying to pentest causing noise in the logs. If the
// request doesn't have a fileID, we can just safely ignore it thereafter.
const fileID = url.searchParams.get("fileID");
if (!fileID) return new Response(null, { status: 400 });
let token = request.headers.get("X-Auth-Token");
if (!token) {
console.warn("Using deprecated token query param");
token = url.searchParams.get("token");
}
if (!token) {
console.error("No token provided");
// return new Response(null, { status: 400 });
}
// We forward the auth token as a query parameter to museum. This is so that
// it does not get preserved when museum does a redirect to the presigned S3
// URL that serves the actual thumbnail.
//
// See: [Note: Passing credentials for self-hosted file fetches]
const params = new URLSearchParams();
if (token) params.set("token", token);
let response = await fetch(
`https://api.ente.io/files/download/${fileID}?${params.toString()}`,
{
headers: {
"User-Agent": request.headers.get("User-Agent") ?? "",
},
}
);
if (!response.ok) console.log("Upstream error", response.status);
response = new Response(response.body, response);
response.headers.set("Access-Control-Allow-Origin", "*");
return response;
};

View File

@@ -0,0 +1 @@
{ "extends": "../tsconfig.base.json", "include": ["src"] }

View File

@@ -0,0 +1,11 @@
name = "files"
main = "src/index.ts"
compatibility_date = "2024-06-14"
routes = [
{ pattern = "files.ente.io", custom_domain = true }
]
tail_consumers = [
{ service = "tail" }
]

View File

@@ -2,8 +2,9 @@
"name": "github-discord-notifier",
"private": true,
"devDependencies": {
"@cloudflare/workers-types": "^4.20240314.0",
"@cloudflare/workers-types": "^4.20240614.0",
"typescript": "^5",
"wrangler": "^3"
}
},
"packageManager": "yarn@1.22.22"
}

View File

@@ -2,7 +2,7 @@
* Forward notifications from GitHub to Discord.
*
* This worker receives webhooks from GitHub, filters out the ones we don't
* need, and forwards them to a Discord webhook.
* need, and forwards the rest to a Discord webhook.
*/
export default {
async fetch(request: Request, env: Env) {
@@ -33,13 +33,13 @@ const handleRequest = async (request: Request, discordWebhookURL: string) => {
// doesn't work for get silently ignored (Discord responds with a 204).
// https://github.com/discord/discord-api-docs/issues/6203#issuecomment-1608151265
let response = await fetch(`${discordWebhookURL}/github`, {
const response = await fetch(`${discordWebhookURL}/github`, {
method: request.method,
headers: request.headers,
body: requestBody,
});
if (response.status === 429) {
if (response.status == 429) {
// Sometimes Discord starts returning 429 Rate Limited responses when we
// try to invoke the webhook.
//
@@ -79,7 +79,7 @@ const handleRequest = async (request: Request, discordWebhookURL: string) => {
const action = requestJSON["action"];
if (activityURL && ["created", "opened"].includes(action)) {
response = await fetch(discordWebhookURL, {
return fetch(discordWebhookURL, {
method: request.method,
headers: request.headers,
body: JSON.stringify({
@@ -89,12 +89,5 @@ const handleRequest = async (request: Request, discordWebhookURL: string) => {
}
}
const responseBody = await response.text();
const newResponse = new Response(responseBody, {
status: response.status,
statusText: response.statusText,
headers: response.headers,
});
return newResponse;
return response;
};

View File

@@ -1 +1 @@
{ "extends": "../tsconfig.base.json", "include": ["src/**/*.ts"] }
{ "extends": "../tsconfig.base.json", "include": ["src"] }

View File

@@ -1,6 +1,6 @@
name = "github-discord-notifier"
main = "src/index.ts"
compatibility_date = "2024-03-14"
compatibility_date = "2024-06-14"
[vars]
# Added as a secret via the Cloudflare dashboard

View File

@@ -0,0 +1,10 @@
{
"name": "health-check",
"private": true,
"devDependencies": {
"@cloudflare/workers-types": "^4.20240614.0",
"typescript": "^5",
"wrangler": "^3"
},
"packageManager": "yarn@1.22.22"
}

View File

@@ -0,0 +1,48 @@
/** Ping api.ente.io every minute and yell if it doesn't pong. */
export default {
async scheduled(_, env: Env, ctx: ExecutionContext) {
ctx.waitUntil(ping(env, ctx));
},
} satisfies ExportedHandler<Env>;
interface Env {
NOTIFY_URL: string;
CHAT_ID: string;
}
const ping = async (env: Env, ctx: ExecutionContext) => {
const notify = async (msg: string) =>
sendMessage(`${msg} on ${Date()}`, env);
try {
let timeout = setTimeout(() => {
ctx.waitUntil(notify("Ping timed out"));
}, 5000);
const res = await fetch("https://api.ente.io/ping", {
headers: {
"User-Agent": "health-check",
},
});
clearTimeout(timeout);
if (!res.ok) await notify(`Ping failed (HTTP ${res.status})`);
} catch (e) {
await notify(`Ping failed (${e instanceof Error ? e.message : e})`);
}
};
const sendMessage = async (message: string, env: Env) => {
console.log(message);
const res = await fetch(env.NOTIFY_URL, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
chat_id: parseInt(env.CHAT_ID),
parse_mode: "html",
text: message,
}),
});
if (!res.ok) throw new Error(`Failed to sendMessage (HTTP ${res.status})`);
};

View File

@@ -0,0 +1 @@
{ "extends": "../tsconfig.base.json", "include": ["src"] }

View File

@@ -0,0 +1,17 @@
name = "health-check"
main = "src/index.ts"
compatibility_date = "2024-06-14"
# Disable the default route, this worker does not handle fetch.
workers_dev = false
tail_consumers = [{ service = "tail" }]
[vars]
# Added as a secret via the Cloudflare dashboard
# NOTIFY_URL = ""
# CHAT_ID = ""
[triggers]
# Every minute
crons = [ "*/1 * * * *" ]

View File

@@ -0,0 +1,10 @@
{
"name": "public-albums",
"private": true,
"devDependencies": {
"@cloudflare/workers-types": "^4.20240614.0",
"typescript": "^5",
"wrangler": "^3"
},
"packageManager": "yarn@1.22.22"
}

View File

@@ -0,0 +1,101 @@
/** Proxy requests for files and thumbnails in public albums. */
export default {
async fetch(request: Request) {
switch (request.method) {
case "OPTIONS":
return handleOPTIONS(request);
case "GET":
return handleGET(request);
default:
console.log(`Unsupported HTTP method ${request.method}`);
return new Response(null, { status: 405 });
}
},
} satisfies ExportedHandler;
const handleOPTIONS = (request: Request) => {
const origin = request.headers.get("Origin");
if (!isAllowedOrigin(origin)) console.warn("Unknown origin", origin);
const headers = request.headers.get("Access-Control-Request-Headers");
if (!areAllowedHeaders(headers))
console.warn("Unknown header in list", headers);
return new Response("", {
headers: {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, OPTIONS",
"Access-Control-Max-Age": "86400",
// "Access-Control-Allow-Headers": "X-Auth-Access-Token, X-Auth-Access-Token-JWT",
// "Access-Control-Allow-Headers": "X-Auth-Access-Token, X-Auth-Access-Token-JWT, x-client-package",
"Access-Control-Allow-Headers": "*",
},
});
};
const isAllowedOrigin = (origin: string | null) => {
const allowed = ["albums.ente.io", "albums.ente.sh", "localhost"];
if (!origin) return false;
try {
const url = new URL(origin);
return allowed.includes(url.hostname);
} catch {
// origin is likely an invalid URL
return false;
}
};
const areAllowedHeaders = (headers: string | null) => {
// TODO(MR): Stop sending "x-client-package"
const allowed = [
"x-auth-access-token",
"x-auth-access-token-jwt",
"x-client-package",
];
if (!headers) return true;
for (const header of headers.split(",")) {
if (!allowed.includes(header.trim().toLowerCase())) return false;
}
return true;
};
const handleGET = async (request: Request) => {
const url = new URL(request.url);
const fileID = url.searchParams.get("fileID");
if (!fileID) return new Response(null, { status: 400 });
let accessToken = request.headers.get("X-Auth-Access-Token");
if (accessToken === undefined) {
console.warn("Using deprecated accessToken query param");
accessToken = url.searchParams.get("accessToken");
}
if (!accessToken) {
console.error("No accessToken provided");
// return new Response(null, { status: 400 });
}
let accessTokenJWT = request.headers.get("X-Auth-Access-Token-JWT");
if (accessTokenJWT === undefined) {
console.warn("Using deprecated accessTokenJWT query param");
accessTokenJWT = url.searchParams.get("accessTokenJWT");
}
const pathname = url.pathname;
const params = new URLSearchParams();
if (accessToken) params.set("accessToken", accessToken);
if (accessTokenJWT) params.set("accessTokenJWT", accessTokenJWT);
let response = await fetch(
`https://api.ente.io/public-collection/files${pathname}${fileID}?${params.toString()}`
);
if (!response.ok) console.log("Upstream error", response.status);
response = new Response(response.body, response);
response.headers.set("Access-Control-Allow-Origin", "*");
return response;
};

View File

@@ -0,0 +1 @@
{ "extends": "../tsconfig.base.json", "include": ["src"] }

View File

@@ -0,0 +1,11 @@
name = "public-albums"
main = "src/index.ts"
compatibility_date = "2024-06-14"
routes = [
{ pattern = "public-albums.ente.io", custom_domain = true }
]
tail_consumers = [
{ service = "tail" }
]

View File

@@ -0,0 +1,10 @@
{
"name": "tail",
"private": true,
"devDependencies": {
"@cloudflare/workers-types": "^4.20240614.0",
"typescript": "^5",
"wrangler": "^3"
},
"packageManager": "yarn@1.22.22"
}

View File

@@ -0,0 +1,72 @@
/**
* A tail worker that forwards all `console.log` (and siblings) to Loki.
*
* https://developers.cloudflare.com/workers/observability/logging/tail-workers/
*/
export default {
async tail(events: TraceItem[], env: Env) {
// If the tail worker itself throws an exception (it shouldn't, unless
// Loki is down), we don't catch it so that it counts as an "error" in
// the worker stats.
await handleTail(events, env);
},
} satisfies ExportedHandler<Env>;
interface Env {
/** The URL of the Loki instance to push logs to. */
LOKI_PUSH_URL: string;
/**
* The value of the "Basic" authorization.
*
* [Note: HTTP basic authorization in worker fetch]
*
* Usually a Loki push URL is specified with the credentials inline, say
* `http://user:pass@loki/path`. However, I cannot get that to work with the
* `fetch` inside a Cloudflare worker. Instead, the credentials need to be
* separately provided as the Authorization header of the form:
*
* Authorization: Basic ${btoa(user:pass)}
*
* The LOKI_AUTH secret is the "${btoa(user:pass)}" value.
*/
LOKI_AUTH: string;
}
const handleTail = async (events: TraceItem[], env: Env) => {
for (const event of events.filter(hasLogOrException))
await pushLogLine(Date.now(), JSON.stringify(event), env);
};
/** Return true if the {@link event} has at least one log or exception. */
const hasLogOrException = (event: TraceItem) =>
event.logs.length ?? event.exceptions.length;
/**
* Send a log entry to (Grafana) Loki
*
* For more details about the protocol, see
* https://grafana.com/docs/loki/latest/reference/loki-http-api/#ingest-logs
*
* @param timestampMs Unix epoch (in milliseconds) when the event occurred.
*
* @param logLine The message to log.
*
* @param env The worker environment; we need it for the Loki URL and
* credentials.
*/
const pushLogLine = async (timestampMs: number, logLine: string, env: Env) =>
await fetch(env.LOKI_PUSH_URL, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Basic ${env.LOKI_AUTH}`,
},
body: JSON.stringify({
streams: [
{
stream: { job: "worker" },
values: [[`${timestampMs * 1e6}`, logLine]],
},
],
}),
});

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