@atproto/oauth-provider 0.5.0 → 0.5.1
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/CHANGELOG.md +8 -0
- package/dist/oauth-provider.d.ts +3 -3
- package/dist/oauth-provider.d.ts.map +1 -1
- package/dist/oauth-provider.js.map +1 -1
- package/dist/output/build-customization-data.d.ts +20 -11
- package/dist/output/build-customization-data.d.ts.map +1 -1
- package/dist/output/build-customization-data.js +72 -43
- package/dist/output/build-customization-data.js.map +1 -1
- package/package.json +1 -1
- package/src/assets/app/locales/an/messages.po +6 -6
- package/src/assets/app/locales/ast/messages.po +6 -6
- package/src/assets/app/locales/ca/messages.po +6 -6
- package/src/assets/app/locales/da/messages.po +6 -6
- package/src/assets/app/locales/de/messages.po +6 -6
- package/src/assets/app/locales/el/messages.po +6 -6
- package/src/assets/app/locales/en/messages.po +6 -6
- package/src/assets/app/locales/en-GB/messages.po +6 -6
- package/src/assets/app/locales/es/messages.po +6 -6
- package/src/assets/app/locales/eu/messages.po +6 -6
- package/src/assets/app/locales/fi/messages.po +6 -6
- package/src/assets/app/locales/fr/messages.po +6 -6
- package/src/assets/app/locales/ga/messages.po +6 -6
- package/src/assets/app/locales/gl/messages.po +6 -6
- package/src/assets/app/locales/hi/messages.po +6 -6
- package/src/assets/app/locales/hu/messages.po +6 -6
- package/src/assets/app/locales/ia/messages.po +6 -6
- package/src/assets/app/locales/id/messages.po +6 -6
- package/src/assets/app/locales/it/messages.po +6 -6
- package/src/assets/app/locales/ja/messages.po +6 -6
- package/src/assets/app/locales/km/messages.po +6 -6
- package/src/assets/app/locales/ko/messages.po +6 -6
- package/src/assets/app/locales/ne/messages.po +6 -6
- package/src/assets/app/locales/nl/messages.po +6 -6
- package/src/assets/app/locales/pl/messages.po +6 -6
- package/src/assets/app/locales/pt-BR/messages.po +6 -6
- package/src/assets/app/locales/ro/messages.po +6 -6
- package/src/assets/app/locales/ru/messages.po +6 -6
- package/src/assets/app/locales/sv/messages.po +6 -6
- package/src/assets/app/locales/th/messages.po +6 -6
- package/src/assets/app/locales/tr/messages.po +6 -6
- package/src/assets/app/locales/uk/messages.po +6 -6
- package/src/assets/app/locales/vi/messages.po +6 -6
- package/src/assets/app/locales/zh-CN/messages.po +6 -6
- package/src/assets/app/locales/zh-HK/messages.po +6 -6
- package/src/assets/app/locales/zh-TW/messages.po +6 -6
- package/src/oauth-provider.ts +7 -3
- package/src/output/build-customization-data.ts +89 -50
@@ -9,8 +9,32 @@ export const colorNames = ['brand', 'error', 'warning', 'success'] as const
|
|
9
9
|
export const colorNameSchema = z.enum(colorNames)
|
10
10
|
export type ColorName = z.infer<typeof colorNameSchema>
|
11
11
|
|
12
|
-
|
13
|
-
|
12
|
+
const parsedColorSchema = z.string().transform((value, ctx): RgbColor => {
|
13
|
+
try {
|
14
|
+
const { r, g, b, a } = parseColor(value)
|
15
|
+
if (a != null) {
|
16
|
+
ctx.addIssue({
|
17
|
+
code: z.ZodIssueCode.custom,
|
18
|
+
message: 'Alpha values are not supported',
|
19
|
+
})
|
20
|
+
}
|
21
|
+
return { r, g, b }
|
22
|
+
} catch (e) {
|
23
|
+
ctx.addIssue({
|
24
|
+
code: z.ZodIssueCode.custom,
|
25
|
+
message: e instanceof Error ? e.message : 'Invalid color value',
|
26
|
+
})
|
27
|
+
// Won't actually be used (since an issue was added):
|
28
|
+
return { r: 0, g: 0, b: 0 }
|
29
|
+
}
|
30
|
+
})
|
31
|
+
export type ParsedColor = z.infer<typeof parsedColorSchema> // Same as RgbColor
|
32
|
+
|
33
|
+
export const colorsDefinitionSchema = z.record(
|
34
|
+
colorNameSchema,
|
35
|
+
parsedColorSchema.optional(),
|
36
|
+
)
|
37
|
+
export type ColorsDefinition = z.infer<typeof colorsDefinitionSchema>
|
14
38
|
|
15
39
|
export const localizedStringSchema = z.union([
|
16
40
|
z.string(),
|
@@ -34,10 +58,11 @@ export type LinkDefinition = z.infer<typeof linkDefinitionSchema>
|
|
34
58
|
export const brandingConfigSchema = z.object({
|
35
59
|
name: z.string().optional(),
|
36
60
|
logo: z.string().optional(),
|
37
|
-
colors:
|
61
|
+
colors: colorsDefinitionSchema.optional(),
|
38
62
|
links: z.array(linkDefinitionSchema).readonly().optional(),
|
39
63
|
})
|
40
|
-
export type
|
64
|
+
export type BrandingInput = z.input<typeof brandingConfigSchema>
|
65
|
+
export type Branding = z.infer<typeof brandingConfigSchema>
|
41
66
|
|
42
67
|
export const customizationSchema = z.object({
|
43
68
|
/**
|
@@ -58,6 +83,7 @@ export const customizationSchema = z.object({
|
|
58
83
|
*/
|
59
84
|
hcaptcha: hcaptchaConfigSchema.optional(),
|
60
85
|
})
|
86
|
+
export type CustomizationInput = z.input<typeof customizationSchema>
|
61
87
|
export type Customization = z.infer<typeof customizationSchema>
|
62
88
|
|
63
89
|
export type CustomizationData = {
|
@@ -99,19 +125,13 @@ export function buildCustomizationCss({ branding }: Customization) {
|
|
99
125
|
return ''
|
100
126
|
}
|
101
127
|
|
102
|
-
function* buildCustomizationVars(branding?:
|
128
|
+
function* buildCustomizationVars(branding?: Branding) {
|
103
129
|
if (branding?.colors) {
|
104
130
|
for (const name of colorNames) {
|
105
131
|
const value = branding.colors[name]
|
106
|
-
if (!value) continue
|
107
|
-
|
108
|
-
// Skip undefined values
|
109
|
-
if (value === undefined) continue
|
132
|
+
if (!value) continue // Skip missing colors
|
110
133
|
|
111
|
-
const { r, g, b
|
112
|
-
|
113
|
-
// Tailwind does not apply alpha values to base colors
|
114
|
-
if (a !== undefined) throw new TypeError('Alpha not supported')
|
134
|
+
const { r, g, b } = value
|
115
135
|
|
116
136
|
const contrast = computeLuma({ r, g, b }) > 128 ? '0 0 0' : '255 255 255'
|
117
137
|
|
@@ -121,54 +141,71 @@ function* buildCustomizationVars(branding?: BrandingConfig) {
|
|
121
141
|
}
|
122
142
|
}
|
123
143
|
|
144
|
+
type RgbColor = { r: number; g: number; b: number }
|
124
145
|
type RgbaColor = { r: number; g: number; b: number; a?: number }
|
125
|
-
function parseColor(color:
|
126
|
-
if (
|
127
|
-
|
146
|
+
function parseColor(color: string): RgbaColor {
|
147
|
+
if (color.startsWith('#')) {
|
148
|
+
return parseHexColor(color)
|
128
149
|
}
|
129
150
|
|
130
|
-
if (color.startsWith('
|
131
|
-
|
132
|
-
|
133
|
-
const g = parseUi8Hex(color.slice(2, 3))
|
134
|
-
const b = parseUi8Hex(color.slice(3, 4))
|
135
|
-
const a = color.length > 4 ? parseUi8Hex(color.slice(4, 5)) : undefined
|
136
|
-
return { r, g, b, a }
|
137
|
-
}
|
151
|
+
if (color.startsWith('rgba(')) {
|
152
|
+
return parseRgbaColor(color)
|
153
|
+
}
|
138
154
|
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
155
|
+
if (color.startsWith('rgb(')) {
|
156
|
+
return parseRgbColor(color)
|
157
|
+
}
|
158
|
+
|
159
|
+
// Should never happen (as long as the input is a validated WebColor)
|
160
|
+
throw new TypeError(`Invalid color value: ${color}`)
|
161
|
+
}
|
146
162
|
|
147
|
-
|
163
|
+
function parseHexColor(v: string) {
|
164
|
+
// parseInt('az', 16) does not return NaN so we need to check the format
|
165
|
+
if (!/^#[0-9a-f]+$/i.test(v)) {
|
166
|
+
throw new TypeError(`Invalid hex color value: ${v}`)
|
148
167
|
}
|
149
168
|
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
const
|
155
|
-
|
156
|
-
const b = parseUi8Dec(rgbMatch[3])
|
157
|
-
return { r, g, b }
|
169
|
+
if (v.length === 4 || v.length === 5) {
|
170
|
+
const r = parseUi8Hex(v.slice(1, 2))
|
171
|
+
const g = parseUi8Hex(v.slice(2, 3))
|
172
|
+
const b = parseUi8Hex(v.slice(3, 4))
|
173
|
+
const a = v.length > 4 ? parseUi8Hex(v.slice(4, 5)) : undefined
|
174
|
+
return { r, g, b, a }
|
158
175
|
}
|
159
176
|
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
const
|
165
|
-
const g = parseUi8Dec(rgbaMatch[2])
|
166
|
-
const b = parseUi8Dec(rgbaMatch[3])
|
167
|
-
const a = parseUi8Dec(rgbaMatch[4])
|
177
|
+
if (v.length === 7 || v.length === 9) {
|
178
|
+
const r = parseUi8Hex(v.slice(1, 3))
|
179
|
+
const g = parseUi8Hex(v.slice(3, 5))
|
180
|
+
const b = parseUi8Hex(v.slice(5, 7))
|
181
|
+
const a = v.length > 8 ? parseUi8Hex(v.slice(7, 9)) : undefined
|
168
182
|
return { r, g, b, a }
|
169
183
|
}
|
170
184
|
|
171
|
-
throw new TypeError(`
|
185
|
+
throw new TypeError(`Invalid hex color value: ${v}`)
|
186
|
+
}
|
187
|
+
|
188
|
+
function parseRgbColor(v: string) {
|
189
|
+
const matches = v.match(/^\s*rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)\s*$/)
|
190
|
+
if (!matches) throw new TypeError(`Invalid rgb color value: ${v}`)
|
191
|
+
|
192
|
+
const r = parseUi8Dec(matches[1])
|
193
|
+
const g = parseUi8Dec(matches[2])
|
194
|
+
const b = parseUi8Dec(matches[3])
|
195
|
+
return { r, g, b }
|
196
|
+
}
|
197
|
+
|
198
|
+
function parseRgbaColor(v: string) {
|
199
|
+
const matches = v.match(
|
200
|
+
/^\s*rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)\s*$/,
|
201
|
+
)
|
202
|
+
if (!matches) throw new TypeError(`Invalid rgba color value: ${v}`)
|
203
|
+
|
204
|
+
const r = parseUi8Dec(matches[1])
|
205
|
+
const g = parseUi8Dec(matches[2])
|
206
|
+
const b = parseUi8Dec(matches[3])
|
207
|
+
const a = parseUi8Dec(matches[4])
|
208
|
+
return { r, g, b, a }
|
172
209
|
}
|
173
210
|
|
174
211
|
function computeLuma({ r, g, b }: RgbaColor) {
|
@@ -185,5 +222,7 @@ function parseUi8Dec(v: string) {
|
|
185
222
|
|
186
223
|
function asUi8(v: number) {
|
187
224
|
if (v >= 0 && v <= 255 && v === (v | 0)) return v
|
188
|
-
throw new TypeError(
|
225
|
+
throw new TypeError(
|
226
|
+
`Invalid color component "${v}" (expected an integer between 0 and 255)`,
|
227
|
+
)
|
189
228
|
}
|