@graffiti-garden/implementation-decentralized 0.0.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/LICENSE +674 -0
- package/dist/1-services/1-authorization.d.ts +37 -0
- package/dist/1-services/1-authorization.d.ts.map +1 -0
- package/dist/1-services/2-dids-tests.d.ts +2 -0
- package/dist/1-services/2-dids-tests.d.ts.map +1 -0
- package/dist/1-services/2-dids.d.ts +9 -0
- package/dist/1-services/2-dids.d.ts.map +1 -0
- package/dist/1-services/3-storage-buckets-tests.d.ts +2 -0
- package/dist/1-services/3-storage-buckets-tests.d.ts.map +1 -0
- package/dist/1-services/3-storage-buckets.d.ts +11 -0
- package/dist/1-services/3-storage-buckets.d.ts.map +1 -0
- package/dist/1-services/4-inboxes-tests.d.ts +2 -0
- package/dist/1-services/4-inboxes-tests.d.ts.map +1 -0
- package/dist/1-services/4-inboxes.d.ts +87 -0
- package/dist/1-services/4-inboxes.d.ts.map +1 -0
- package/dist/1-services/utilities.d.ts +7 -0
- package/dist/1-services/utilities.d.ts.map +1 -0
- package/dist/2-primitives/1-string-encoding-tests.d.ts +2 -0
- package/dist/2-primitives/1-string-encoding-tests.d.ts.map +1 -0
- package/dist/2-primitives/1-string-encoding.d.ts +6 -0
- package/dist/2-primitives/1-string-encoding.d.ts.map +1 -0
- package/dist/2-primitives/2-content-addresses-tests.d.ts +2 -0
- package/dist/2-primitives/2-content-addresses-tests.d.ts.map +1 -0
- package/dist/2-primitives/2-content-addresses.d.ts +8 -0
- package/dist/2-primitives/2-content-addresses.d.ts.map +1 -0
- package/dist/2-primitives/3-channel-attestations-tests.d.ts +2 -0
- package/dist/2-primitives/3-channel-attestations-tests.d.ts.map +1 -0
- package/dist/2-primitives/3-channel-attestations.d.ts +13 -0
- package/dist/2-primitives/3-channel-attestations.d.ts.map +1 -0
- package/dist/2-primitives/4-allowed-attestations-tests.d.ts +2 -0
- package/dist/2-primitives/4-allowed-attestations-tests.d.ts.map +1 -0
- package/dist/2-primitives/4-allowed-attestations.d.ts +9 -0
- package/dist/2-primitives/4-allowed-attestations.d.ts.map +1 -0
- package/dist/3-protocol/1-sessions.d.ts +81 -0
- package/dist/3-protocol/1-sessions.d.ts.map +1 -0
- package/dist/3-protocol/2-handles-tests.d.ts +2 -0
- package/dist/3-protocol/2-handles-tests.d.ts.map +1 -0
- package/dist/3-protocol/2-handles.d.ts +13 -0
- package/dist/3-protocol/2-handles.d.ts.map +1 -0
- package/dist/3-protocol/3-object-encoding-tests.d.ts +2 -0
- package/dist/3-protocol/3-object-encoding-tests.d.ts.map +1 -0
- package/dist/3-protocol/3-object-encoding.d.ts +43 -0
- package/dist/3-protocol/3-object-encoding.d.ts.map +1 -0
- package/dist/3-protocol/4-graffiti.d.ts +79 -0
- package/dist/3-protocol/4-graffiti.d.ts.map +1 -0
- package/dist/3-protocol/login-dialog.html.d.ts +2 -0
- package/dist/3-protocol/login-dialog.html.d.ts.map +1 -0
- package/dist/browser/ajv-QBSREQSI.js +9 -0
- package/dist/browser/ajv-QBSREQSI.js.map +7 -0
- package/dist/browser/build-BXWPS7VK.js +2 -0
- package/dist/browser/build-BXWPS7VK.js.map +7 -0
- package/dist/browser/chunk-RFBBAUMM.js +2 -0
- package/dist/browser/chunk-RFBBAUMM.js.map +7 -0
- package/dist/browser/graffiti-KV3G3O72-URO7SJIJ.js +2 -0
- package/dist/browser/graffiti-KV3G3O72-URO7SJIJ.js.map +7 -0
- package/dist/browser/index.js +16 -0
- package/dist/browser/index.js.map +7 -0
- package/dist/browser/login-dialog.html-XUWYDNNI.js +44 -0
- package/dist/browser/login-dialog.html-XUWYDNNI.js.map +7 -0
- package/dist/browser/rock-salt-LI7DAH66-KPFEBIBO.js +2 -0
- package/dist/browser/rock-salt-LI7DAH66-KPFEBIBO.js.map +7 -0
- package/dist/browser/style-YUTCEBZV-RWYJV575.js +287 -0
- package/dist/browser/style-YUTCEBZV-RWYJV575.js.map +7 -0
- package/dist/cjs/1-services/1-authorization.js +317 -0
- package/dist/cjs/1-services/1-authorization.js.map +7 -0
- package/dist/cjs/1-services/2-dids-tests.js +44 -0
- package/dist/cjs/1-services/2-dids-tests.js.map +7 -0
- package/dist/cjs/1-services/2-dids.js +47 -0
- package/dist/cjs/1-services/2-dids.js.map +7 -0
- package/dist/cjs/1-services/3-storage-buckets-tests.js +123 -0
- package/dist/cjs/1-services/3-storage-buckets-tests.js.map +7 -0
- package/dist/cjs/1-services/3-storage-buckets.js +148 -0
- package/dist/cjs/1-services/3-storage-buckets.js.map +7 -0
- package/dist/cjs/1-services/4-inboxes-tests.js +145 -0
- package/dist/cjs/1-services/4-inboxes-tests.js.map +7 -0
- package/dist/cjs/1-services/4-inboxes.js +539 -0
- package/dist/cjs/1-services/4-inboxes.js.map +7 -0
- package/dist/cjs/1-services/utilities.js +75 -0
- package/dist/cjs/1-services/utilities.js.map +7 -0
- package/dist/cjs/2-primitives/1-string-encoding-tests.js +50 -0
- package/dist/cjs/2-primitives/1-string-encoding-tests.js.map +7 -0
- package/dist/cjs/2-primitives/1-string-encoding.js +46 -0
- package/dist/cjs/2-primitives/1-string-encoding.js.map +7 -0
- package/dist/cjs/2-primitives/2-content-addresses-tests.js +62 -0
- package/dist/cjs/2-primitives/2-content-addresses-tests.js.map +7 -0
- package/dist/cjs/2-primitives/2-content-addresses.js +53 -0
- package/dist/cjs/2-primitives/2-content-addresses.js.map +7 -0
- package/dist/cjs/2-primitives/3-channel-attestations-tests.js +130 -0
- package/dist/cjs/2-primitives/3-channel-attestations-tests.js.map +7 -0
- package/dist/cjs/2-primitives/3-channel-attestations.js +84 -0
- package/dist/cjs/2-primitives/3-channel-attestations.js.map +7 -0
- package/dist/cjs/2-primitives/4-allowed-attestations-tests.js +96 -0
- package/dist/cjs/2-primitives/4-allowed-attestations-tests.js.map +7 -0
- package/dist/cjs/2-primitives/4-allowed-attestations.js +68 -0
- package/dist/cjs/2-primitives/4-allowed-attestations.js.map +7 -0
- package/dist/cjs/3-protocol/1-sessions.js +473 -0
- package/dist/cjs/3-protocol/1-sessions.js.map +7 -0
- package/dist/cjs/3-protocol/2-handles-tests.js +39 -0
- package/dist/cjs/3-protocol/2-handles-tests.js.map +7 -0
- package/dist/cjs/3-protocol/2-handles.js +65 -0
- package/dist/cjs/3-protocol/2-handles.js.map +7 -0
- package/dist/cjs/3-protocol/3-object-encoding-tests.js +253 -0
- package/dist/cjs/3-protocol/3-object-encoding-tests.js.map +7 -0
- package/dist/cjs/3-protocol/3-object-encoding.js +287 -0
- package/dist/cjs/3-protocol/3-object-encoding.js.map +7 -0
- package/dist/cjs/3-protocol/4-graffiti.js +937 -0
- package/dist/cjs/3-protocol/4-graffiti.js.map +7 -0
- package/dist/cjs/3-protocol/login-dialog.html.js +67 -0
- package/dist/cjs/3-protocol/login-dialog.html.js.map +7 -0
- package/dist/cjs/index.js +32 -0
- package/dist/cjs/index.js.map +7 -0
- package/dist/cjs/index.spec.js +130 -0
- package/dist/cjs/index.spec.js.map +7 -0
- package/dist/esm/1-services/1-authorization.js +304 -0
- package/dist/esm/1-services/1-authorization.js.map +7 -0
- package/dist/esm/1-services/2-dids-tests.js +24 -0
- package/dist/esm/1-services/2-dids-tests.js.map +7 -0
- package/dist/esm/1-services/2-dids.js +27 -0
- package/dist/esm/1-services/2-dids.js.map +7 -0
- package/dist/esm/1-services/3-storage-buckets-tests.js +103 -0
- package/dist/esm/1-services/3-storage-buckets-tests.js.map +7 -0
- package/dist/esm/1-services/3-storage-buckets.js +132 -0
- package/dist/esm/1-services/3-storage-buckets.js.map +7 -0
- package/dist/esm/1-services/4-inboxes-tests.js +125 -0
- package/dist/esm/1-services/4-inboxes-tests.js.map +7 -0
- package/dist/esm/1-services/4-inboxes.js +533 -0
- package/dist/esm/1-services/4-inboxes.js.map +7 -0
- package/dist/esm/1-services/utilities.js +60 -0
- package/dist/esm/1-services/utilities.js.map +7 -0
- package/dist/esm/2-primitives/1-string-encoding-tests.js +33 -0
- package/dist/esm/2-primitives/1-string-encoding-tests.js.map +7 -0
- package/dist/esm/2-primitives/1-string-encoding.js +26 -0
- package/dist/esm/2-primitives/1-string-encoding.js.map +7 -0
- package/dist/esm/2-primitives/2-content-addresses-tests.js +45 -0
- package/dist/esm/2-primitives/2-content-addresses-tests.js.map +7 -0
- package/dist/esm/2-primitives/2-content-addresses.js +33 -0
- package/dist/esm/2-primitives/2-content-addresses.js.map +7 -0
- package/dist/esm/2-primitives/3-channel-attestations-tests.js +116 -0
- package/dist/esm/2-primitives/3-channel-attestations-tests.js.map +7 -0
- package/dist/esm/2-primitives/3-channel-attestations.js +69 -0
- package/dist/esm/2-primitives/3-channel-attestations.js.map +7 -0
- package/dist/esm/2-primitives/4-allowed-attestations-tests.js +82 -0
- package/dist/esm/2-primitives/4-allowed-attestations-tests.js.map +7 -0
- package/dist/esm/2-primitives/4-allowed-attestations.js +51 -0
- package/dist/esm/2-primitives/4-allowed-attestations.js.map +7 -0
- package/dist/esm/3-protocol/1-sessions.js +465 -0
- package/dist/esm/3-protocol/1-sessions.js.map +7 -0
- package/dist/esm/3-protocol/2-handles-tests.js +19 -0
- package/dist/esm/3-protocol/2-handles-tests.js.map +7 -0
- package/dist/esm/3-protocol/2-handles.js +45 -0
- package/dist/esm/3-protocol/2-handles.js.map +7 -0
- package/dist/esm/3-protocol/3-object-encoding-tests.js +248 -0
- package/dist/esm/3-protocol/3-object-encoding-tests.js.map +7 -0
- package/dist/esm/3-protocol/3-object-encoding.js +280 -0
- package/dist/esm/3-protocol/3-object-encoding.js.map +7 -0
- package/dist/esm/3-protocol/4-graffiti.js +957 -0
- package/dist/esm/3-protocol/4-graffiti.js.map +7 -0
- package/dist/esm/3-protocol/login-dialog.html.js +47 -0
- package/dist/esm/3-protocol/login-dialog.html.js.map +7 -0
- package/dist/esm/index.js +14 -0
- package/dist/esm/index.js.map +7 -0
- package/dist/esm/index.spec.js +133 -0
- package/dist/esm/index.spec.js.map +7 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.spec.d.ts +2 -0
- package/dist/index.spec.d.ts.map +1 -0
- package/package.json +62 -0
- package/src/1-services/1-authorization.ts +399 -0
- package/src/1-services/2-dids-tests.ts +24 -0
- package/src/1-services/2-dids.ts +30 -0
- package/src/1-services/3-storage-buckets-tests.ts +121 -0
- package/src/1-services/3-storage-buckets.ts +183 -0
- package/src/1-services/4-inboxes-tests.ts +154 -0
- package/src/1-services/4-inboxes.ts +722 -0
- package/src/1-services/utilities.ts +65 -0
- package/src/2-primitives/1-string-encoding-tests.ts +33 -0
- package/src/2-primitives/1-string-encoding.ts +33 -0
- package/src/2-primitives/2-content-addresses-tests.ts +46 -0
- package/src/2-primitives/2-content-addresses.ts +42 -0
- package/src/2-primitives/3-channel-attestations-tests.ts +125 -0
- package/src/2-primitives/3-channel-attestations.ts +95 -0
- package/src/2-primitives/4-allowed-attestations-tests.ts +86 -0
- package/src/2-primitives/4-allowed-attestations.ts +69 -0
- package/src/3-protocol/1-sessions.ts +601 -0
- package/src/3-protocol/2-handles-tests.ts +17 -0
- package/src/3-protocol/2-handles.ts +60 -0
- package/src/3-protocol/3-object-encoding-tests.ts +269 -0
- package/src/3-protocol/3-object-encoding.ts +396 -0
- package/src/3-protocol/4-graffiti.ts +1265 -0
- package/src/3-protocol/login-dialog.html.ts +43 -0
- package/src/index.spec.ts +158 -0
- package/src/index.ts +16 -0
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
import"./chunk-RFBBAUMM.js";var t=`.graffiti-modal {
|
|
2
|
+
--back: rgb(26, 26, 26, 0.85);
|
|
3
|
+
--halfback: rgba(80, 80, 80, 0.85);
|
|
4
|
+
--halfback2: rgba(26, 26, 26, 0.85);
|
|
5
|
+
--hover: rgba(202, 122, 204, 0.3);
|
|
6
|
+
--frontfaded: rgba(190, 190, 190);
|
|
7
|
+
--front: rgba(240, 240, 240);
|
|
8
|
+
--emph: rgb(202, 122, 204);
|
|
9
|
+
--blurpix: 3px;
|
|
10
|
+
border-color: var(--emph);
|
|
11
|
+
box-sizing: border-box;
|
|
12
|
+
border-width: 2px;
|
|
13
|
+
padding: 0;
|
|
14
|
+
margin: 0;
|
|
15
|
+
border-radius: 1rem;
|
|
16
|
+
box-shadow: 0 0 2rem black;
|
|
17
|
+
overflow: hidden;
|
|
18
|
+
opacity: 0;
|
|
19
|
+
transition: opacity 0.3s;
|
|
20
|
+
pointer-events: none;
|
|
21
|
+
display: block;
|
|
22
|
+
min-width: 95dvw;
|
|
23
|
+
min-height: 95dvh;
|
|
24
|
+
height: 95dvh;
|
|
25
|
+
top: 50%;
|
|
26
|
+
left: 50%;
|
|
27
|
+
transform: translate(-50%, -50%);
|
|
28
|
+
display: flex;
|
|
29
|
+
flex-direction: column;
|
|
30
|
+
justify-content: flex-start;
|
|
31
|
+
align-items: center;
|
|
32
|
+
font-family:
|
|
33
|
+
Inter,
|
|
34
|
+
-apple-system,
|
|
35
|
+
BlinkMacSystemFont,
|
|
36
|
+
"Segoe UI",
|
|
37
|
+
Roboto,
|
|
38
|
+
Oxygen,
|
|
39
|
+
Ubuntu,
|
|
40
|
+
Cantarell,
|
|
41
|
+
"Fira Sans",
|
|
42
|
+
"Droid Sans",
|
|
43
|
+
"Helvetica Neue",
|
|
44
|
+
sans-serif;
|
|
45
|
+
color: var(--front);
|
|
46
|
+
font-size: 150%;
|
|
47
|
+
|
|
48
|
+
* {
|
|
49
|
+
box-sizing: border-box;
|
|
50
|
+
padding: 0;
|
|
51
|
+
margin: 0;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
::selection {
|
|
55
|
+
background: rgba(202, 122, 204, 0.3);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
:focus {
|
|
59
|
+
outline: 2px solid var(--front);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
header {
|
|
63
|
+
width: 100%;
|
|
64
|
+
display: flex;
|
|
65
|
+
justify-content: flex-end;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
main {
|
|
69
|
+
flex: 1;
|
|
70
|
+
max-width: 600px;
|
|
71
|
+
width: 100%;
|
|
72
|
+
gap: 2em;
|
|
73
|
+
padding-top: 4dvh;
|
|
74
|
+
padding-bottom: 4dvh;
|
|
75
|
+
margin-top: 4dvh;
|
|
76
|
+
margin-bottom: 4dvh;
|
|
77
|
+
margin-left: 4dvw;
|
|
78
|
+
margin-right: 4dvw;
|
|
79
|
+
padding-left: 4dvw;
|
|
80
|
+
padding-right: 4dvw;
|
|
81
|
+
background: var(--back);
|
|
82
|
+
border-radius: 1rem;
|
|
83
|
+
display: flex;
|
|
84
|
+
flex-direction: column;
|
|
85
|
+
overflow-y: auto;
|
|
86
|
+
scrollbar-color: var(--emph) rgba(0, 0, 0, 0);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
ul {
|
|
90
|
+
list-style-type: none;
|
|
91
|
+
display: flex;
|
|
92
|
+
flex-direction: column;
|
|
93
|
+
gap: 0.5em;
|
|
94
|
+
align-items: stretch;
|
|
95
|
+
justify-content: stretch;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
aside {
|
|
99
|
+
color: var(--frontfaded);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.secondary,
|
|
103
|
+
a:not([type="button"]) {
|
|
104
|
+
color: var(--emph);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
h1 {
|
|
108
|
+
font-size: 120%;
|
|
109
|
+
font-family:
|
|
110
|
+
Rock Salt,
|
|
111
|
+
cursive,
|
|
112
|
+
sans-serif;
|
|
113
|
+
letter-spacing: 0.1em;
|
|
114
|
+
text-align: center;
|
|
115
|
+
color: var(--front);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
h1 a:not([type="button"]) {
|
|
119
|
+
color: inherit;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
h1 a:hover {
|
|
123
|
+
background: none;
|
|
124
|
+
color: inherit;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
button,
|
|
128
|
+
input[type="submit"],
|
|
129
|
+
input[type="text"],
|
|
130
|
+
a[type="button"] {
|
|
131
|
+
font-size: inherit;
|
|
132
|
+
width: 100%;
|
|
133
|
+
text-align: center;
|
|
134
|
+
display: block;
|
|
135
|
+
border-radius: 1rem;
|
|
136
|
+
border: 2px solid var(--emph);
|
|
137
|
+
padding: 1em;
|
|
138
|
+
padding-top: 0.5em;
|
|
139
|
+
padding-bottom: 0.5em;
|
|
140
|
+
transition: 0.1s;
|
|
141
|
+
text-overflow: ellipsis;
|
|
142
|
+
background: none;
|
|
143
|
+
line-height: 1.2em;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
input[type="text"] {
|
|
147
|
+
font-weight: 500;
|
|
148
|
+
background: var(--front);
|
|
149
|
+
text-align: left;
|
|
150
|
+
color: black;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
header button {
|
|
154
|
+
border-radius: 0 0 0 1rem;
|
|
155
|
+
border-right: none;
|
|
156
|
+
border-top: none;
|
|
157
|
+
background-color: var(--halfback2);
|
|
158
|
+
width: fit-content;
|
|
159
|
+
position: relative;
|
|
160
|
+
overflow: hidden;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
header button::before {
|
|
164
|
+
z-index: -1;
|
|
165
|
+
top: 0;
|
|
166
|
+
left: 0;
|
|
167
|
+
height: 100%;
|
|
168
|
+
position: absolute;
|
|
169
|
+
width: 100%;
|
|
170
|
+
content: "";
|
|
171
|
+
background-color: var(--back);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
@media (max-width: 600px) {
|
|
175
|
+
main {
|
|
176
|
+
border-radius: 0;
|
|
177
|
+
margin: auto;
|
|
178
|
+
overflow: auto;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
header button {
|
|
182
|
+
border-radius: 0;
|
|
183
|
+
border-left: none;
|
|
184
|
+
width: 100%;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
html {
|
|
188
|
+
justify-content: safe center;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
a {
|
|
193
|
+
text-decoration: none;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
:is(button, ul a, input[type="submit"]):hover {
|
|
197
|
+
cursor: pointer;
|
|
198
|
+
background: var(--hover);
|
|
199
|
+
color: var(--front);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
a:hover {
|
|
203
|
+
text-decoration: underline;
|
|
204
|
+
cursor: pointer;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
form {
|
|
208
|
+
display: flex;
|
|
209
|
+
flex-direction: column;
|
|
210
|
+
justify-content: flex-start;
|
|
211
|
+
align-items: stretch;
|
|
212
|
+
gap: 0.5em;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
iframe {
|
|
216
|
+
width: 100%;
|
|
217
|
+
height: 100%;
|
|
218
|
+
border: none;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
:is(button, a[type="button"], input[type="submit"]).secondary {
|
|
222
|
+
color: rgb(244, 213, 244);
|
|
223
|
+
background: rgba(26, 26, 26, 0.6);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
:is(button, a[type="button"], input[type="submit"]):not(.secondary) {
|
|
227
|
+
background: var(--hover);
|
|
228
|
+
color: white;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
:is(button, a[type="button"], input[type="submit"]):hover {
|
|
232
|
+
background: rgba(202, 122, 204, 0.6);
|
|
233
|
+
color: white;
|
|
234
|
+
text-decoration: none;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
h3 {
|
|
238
|
+
color: var(--frontfaded);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
h2 {
|
|
242
|
+
text-align: center;
|
|
243
|
+
font-weight: 500;
|
|
244
|
+
font-size: 150%;
|
|
245
|
+
background: var(--halfback2);
|
|
246
|
+
padding: 1rem;
|
|
247
|
+
border-radius: 1rem;
|
|
248
|
+
border: 1px solid var(--frontfaded);
|
|
249
|
+
color: var(--front);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
main > div {
|
|
253
|
+
display: flex;
|
|
254
|
+
flex-direction: column;
|
|
255
|
+
justify-content: center;
|
|
256
|
+
align-items: stretch;
|
|
257
|
+
gap: 0.5rem;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
.graffiti-modal[open] {
|
|
262
|
+
pointer-events: inherit;
|
|
263
|
+
opacity: 1;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
.graffiti-modal::backdrop {
|
|
267
|
+
background-color: black;
|
|
268
|
+
opacity: 0.5;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
.graffiti-modal::before {
|
|
272
|
+
content: "";
|
|
273
|
+
position: fixed;
|
|
274
|
+
left: 0;
|
|
275
|
+
right: 0;
|
|
276
|
+
z-index: -1;
|
|
277
|
+
background-image: url(graffiti.jpg);
|
|
278
|
+
background-size: cover;
|
|
279
|
+
background-repeat: no-repeat;
|
|
280
|
+
background-position: 50% 50%;
|
|
281
|
+
height: calc(100% + 2 * var(--blurpix));
|
|
282
|
+
width: calc(100% + 2 * var(--blurpix));
|
|
283
|
+
filter: blur(var(--blurpix));
|
|
284
|
+
margin: calc(-1 * var(--blurpix));
|
|
285
|
+
}
|
|
286
|
+
`;export{t as default};
|
|
287
|
+
//# sourceMappingURL=style-YUTCEBZV-RWYJV575.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../node_modules/@graffiti-garden/modal/src/style.css"],
|
|
4
|
+
"sourcesContent": [".graffiti-modal {\n --back: rgb(26, 26, 26, 0.85);\n --halfback: rgba(80, 80, 80, 0.85);\n --halfback2: rgba(26, 26, 26, 0.85);\n --hover: rgba(202, 122, 204, 0.3);\n --frontfaded: rgba(190, 190, 190);\n --front: rgba(240, 240, 240);\n --emph: rgb(202, 122, 204);\n --blurpix: 3px;\n border-color: var(--emph);\n box-sizing: border-box;\n border-width: 2px;\n padding: 0;\n margin: 0;\n border-radius: 1rem;\n box-shadow: 0 0 2rem black;\n overflow: hidden;\n opacity: 0;\n transition: opacity 0.3s;\n pointer-events: none;\n display: block;\n min-width: 95dvw;\n min-height: 95dvh;\n height: 95dvh;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n display: flex;\n flex-direction: column;\n justify-content: flex-start;\n align-items: center;\n font-family:\n Inter,\n -apple-system,\n BlinkMacSystemFont,\n \"Segoe UI\",\n Roboto,\n Oxygen,\n Ubuntu,\n Cantarell,\n \"Fira Sans\",\n \"Droid Sans\",\n \"Helvetica Neue\",\n sans-serif;\n color: var(--front);\n font-size: 150%;\n\n * {\n box-sizing: border-box;\n padding: 0;\n margin: 0;\n }\n\n ::selection {\n background: rgba(202, 122, 204, 0.3);\n }\n\n :focus {\n outline: 2px solid var(--front);\n }\n\n header {\n width: 100%;\n display: flex;\n justify-content: flex-end;\n }\n\n main {\n flex: 1;\n max-width: 600px;\n width: 100%;\n gap: 2em;\n padding-top: 4dvh;\n padding-bottom: 4dvh;\n margin-top: 4dvh;\n margin-bottom: 4dvh;\n margin-left: 4dvw;\n margin-right: 4dvw;\n padding-left: 4dvw;\n padding-right: 4dvw;\n background: var(--back);\n border-radius: 1rem;\n display: flex;\n flex-direction: column;\n overflow-y: auto;\n scrollbar-color: var(--emph) rgba(0, 0, 0, 0);\n }\n\n ul {\n list-style-type: none;\n display: flex;\n flex-direction: column;\n gap: 0.5em;\n align-items: stretch;\n justify-content: stretch;\n }\n\n aside {\n color: var(--frontfaded);\n }\n\n .secondary,\n a:not([type=\"button\"]) {\n color: var(--emph);\n }\n\n h1 {\n font-size: 120%;\n font-family:\n Rock Salt,\n cursive,\n sans-serif;\n letter-spacing: 0.1em;\n text-align: center;\n color: var(--front);\n }\n\n h1 a:not([type=\"button\"]) {\n color: inherit;\n }\n\n h1 a:hover {\n background: none;\n color: inherit;\n }\n\n button,\n input[type=\"submit\"],\n input[type=\"text\"],\n a[type=\"button\"] {\n font-size: inherit;\n width: 100%;\n text-align: center;\n display: block;\n border-radius: 1rem;\n border: 2px solid var(--emph);\n padding: 1em;\n padding-top: 0.5em;\n padding-bottom: 0.5em;\n transition: 0.1s;\n text-overflow: ellipsis;\n background: none;\n line-height: 1.2em;\n }\n\n input[type=\"text\"] {\n font-weight: 500;\n background: var(--front);\n text-align: left;\n color: black;\n }\n\n header button {\n border-radius: 0 0 0 1rem;\n border-right: none;\n border-top: none;\n background-color: var(--halfback2);\n width: fit-content;\n position: relative;\n overflow: hidden;\n }\n\n header button::before {\n z-index: -1;\n top: 0;\n left: 0;\n height: 100%;\n position: absolute;\n width: 100%;\n content: \"\";\n background-color: var(--back);\n }\n\n @media (max-width: 600px) {\n main {\n border-radius: 0;\n margin: auto;\n overflow: auto;\n }\n\n header button {\n border-radius: 0;\n border-left: none;\n width: 100%;\n }\n\n html {\n justify-content: safe center;\n }\n }\n\n a {\n text-decoration: none;\n }\n\n :is(button, ul a, input[type=\"submit\"]):hover {\n cursor: pointer;\n background: var(--hover);\n color: var(--front);\n }\n\n a:hover {\n text-decoration: underline;\n cursor: pointer;\n }\n\n form {\n display: flex;\n flex-direction: column;\n justify-content: flex-start;\n align-items: stretch;\n gap: 0.5em;\n }\n\n iframe {\n width: 100%;\n height: 100%;\n border: none;\n }\n\n :is(button, a[type=\"button\"], input[type=\"submit\"]).secondary {\n color: rgb(244, 213, 244);\n background: rgba(26, 26, 26, 0.6);\n }\n\n :is(button, a[type=\"button\"], input[type=\"submit\"]):not(.secondary) {\n background: var(--hover);\n color: white;\n }\n\n :is(button, a[type=\"button\"], input[type=\"submit\"]):hover {\n background: rgba(202, 122, 204, 0.6);\n color: white;\n text-decoration: none;\n }\n\n h3 {\n color: var(--frontfaded);\n }\n\n h2 {\n text-align: center;\n font-weight: 500;\n font-size: 150%;\n background: var(--halfback2);\n padding: 1rem;\n border-radius: 1rem;\n border: 1px solid var(--frontfaded);\n color: var(--front);\n }\n\n main > div {\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: stretch;\n gap: 0.5rem;\n }\n}\n\n.graffiti-modal[open] {\n pointer-events: inherit;\n opacity: 1;\n}\n\n.graffiti-modal::backdrop {\n background-color: black;\n opacity: 0.5;\n}\n\n.graffiti-modal::before {\n content: \"\";\n position: fixed;\n left: 0;\n right: 0;\n z-index: -1;\n background-image: url(graffiti.jpg);\n background-size: cover;\n background-repeat: no-repeat;\n background-position: 50% 50%;\n height: calc(100% + 2 * var(--blurpix));\n width: calc(100% + 2 * var(--blurpix));\n filter: blur(var(--blurpix));\n margin: calc(-1 * var(--blurpix));\n}\n"],
|
|
5
|
+
"mappings": "4BAAA,IAAAA,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;",
|
|
6
|
+
"names": ["style_default"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var authorization_exports = {};
|
|
30
|
+
__export(authorization_exports, {
|
|
31
|
+
Authorization: () => Authorization,
|
|
32
|
+
InitializedEventDetailSchema: () => InitializedEventDetailSchema,
|
|
33
|
+
LoginEventDetailSchema: () => LoginEventDetailSchema,
|
|
34
|
+
LogoutEventDetailSchema: () => LogoutEventDetailSchema
|
|
35
|
+
});
|
|
36
|
+
module.exports = __toCommonJS(authorization_exports);
|
|
37
|
+
var import_openid_client = require("openid-client");
|
|
38
|
+
var import_mini = require("zod/mini");
|
|
39
|
+
const AUTHORIZATION_ENDPOINT_METHOD_PREFIX_OAUTH2 = "oauth2:";
|
|
40
|
+
const LOCAL_STORAGE_OAUTH2_KEY = "graffiti-auth-oauth2-data";
|
|
41
|
+
class Authorization {
|
|
42
|
+
eventTarget = new EventTarget();
|
|
43
|
+
constructor() {
|
|
44
|
+
const oauthPromise = this.completeOauth();
|
|
45
|
+
(async () => {
|
|
46
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
47
|
+
await oauthPromise;
|
|
48
|
+
const initializedEvent = new CustomEvent("initialized");
|
|
49
|
+
this.eventTarget.dispatchEvent(initializedEvent);
|
|
50
|
+
})();
|
|
51
|
+
}
|
|
52
|
+
async login(...args) {
|
|
53
|
+
try {
|
|
54
|
+
await this.login_(...args);
|
|
55
|
+
} catch (e) {
|
|
56
|
+
const error = e instanceof Error ? e : new Error("Unknown error");
|
|
57
|
+
const detail = { loginId: args[1], error };
|
|
58
|
+
this.eventTarget.dispatchEvent(new CustomEvent("login", { detail }));
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
async login_(authorizationEndpoint, loginId, serviceEndpoints) {
|
|
62
|
+
const configuration = await this.getAuthorizationConfiguration(
|
|
63
|
+
authorizationEndpoint
|
|
64
|
+
);
|
|
65
|
+
const scope = serviceEndpoints.map(encodeURIComponent).join(" ");
|
|
66
|
+
const state = (0, import_openid_client.randomState)();
|
|
67
|
+
let redirectUri;
|
|
68
|
+
let waitForCallback = void 0;
|
|
69
|
+
if (typeof window !== "undefined") {
|
|
70
|
+
redirectUri = window.location.href;
|
|
71
|
+
const data = {
|
|
72
|
+
loginId,
|
|
73
|
+
redirectUri,
|
|
74
|
+
authorizationEndpoint,
|
|
75
|
+
state,
|
|
76
|
+
serviceEndpoints
|
|
77
|
+
};
|
|
78
|
+
window.localStorage.setItem(
|
|
79
|
+
LOCAL_STORAGE_OAUTH2_KEY,
|
|
80
|
+
JSON.stringify(data)
|
|
81
|
+
);
|
|
82
|
+
} else {
|
|
83
|
+
const http = await import("node:http").catch((e) => {
|
|
84
|
+
throw new Error(
|
|
85
|
+
"Unrecognized environment: cannot find window or node:http"
|
|
86
|
+
);
|
|
87
|
+
});
|
|
88
|
+
const server = http.createServer();
|
|
89
|
+
try {
|
|
90
|
+
await new Promise((resolve, reject) => {
|
|
91
|
+
server.once("error", reject);
|
|
92
|
+
server.listen(0, "::1", resolve);
|
|
93
|
+
});
|
|
94
|
+
} catch (e) {
|
|
95
|
+
try {
|
|
96
|
+
server.close();
|
|
97
|
+
} catch {
|
|
98
|
+
}
|
|
99
|
+
throw new Error("Failed to start local oauth callback server.");
|
|
100
|
+
}
|
|
101
|
+
const address = server.address();
|
|
102
|
+
if (!address) {
|
|
103
|
+
try {
|
|
104
|
+
server.close();
|
|
105
|
+
} catch {
|
|
106
|
+
}
|
|
107
|
+
throw new Error("Failed to get local oauth callback server address.");
|
|
108
|
+
}
|
|
109
|
+
redirectUri = typeof address === "string" ? `http://${address}` : `http://${address.family === "IPv6" ? `[${address.address}]` : address.address}:${address.port}`;
|
|
110
|
+
waitForCallback = new Promise((resolve, reject) => {
|
|
111
|
+
const timeout = setTimeout(
|
|
112
|
+
() => {
|
|
113
|
+
try {
|
|
114
|
+
server.close();
|
|
115
|
+
} catch {
|
|
116
|
+
}
|
|
117
|
+
reject("Oauth callback timed out.");
|
|
118
|
+
},
|
|
119
|
+
5 * 60 * 1e3
|
|
120
|
+
// 5 minutes
|
|
121
|
+
);
|
|
122
|
+
const sockets = /* @__PURE__ */ new Set();
|
|
123
|
+
server.on("connection", (socket) => {
|
|
124
|
+
sockets.add(socket);
|
|
125
|
+
socket.on("close", () => {
|
|
126
|
+
sockets.delete(socket);
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
const onRequest = async (req, res) => {
|
|
130
|
+
try {
|
|
131
|
+
const callbackUrl = new URL(req.url ?? "/", redirectUri);
|
|
132
|
+
await this.onCallbackUrl({
|
|
133
|
+
loginId,
|
|
134
|
+
callbackUrl,
|
|
135
|
+
configuration,
|
|
136
|
+
expectedState: state,
|
|
137
|
+
serviceEndpoints
|
|
138
|
+
});
|
|
139
|
+
res.statusCode = 200;
|
|
140
|
+
res.setHeader("Content-Type", "text/plain");
|
|
141
|
+
res.end("You may now close this window.");
|
|
142
|
+
} catch (e) {
|
|
143
|
+
res.statusCode = 500;
|
|
144
|
+
res.setHeader("Content-Type", "text/plain");
|
|
145
|
+
res.end("Error processing OAuth callback.");
|
|
146
|
+
throw e;
|
|
147
|
+
} finally {
|
|
148
|
+
clearTimeout(timeout);
|
|
149
|
+
server.off("request", onRequest);
|
|
150
|
+
for (const socket of sockets) {
|
|
151
|
+
socket.destroy();
|
|
152
|
+
}
|
|
153
|
+
server.close(() => resolve());
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
server.on("request", onRequest);
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
const redirectUriStripped = new URL(redirectUri);
|
|
160
|
+
redirectUriStripped.hash = "";
|
|
161
|
+
redirectUriStripped.search = "";
|
|
162
|
+
const redirectTo = (0, import_openid_client.buildAuthorizationUrl)(configuration, {
|
|
163
|
+
scope,
|
|
164
|
+
redirect_uri: redirectUriStripped.toString(),
|
|
165
|
+
state
|
|
166
|
+
});
|
|
167
|
+
if (typeof window !== "undefined") {
|
|
168
|
+
window.location.href = redirectTo.toString();
|
|
169
|
+
} else {
|
|
170
|
+
console.log("Please open the following URL in your browser:");
|
|
171
|
+
console.log(redirectTo.toString());
|
|
172
|
+
await waitForCallback;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
completeOauth() {
|
|
176
|
+
if (typeof window === "undefined") return;
|
|
177
|
+
const data = window.localStorage.getItem(LOCAL_STORAGE_OAUTH2_KEY);
|
|
178
|
+
if (!data) return;
|
|
179
|
+
let json;
|
|
180
|
+
try {
|
|
181
|
+
json = JSON.parse(data);
|
|
182
|
+
} catch {
|
|
183
|
+
console.error("Invalid OAuth2 login data in local storage.");
|
|
184
|
+
window.localStorage.removeItem(LOCAL_STORAGE_OAUTH2_KEY);
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
const parseResult = OAuth2LoginDataSchema.safeParse(json);
|
|
188
|
+
if (!parseResult.success) {
|
|
189
|
+
console.error(
|
|
190
|
+
"Invalid OAuth2 login data structure in local storage.",
|
|
191
|
+
parseResult.error
|
|
192
|
+
);
|
|
193
|
+
window.localStorage.removeItem(LOCAL_STORAGE_OAUTH2_KEY);
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
const {
|
|
197
|
+
loginId,
|
|
198
|
+
redirectUri,
|
|
199
|
+
authorizationEndpoint,
|
|
200
|
+
state,
|
|
201
|
+
serviceEndpoints
|
|
202
|
+
} = parseResult.data;
|
|
203
|
+
try {
|
|
204
|
+
const expectedUrl = new URL(redirectUri);
|
|
205
|
+
const callbackUrl = new URL(window.location.href);
|
|
206
|
+
if (expectedUrl.pathname !== callbackUrl.pathname) return;
|
|
207
|
+
const params = callbackUrl.searchParams;
|
|
208
|
+
if (!params.has("code") && !params.has("error")) return;
|
|
209
|
+
window.history.replaceState({}, document.title, expectedUrl.toString());
|
|
210
|
+
window.localStorage.removeItem(LOCAL_STORAGE_OAUTH2_KEY);
|
|
211
|
+
return new Promise((resolve) => setTimeout(resolve, 0)).then(() => this.getAuthorizationConfiguration(authorizationEndpoint)).then(
|
|
212
|
+
(configuration) => this.onCallbackUrl({
|
|
213
|
+
loginId,
|
|
214
|
+
callbackUrl,
|
|
215
|
+
configuration,
|
|
216
|
+
expectedState: state,
|
|
217
|
+
serviceEndpoints
|
|
218
|
+
})
|
|
219
|
+
).catch((e) => {
|
|
220
|
+
const error = e instanceof Error ? e : new Error("Unknown error");
|
|
221
|
+
const detail = { loginId, error };
|
|
222
|
+
this.eventTarget.dispatchEvent(new CustomEvent("login", { detail }));
|
|
223
|
+
});
|
|
224
|
+
} catch (e) {
|
|
225
|
+
console.error(e);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
async onCallbackUrl(args) {
|
|
229
|
+
const {
|
|
230
|
+
loginId,
|
|
231
|
+
callbackUrl,
|
|
232
|
+
configuration,
|
|
233
|
+
expectedState,
|
|
234
|
+
serviceEndpoints
|
|
235
|
+
} = args;
|
|
236
|
+
const response = await (0, import_openid_client.authorizationCodeGrant)(configuration, callbackUrl, {
|
|
237
|
+
expectedState
|
|
238
|
+
});
|
|
239
|
+
const token = response.access_token;
|
|
240
|
+
const scope = response.scope;
|
|
241
|
+
const grantedEndpoints = scope?.split(" ").map(decodeURIComponent) || serviceEndpoints;
|
|
242
|
+
if (!serviceEndpoints.every((endpoint) => grantedEndpoints.includes(endpoint))) {
|
|
243
|
+
throw new Error("Not all requested service endpoints were granted.");
|
|
244
|
+
}
|
|
245
|
+
const loginEvent = new CustomEvent("login", {
|
|
246
|
+
detail: {
|
|
247
|
+
loginId,
|
|
248
|
+
token
|
|
249
|
+
}
|
|
250
|
+
});
|
|
251
|
+
this.eventTarget.dispatchEvent(loginEvent);
|
|
252
|
+
}
|
|
253
|
+
async logout(authorizationEndpoint, logoutId, token) {
|
|
254
|
+
try {
|
|
255
|
+
await this.logout_(authorizationEndpoint, logoutId, token);
|
|
256
|
+
} catch (e) {
|
|
257
|
+
const error = e instanceof Error ? e : new Error("Unknown error");
|
|
258
|
+
const detail = { logoutId, error };
|
|
259
|
+
this.eventTarget.dispatchEvent(new CustomEvent("logout", { detail }));
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
async logout_(authorizationEndpoint, logoutId, token) {
|
|
263
|
+
const configuration = await this.getAuthorizationConfiguration(
|
|
264
|
+
authorizationEndpoint
|
|
265
|
+
);
|
|
266
|
+
await (0, import_openid_client.tokenRevocation)(configuration, token);
|
|
267
|
+
const detail = { logoutId };
|
|
268
|
+
this.eventTarget.dispatchEvent(new CustomEvent("logout", { detail }));
|
|
269
|
+
}
|
|
270
|
+
async getAuthorizationConfiguration(authorizationEndpoint) {
|
|
271
|
+
if (!authorizationEndpoint.startsWith(
|
|
272
|
+
AUTHORIZATION_ENDPOINT_METHOD_PREFIX_OAUTH2
|
|
273
|
+
)) {
|
|
274
|
+
throw new Error(
|
|
275
|
+
`Unrecognized authorization endpoint method: ${authorizationEndpoint}`
|
|
276
|
+
);
|
|
277
|
+
}
|
|
278
|
+
const issuer = authorizationEndpoint.slice(
|
|
279
|
+
AUTHORIZATION_ENDPOINT_METHOD_PREFIX_OAUTH2.length
|
|
280
|
+
);
|
|
281
|
+
let issuerUrl;
|
|
282
|
+
try {
|
|
283
|
+
issuerUrl = new URL(issuer);
|
|
284
|
+
} catch (e) {
|
|
285
|
+
throw new Error("Invalid issuer URL.");
|
|
286
|
+
}
|
|
287
|
+
return await (0, import_openid_client.discovery)(issuerUrl, "graffiti-client");
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
const LoginEventDetailSchema = (0, import_mini.intersection)(
|
|
291
|
+
(0, import_mini.object)({
|
|
292
|
+
loginId: (0, import_mini.string)()
|
|
293
|
+
}),
|
|
294
|
+
(0, import_mini.union)([
|
|
295
|
+
(0, import_mini.object)({ token: (0, import_mini.string)(), error: (0, import_mini.optional)((0, import_mini.undefined)()) }),
|
|
296
|
+
(0, import_mini.object)({ error: (0, import_mini.instanceof)(Error) })
|
|
297
|
+
])
|
|
298
|
+
);
|
|
299
|
+
const LogoutEventDetailSchema = (0, import_mini.object)({
|
|
300
|
+
logoutId: (0, import_mini.string)(),
|
|
301
|
+
error: (0, import_mini.optional)((0, import_mini.instanceof)(Error))
|
|
302
|
+
});
|
|
303
|
+
const InitializedEventDetailSchema = (0, import_mini.optional)(
|
|
304
|
+
(0, import_mini.nullable)(
|
|
305
|
+
(0, import_mini.object)({
|
|
306
|
+
error: (0, import_mini.optional)((0, import_mini.instanceof)(Error))
|
|
307
|
+
})
|
|
308
|
+
)
|
|
309
|
+
);
|
|
310
|
+
const OAuth2LoginDataSchema = (0, import_mini.object)({
|
|
311
|
+
loginId: (0, import_mini.string)(),
|
|
312
|
+
redirectUri: (0, import_mini.url)(),
|
|
313
|
+
authorizationEndpoint: (0, import_mini.url)(),
|
|
314
|
+
state: (0, import_mini.string)(),
|
|
315
|
+
serviceEndpoints: (0, import_mini.array)((0, import_mini.url)())
|
|
316
|
+
});
|
|
317
|
+
//# sourceMappingURL=1-authorization.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/1-services/1-authorization.ts"],
|
|
4
|
+
"sourcesContent": ["import {\n discovery,\n randomState,\n buildAuthorizationUrl,\n authorizationCodeGrant,\n tokenRevocation,\n} from \"openid-client\";\nimport {\n type infer as infer_,\n string,\n url,\n array,\n object,\n optional,\n nullable,\n instanceof as instanceof_,\n undefined as undefined_,\n intersection,\n union,\n} from \"zod/mini\";\nimport type { IncomingMessage, ServerResponse } from \"node:http\";\nimport type { Socket } from \"node:net\";\n\nconst AUTHORIZATION_ENDPOINT_METHOD_PREFIX_OAUTH2 = \"oauth2:\";\nconst LOCAL_STORAGE_OAUTH2_KEY = \"graffiti-auth-oauth2-data\";\n\nexport class Authorization {\n eventTarget: EventTarget = new EventTarget();\n\n constructor() {\n // Extract oauth redirect synchronously so the route\n // can be changed before any SPA routers (e.g. vue router)\n // start messing with things\n const oauthPromise = this.completeOauth();\n\n (async () => {\n // Allow listeners to be added first\n await new Promise((resolve) => setTimeout(resolve, 0));\n\n // Complete the oauth flow\n await oauthPromise;\n\n // Send an initialized event\n const initializedEvent: InitializedEvent = new CustomEvent(\"initialized\");\n this.eventTarget.dispatchEvent(initializedEvent);\n })();\n }\n\n async login(...args: Parameters<typeof this.login_>): Promise<void> {\n try {\n await this.login_(...args);\n } catch (e) {\n const error = e instanceof Error ? e : new Error(\"Unknown error\");\n const detail: LoginEvent[\"detail\"] = { loginId: args[1], error };\n this.eventTarget.dispatchEvent(new CustomEvent(\"login\", { detail }));\n }\n }\n protected async login_(\n authorizationEndpoint: string,\n loginId: string,\n serviceEndpoints: string[],\n ): Promise<void> {\n const configuration = await this.getAuthorizationConfiguration(\n authorizationEndpoint,\n );\n\n const scope = serviceEndpoints.map(encodeURIComponent).join(\" \");\n const state = randomState();\n\n let redirectUri: string;\n let waitForCallback: Promise<void> | undefined = undefined;\n if (typeof window !== \"undefined\") {\n // If in a browser, prepare for a redirect by\n // storing the configuration, expected state,\n // current URL, and endpoints in local storage\n redirectUri = window.location.href;\n const data: infer_<typeof OAuth2LoginDataSchema> = {\n loginId,\n redirectUri,\n authorizationEndpoint,\n state,\n serviceEndpoints,\n };\n window.localStorage.setItem(\n LOCAL_STORAGE_OAUTH2_KEY,\n JSON.stringify(data),\n );\n } else {\n // Otherwise, in node, start a local server to receive the callback\n const http = await import(\"node:http\").catch((e) => {\n throw new Error(\n \"Unrecognized environment: cannot find window or node:http\",\n );\n });\n const server = http.createServer();\n\n try {\n await new Promise<void>((resolve, reject) => {\n server.once(\"error\", reject);\n server.listen(0, \"::1\", resolve);\n });\n } catch (e) {\n try {\n server.close();\n } catch {}\n throw new Error(\"Failed to start local oauth callback server.\");\n }\n\n const address = server.address();\n if (!address) {\n try {\n server.close();\n } catch {}\n throw new Error(\"Failed to get local oauth callback server address.\");\n }\n redirectUri =\n typeof address === \"string\"\n ? `http://${address}`\n : `http://${address.family === \"IPv6\" ? `[${address.address}]` : address.address}:${address.port}`;\n\n // Wait for a callback request\n waitForCallback = new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(\n () => {\n try {\n server.close();\n } catch {}\n reject(\"Oauth callback timed out.\");\n },\n 5 * 60 * 1000, // 5 minutes\n );\n\n const sockets = new Set<Socket>();\n server.on(\"connection\", (socket: Socket) => {\n sockets.add(socket);\n socket.on(\"close\", () => {\n sockets.delete(socket);\n });\n });\n\n // Set up the actual request handler\n const onRequest = async (req: IncomingMessage, res: ServerResponse) => {\n try {\n const callbackUrl = new URL(req.url ?? \"/\", redirectUri);\n await this.onCallbackUrl({\n loginId,\n callbackUrl,\n configuration,\n expectedState: state,\n serviceEndpoints,\n });\n\n res.statusCode = 200;\n res.setHeader(\"Content-Type\", \"text/plain\");\n res.end(\"You may now close this window.\");\n } catch (e) {\n res.statusCode = 500;\n res.setHeader(\"Content-Type\", \"text/plain\");\n res.end(\"Error processing OAuth callback.\");\n\n throw e;\n } finally {\n clearTimeout(timeout);\n server.off(\"request\", onRequest);\n\n for (const socket of sockets) {\n socket.destroy();\n }\n\n server.close(() => resolve());\n }\n };\n\n server.on(\"request\", onRequest);\n });\n }\n\n // Construct the authorization URL\n const redirectUriStripped = new URL(redirectUri);\n redirectUriStripped.hash = \"\";\n redirectUriStripped.search = \"\";\n\n const redirectTo = buildAuthorizationUrl(configuration, {\n scope,\n redirect_uri: redirectUriStripped.toString(),\n state,\n });\n\n // Either redirect (browser) or print the URL and wait (node)\n if (typeof window !== \"undefined\") {\n window.location.href = redirectTo.toString();\n } else {\n console.log(\"Please open the following URL in your browser:\");\n console.log(redirectTo.toString());\n await waitForCallback;\n }\n }\n\n protected completeOauth() {\n if (typeof window === \"undefined\") return;\n\n // Look in local storage to see if we have a pending login\n const data = window.localStorage.getItem(LOCAL_STORAGE_OAUTH2_KEY);\n if (!data) return;\n\n let json: unknown;\n try {\n json = JSON.parse(data);\n } catch {\n console.error(\"Invalid OAuth2 login data in local storage.\");\n window.localStorage.removeItem(LOCAL_STORAGE_OAUTH2_KEY);\n return;\n }\n\n const parseResult = OAuth2LoginDataSchema.safeParse(json);\n if (!parseResult.success) {\n console.error(\n \"Invalid OAuth2 login data structure in local storage.\",\n parseResult.error,\n );\n window.localStorage.removeItem(LOCAL_STORAGE_OAUTH2_KEY);\n return;\n }\n\n const {\n loginId,\n redirectUri,\n authorizationEndpoint,\n state,\n serviceEndpoints,\n } = parseResult.data;\n\n try {\n // Make sure that we redirected back to the correct page\n const expectedUrl = new URL(redirectUri);\n const callbackUrl = new URL(window.location.href);\n if (expectedUrl.pathname !== callbackUrl.pathname) return;\n // Make sure it is actually an oauth call\n const params = callbackUrl.searchParams;\n if (!params.has(\"code\") && !params.has(\"error\")) return;\n\n // Restore the hash and query parameters to the expected URL,\n // removing the code, state, and error parameters\n window.history.replaceState({}, document.title, expectedUrl.toString());\n window.localStorage.removeItem(LOCAL_STORAGE_OAUTH2_KEY);\n\n return new Promise<void>((resolve) => setTimeout(resolve, 0))\n .then(() => this.getAuthorizationConfiguration(authorizationEndpoint))\n .then((configuration) =>\n this.onCallbackUrl({\n loginId,\n callbackUrl,\n configuration,\n expectedState: state,\n serviceEndpoints,\n }),\n )\n .catch((e) => {\n const error = e instanceof Error ? e : new Error(\"Unknown error\");\n const detail: LoginEvent[\"detail\"] = { loginId, error };\n this.eventTarget.dispatchEvent(new CustomEvent(\"login\", { detail }));\n });\n } catch (e) {\n console.error(e);\n }\n }\n\n protected async onCallbackUrl(args: {\n loginId: string;\n callbackUrl: URL;\n configuration: any;\n expectedState: string;\n serviceEndpoints: string[];\n }) {\n const {\n loginId,\n callbackUrl,\n configuration,\n expectedState,\n serviceEndpoints,\n } = args;\n\n const response = await authorizationCodeGrant(configuration, callbackUrl, {\n expectedState,\n });\n\n const token = response.access_token;\n const scope = response.scope;\n const grantedEndpoints =\n scope?.split(\" \").map(decodeURIComponent) || serviceEndpoints;\n\n // Make sure granted endpoints cover the requested endpoints\n if (\n !serviceEndpoints.every((endpoint) => grantedEndpoints.includes(endpoint))\n ) {\n throw new Error(\"Not all requested service endpoints were granted.\");\n }\n\n // Send a logged in event\n const loginEvent: LoginEvent = new CustomEvent(\"login\", {\n detail: {\n loginId,\n token,\n },\n });\n this.eventTarget.dispatchEvent(loginEvent);\n }\n\n async logout(\n authorizationEndpoint: string,\n logoutId: string,\n token: string,\n ): Promise<void> {\n try {\n await this.logout_(authorizationEndpoint, logoutId, token);\n } catch (e) {\n const error = e instanceof Error ? e : new Error(\"Unknown error\");\n const detail: LogoutEvent[\"detail\"] = { logoutId, error };\n this.eventTarget.dispatchEvent(new CustomEvent(\"logout\", { detail }));\n }\n }\n protected async logout_(\n authorizationEndpoint: string,\n logoutId: string,\n token: string,\n ): Promise<void> {\n const configuration = await this.getAuthorizationConfiguration(\n authorizationEndpoint,\n );\n await tokenRevocation(configuration, token);\n const detail: LogoutEvent[\"detail\"] = { logoutId };\n this.eventTarget.dispatchEvent(new CustomEvent(\"logout\", { detail }));\n }\n\n protected async getAuthorizationConfiguration(\n authorizationEndpoint: string,\n ): Promise<any> {\n // Parse the authorization endpoint\n if (\n !authorizationEndpoint.startsWith(\n AUTHORIZATION_ENDPOINT_METHOD_PREFIX_OAUTH2,\n )\n ) {\n throw new Error(\n `Unrecognized authorization endpoint method: ${authorizationEndpoint}`,\n );\n }\n const issuer = authorizationEndpoint.slice(\n AUTHORIZATION_ENDPOINT_METHOD_PREFIX_OAUTH2.length,\n );\n\n // Look up the oauth configuration\n let issuerUrl: URL;\n try {\n issuerUrl = new URL(issuer);\n } catch (e) {\n throw new Error(\"Invalid issuer URL.\");\n }\n\n return await discovery(issuerUrl, \"graffiti-client\");\n }\n}\n\nexport const LoginEventDetailSchema = intersection(\n object({\n loginId: string(),\n }),\n union([\n object({ token: string(), error: optional(undefined_()) }),\n object({ error: instanceof_(Error) }),\n ]),\n);\n\nexport const LogoutEventDetailSchema = object({\n logoutId: string(),\n error: optional(instanceof_(Error)),\n});\n\nexport const InitializedEventDetailSchema = optional(\n nullable(\n object({\n error: optional(instanceof_(Error)),\n }),\n ),\n);\n\nexport type LoginEvent = CustomEvent<infer_<typeof LoginEventDetailSchema>>;\nexport type LogoutEvent = CustomEvent<infer_<typeof LogoutEventDetailSchema>>;\nexport type InitializedEvent = CustomEvent<\n infer_<typeof InitializedEventDetailSchema>\n>;\n\nconst OAuth2LoginDataSchema = object({\n loginId: string(),\n redirectUri: url(),\n authorizationEndpoint: url(),\n state: string(),\n serviceEndpoints: array(url()),\n});\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["undefined_", "instanceof_"]
|
|
7
|
+
}
|