@unavatar/core 3.24.0 → 3.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +32 -4
- package/package.json +5 -1
- package/src/avatar/auto.js +9 -2
- package/src/index.js +5 -0
- package/src/providers/gravatar.js +6 -4
- package/src/util/is-hash.js +5 -0
package/README.md
CHANGED
|
@@ -52,6 +52,7 @@
|
|
|
52
52
|
- [X/Twitter](#xtwitter)
|
|
53
53
|
- [Xbox Gamertag](#xbox-gamertag)
|
|
54
54
|
- [YouTube](#youtube)
|
|
55
|
+
- [Privacy](#privacy)
|
|
55
56
|
- [Response Format](#response-format)
|
|
56
57
|
- [Response Headers](#response-headers)
|
|
57
58
|
- [Response Errors](#response-errors)
|
|
@@ -68,13 +69,15 @@ It's proudly powered by [microlink.io](https://microlink.io/), the headless brow
|
|
|
68
69
|
|
|
69
70
|
The service is exposed in **unavatar.io** via provider endpoints:
|
|
70
71
|
|
|
71
|
-
- an **email
|
|
72
|
+
- an **email**: [unavatar.io/email/hello@microlink.io](https://unavatar.io/email/hello@microlink.io)
|
|
73
|
+
- an **email hash** (auto-detected as hashed email): [unavatar.io/email/295dee0d3dbb93aac67e72ae4af40f728f050e5fd18417ad60d1ed19186ae03b](https://unavatar.io/email/295dee0d3dbb93aac67e72ae4af40f728f050e5fd18417ad60d1ed19186ae03b)
|
|
74
|
+
- a **domain**: [unavatar.io/domain/reddit.com](https://unavatar.io/domain/reddit.com)
|
|
72
75
|
- an **email** via Gravatar: [unavatar.io/gravatar/hello@microlink.io](https://unavatar.io/gravatar/hello@microlink.io)
|
|
73
76
|
- an **email** via GitHub: [unavatar.io/github/sindresorhus@gmail.com](https://unavatar.io/github/sindresorhus@gmail.com)
|
|
74
77
|
- an **username**: [unavatar.io/github/kikobeats](https://unavatar.io/github/kikobeats)
|
|
75
78
|
- a **domain**: [unavatar.io/google/reddit.com](https://unavatar.io/google/reddit.com)
|
|
76
79
|
|
|
77
|
-
Use
|
|
80
|
+
Use `/email/:key` and `/domain/:key` for type-based resolution. You can read more in [Email avatars](https://unavatar.io/email) and [providers](https://unavatar.io/docs#providers).
|
|
78
81
|
|
|
79
82
|
## Authentication
|
|
80
83
|
|
|
@@ -410,6 +413,10 @@ Get any user's avatar by their email address via Gravatar. The most widely used
|
|
|
410
413
|
Available inputs:
|
|
411
414
|
|
|
412
415
|
- Email address, e.g., [unavatar.io/gravatar/hello@microlink.io](https://unavatar.io/gravatar/hello@microlink.io)
|
|
416
|
+
- SHA256 hash, e.g., [unavatar.io/gravatar/295dee0d3dbb93aac67e72ae4af40f728f050e5fd18417ad60d1ed19186ae03b](https://unavatar.io/gravatar/295dee0d3dbb93aac67e72ae4af40f728f050e5fd18417ad60d1ed19186ae03b)
|
|
417
|
+
- MD5 hash (legacy), e.g., [unavatar.io/gravatar/0bc83cb571cd1c50ba6f3e8a78ef1346](https://unavatar.io/gravatar/0bc83cb571cd1c50ba6f3e8a78ef1346)
|
|
418
|
+
|
|
419
|
+
Passing a pre-computed hash instead of the raw email avoids exposing the email address in the URL. See [Privacy](#privacy) for details.
|
|
413
420
|
|
|
414
421
|
### Instagram
|
|
415
422
|
|
|
@@ -651,7 +658,7 @@ Available inputs:
|
|
|
651
658
|
|
|
652
659
|
### YouTube
|
|
653
660
|
|
|
654
|
-
Get any YouTube channel's thumbnail by their handle,
|
|
661
|
+
Get any YouTube channel's thumbnail by their handle, username, or channel ID.
|
|
655
662
|
|
|
656
663
|
e.g., [unavatar.io/youtube/casey](https://unavatar.io/youtube/casey)
|
|
657
664
|
|
|
@@ -664,6 +671,27 @@ Available inputs:
|
|
|
664
671
|
- `username`: [unavatar.io/youtube/casey](https://unavatar.io/youtube/casey)
|
|
665
672
|
- `channel`: [unavatar.io/youtube/UC_x5XG1OV2P6uZZ5FSM9Ttw](https://unavatar.io/youtube/UC_x5XG1OV2P6uZZ5FSM9Ttw)
|
|
666
673
|
|
|
674
|
+
## Privacy
|
|
675
|
+
|
|
676
|
+
When you pass an email address directly in the URL, it is visible in plain text — both in server logs and to any intermediary that inspects the request.
|
|
677
|
+
|
|
678
|
+
To avoid this, pass a pre-computed **MD5** or **SHA256** hash of the email instead. Unavatar detects the hash automatically and routes it to Gravatar, which natively supports both hash formats.
|
|
679
|
+
|
|
680
|
+
```bash
|
|
681
|
+
# Instead of exposing the raw email:
|
|
682
|
+
https://unavatar.io/hello@example.com
|
|
683
|
+
|
|
684
|
+
# Pass the SHA256 hash:
|
|
685
|
+
https://unavatar.io/295dee0d3dbb93aac67e72ae4af40f728f050e5fd18417ad60d1ed19186ae03b
|
|
686
|
+
|
|
687
|
+
# Or the MD5 hash (legacy, still supported by Gravatar):
|
|
688
|
+
https://unavatar.io/0bc83cb571cd1c50ba6f3e8a78ef1346
|
|
689
|
+
```
|
|
690
|
+
|
|
691
|
+
The hash must be exactly 32 hex characters (MD5) or 64 hex characters (SHA256), lowercase or uppercase — unavatar normalises it automatically.
|
|
692
|
+
|
|
693
|
+
Note: hash-based lookup is only supported for Gravatar. Other providers such as GitHub require the raw email address and cannot reverse a hash.
|
|
694
|
+
|
|
667
695
|
## Response Format
|
|
668
696
|
|
|
669
697
|
A response is returning the user avatar by default.
|
|
@@ -745,4 +773,4 @@ Expected errors are known operational cases returned with stable codes.
|
|
|
745
773
|
|
|
746
774
|
## Contact
|
|
747
775
|
|
|
748
|
-
If you have any suggestion or bug to report, please contact to ust mailing to [hello@unavatar.io](mailto:hello@unavatar.io).
|
|
776
|
+
If you have any suggestion or bug to report, please contact to ust mailing to [hello@unavatar.io](mailto:hello@unavatar.io).
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@unavatar/core",
|
|
3
3
|
"description": "Get unified user avatar from social networks, including Instagram, SoundCloud, Telegram, Twitter, YouTube & more.",
|
|
4
4
|
"homepage": "https://unavatar.io",
|
|
5
|
-
"version": "3.
|
|
5
|
+
"version": "3.25.0",
|
|
6
6
|
"main": "src/index.js",
|
|
7
7
|
"exports": {
|
|
8
8
|
".": "./src/index.js",
|
|
@@ -50,6 +50,10 @@
|
|
|
50
50
|
"name": "Nicolas Hedger",
|
|
51
51
|
"email": "649677+nhedger@users.noreply.github.com"
|
|
52
52
|
},
|
|
53
|
+
{
|
|
54
|
+
"name": "Mariano Álvarez",
|
|
55
|
+
"email": "66380259+creativoma@users.noreply.github.com"
|
|
56
|
+
},
|
|
53
57
|
{
|
|
54
58
|
"name": "Angel M De Miguel",
|
|
55
59
|
"email": "angel@bitnami.com"
|
package/src/avatar/auto.js
CHANGED
|
@@ -15,8 +15,10 @@ const ExtendableError = require('../util/error')
|
|
|
15
15
|
const DATA_URI_REGEX = dataUriRegex()
|
|
16
16
|
const DOMAIN_REGEX = urlRegex({ strict: false })
|
|
17
17
|
|
|
18
|
+
const isHash = require('../util/is-hash')
|
|
19
|
+
|
|
18
20
|
const getInputType = input => {
|
|
19
|
-
if (isEmail(input)) return 'email'
|
|
21
|
+
if (isEmail(input) || isHash(input)) return 'email'
|
|
20
22
|
if (stableRegex(DOMAIN_REGEX, input)) return 'domain'
|
|
21
23
|
return 'username'
|
|
22
24
|
}
|
|
@@ -84,7 +86,12 @@ const factory = ({ constants, providers, providersBy, reachableUrl }) => {
|
|
|
84
86
|
}
|
|
85
87
|
|
|
86
88
|
const resolveAutoByType = async (inputType, input, context) => {
|
|
87
|
-
|
|
89
|
+
let collection = providerEntriesByType[inputType]
|
|
90
|
+
|
|
91
|
+
if (inputType === 'email' && isHash(input)) {
|
|
92
|
+
collection = collection.filter(([provider]) => provider === 'gravatar')
|
|
93
|
+
}
|
|
94
|
+
|
|
88
95
|
const promises = new Array(collection.length)
|
|
89
96
|
|
|
90
97
|
for (let index = 0; index < collection.length; index++) {
|
package/src/index.js
CHANGED
|
@@ -61,6 +61,11 @@ module.exports = ({ constants: userConstants, redis, onFetchHTML } = {}) => {
|
|
|
61
61
|
unavatar[name] = input => getAvatar(providers[name], name, input, {})
|
|
62
62
|
})
|
|
63
63
|
|
|
64
|
+
const createTypedAutoResolver = inputType => input => auto(inputType)(input, {})
|
|
65
|
+
|
|
66
|
+
unavatar.email = createTypedAutoResolver('email')
|
|
67
|
+
unavatar.domain = createTypedAutoResolver('domain')
|
|
68
|
+
|
|
64
69
|
unavatar.auto = auto
|
|
65
70
|
unavatar.getInputType = getInputType
|
|
66
71
|
unavatar.getAvatar = getAvatar
|
|
@@ -3,14 +3,16 @@
|
|
|
3
3
|
const crypto = require('crypto')
|
|
4
4
|
|
|
5
5
|
const stringify = require('../util/stringify')
|
|
6
|
+
const isHash = require('../util/is-hash')
|
|
6
7
|
|
|
7
|
-
const
|
|
8
|
+
const sha256 = str => crypto.createHash('sha256').update(str).digest('hex')
|
|
9
|
+
|
|
10
|
+
const toHash = input =>
|
|
11
|
+
isHash(input) ? input.toLowerCase() : sha256(input.trim().toLowerCase())
|
|
8
12
|
|
|
9
13
|
module.exports = ({ constants }) =>
|
|
10
14
|
function gravatar (input) {
|
|
11
|
-
return `https://gravatar.com/avatar/${
|
|
12
|
-
input.trim().toLowerCase()
|
|
13
|
-
)}?${stringify({
|
|
15
|
+
return `https://gravatar.com/avatar/${toHash(input)}?${stringify({
|
|
14
16
|
size: constants.AVATAR_SIZE,
|
|
15
17
|
d: '404'
|
|
16
18
|
})}`
|