gammait 1.0.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/LICENSE +21 -0
- package/lib/api.d.ts +48 -0
- package/lib/api.d.ts.map +1 -0
- package/lib/api.js +182 -0
- package/lib/index.d.ts +3 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +19 -0
- package/lib/types.d.ts +88 -0
- package/lib/types.d.ts.map +1 -0
- package/lib/types.js +4 -0
- package/lib/urls.d.ts +34 -0
- package/lib/urls.d.ts.map +1 -0
- package/lib/urls.js +73 -0
- package/package.json +51 -0
- package/src/api.ts +179 -0
- package/src/index.ts +2 -0
- package/src/types.ts +124 -0
- package/src/urls.ts +67 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 olillin
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/lib/api.d.ts
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import oauth2 from 'simple-oauth2';
|
|
2
|
+
import { ClientAuthority, Group, GroupWithPost, Scope, SuperGroup, User, UserId, UserInfo, UserWithGroups } from './types';
|
|
3
|
+
declare abstract class Client {
|
|
4
|
+
protected abstract fetch<T extends object>(url: string, method: string): Promise<T>;
|
|
5
|
+
}
|
|
6
|
+
interface ApiClientConfig {
|
|
7
|
+
authorization: string;
|
|
8
|
+
}
|
|
9
|
+
declare class ApiClient extends Client {
|
|
10
|
+
config: ApiClientConfig;
|
|
11
|
+
constructor(config: ApiClientConfig);
|
|
12
|
+
protected fetch<T extends object>(url: string, method?: string): Promise<T>;
|
|
13
|
+
}
|
|
14
|
+
export declare class ClientApi extends ApiClient {
|
|
15
|
+
getUsers(): Promise<User[]>;
|
|
16
|
+
getUser(id: UserId): Promise<User>;
|
|
17
|
+
getGroups(): Promise<Group[]>;
|
|
18
|
+
getGroupsFor(id: UserId): Promise<GroupWithPost[]>;
|
|
19
|
+
getSuperGroups(): Promise<SuperGroup[]>;
|
|
20
|
+
getAuthorities(): Promise<ClientAuthority[]>;
|
|
21
|
+
getAuthoritiesFor(id: UserId): Promise<ClientAuthority[]>;
|
|
22
|
+
}
|
|
23
|
+
export declare class InfoApi extends ApiClient {
|
|
24
|
+
getUser(id: UserId): Promise<UserWithGroups>;
|
|
25
|
+
}
|
|
26
|
+
export interface AuthorizationCodeConfig {
|
|
27
|
+
clientId: string;
|
|
28
|
+
clientSecret: string;
|
|
29
|
+
redirectUri: string;
|
|
30
|
+
scope: Scope[];
|
|
31
|
+
}
|
|
32
|
+
export declare class AuthorizationCode extends Client {
|
|
33
|
+
config: AuthorizationCodeConfig;
|
|
34
|
+
oauth2Client: oauth2.AuthorizationCode;
|
|
35
|
+
accessToken: oauth2.AccessToken | undefined;
|
|
36
|
+
constructor(config: AuthorizationCodeConfig);
|
|
37
|
+
/**
|
|
38
|
+
* Generate a new access token and store it for later
|
|
39
|
+
* @param code Authorization code
|
|
40
|
+
* @returns The generated access token
|
|
41
|
+
*/
|
|
42
|
+
generateToken(code: string): Promise<oauth2.AccessToken>;
|
|
43
|
+
authorizeUrl(): string;
|
|
44
|
+
protected fetch<T extends object>(url: string, method?: string): Promise<T>;
|
|
45
|
+
userInfo(): Promise<UserInfo>;
|
|
46
|
+
}
|
|
47
|
+
export {};
|
|
48
|
+
//# sourceMappingURL=api.d.ts.map
|
package/lib/api.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,eAAe,CAAA;AAClC,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAG1H,uBAAe,MAAM;IACjB,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,SAAS,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;CACtF;AAED,UAAU,eAAe;IACrB,aAAa,EAAE,MAAM,CAAA;CACxB;AAED,cAAM,SAAU,SAAQ,MAAM;IAC1B,MAAM,EAAE,eAAe,CAAA;gBAEX,MAAM,EAAE,eAAe;IAKnC,SAAS,CAAC,KAAK,CAAC,CAAC,SAAS,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,MAAc,GAAG,OAAO,CAAC,CAAC,CAAC;CA2BrF;AAED,qBAAa,SAAU,SAAQ,SAAS;IACpC,QAAQ,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;IAI3B,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIlC,SAAS,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;IAI7B,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAIlD,cAAc,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;IAIvC,cAAc,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;IAI5C,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;CAG5D;AAED,qBAAa,OAAQ,SAAQ,SAAS;IAClC,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;CAO/C;AAED,MAAM,WAAW,uBAAuB;IACpC,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,MAAM,CAAA;IACpB,WAAW,EAAE,MAAM,CAAA;IACnB,KAAK,EAAE,KAAK,EAAE,CAAA;CACjB;AAED,qBAAa,iBAAkB,SAAQ,MAAM;IACzC,MAAM,EAAE,uBAAuB,CAAA;IAC/B,YAAY,EAAE,MAAM,CAAC,iBAAiB,CAAA;IACtC,WAAW,EAAE,MAAM,CAAC,WAAW,GAAG,SAAS,CAAA;gBAE/B,MAAM,EAAE,uBAAuB;IAoB3C;;;;OAIG;IACG,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC;IAU9D,YAAY;IAOZ,SAAS,CAAC,KAAK,CAAC,CAAC,SAAS,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,MAAc,GAAG,OAAO,CAAC,CAAC,CAAC;IAgClF,QAAQ,IAAI,OAAO,CAAC,QAAQ,CAAC;CAGhC"}
|
package/lib/api.js
ADDED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.AuthorizationCode = exports.InfoApi = exports.ClientApi = void 0;
|
|
40
|
+
const simple_oauth2_1 = __importDefault(require("simple-oauth2"));
|
|
41
|
+
const url = __importStar(require("./urls"));
|
|
42
|
+
class Client {
|
|
43
|
+
}
|
|
44
|
+
class ApiClient extends Client {
|
|
45
|
+
config;
|
|
46
|
+
constructor(config) {
|
|
47
|
+
super();
|
|
48
|
+
this.config = config;
|
|
49
|
+
}
|
|
50
|
+
fetch(url, method = 'GET') {
|
|
51
|
+
return new Promise((resolve, reject) => {
|
|
52
|
+
fetch(url, {
|
|
53
|
+
headers: {
|
|
54
|
+
Authorization: this.config.authorization,
|
|
55
|
+
},
|
|
56
|
+
method: method,
|
|
57
|
+
})
|
|
58
|
+
.then(async (res) => {
|
|
59
|
+
if (!res.ok) {
|
|
60
|
+
reject(`Received code ${res.status} during ${method} to ${url}`);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
if (!res.headers.has('Content-Type') || res.headers.get('Content-Type') !== 'application/json') {
|
|
64
|
+
reject('Response was not JSON');
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
const data = await res.json();
|
|
68
|
+
resolve(data);
|
|
69
|
+
})
|
|
70
|
+
.catch(reason => {
|
|
71
|
+
reject(reason);
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
class ClientApi extends ApiClient {
|
|
77
|
+
getUsers() {
|
|
78
|
+
return this.fetch(url.CLIENT_API_USERS);
|
|
79
|
+
}
|
|
80
|
+
getUser(id) {
|
|
81
|
+
return this.fetch(url.clientApiUser(id));
|
|
82
|
+
}
|
|
83
|
+
getGroups() {
|
|
84
|
+
return this.fetch(url.CLIENT_API_GROUPS);
|
|
85
|
+
}
|
|
86
|
+
getGroupsFor(id) {
|
|
87
|
+
return this.fetch(url.clientApiGroupsFor(id));
|
|
88
|
+
}
|
|
89
|
+
getSuperGroups() {
|
|
90
|
+
return this.fetch(url.CLIENT_API_SUPER_GROUPS);
|
|
91
|
+
}
|
|
92
|
+
getAuthorities() {
|
|
93
|
+
return this.fetch(url.CLIENT_API_AUTHORITIES);
|
|
94
|
+
}
|
|
95
|
+
getAuthoritiesFor(id) {
|
|
96
|
+
return this.fetch(url.clientApiAuthoritiesFor(id));
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
exports.ClientApi = ClientApi;
|
|
100
|
+
class InfoApi extends ApiClient {
|
|
101
|
+
getUser(id) {
|
|
102
|
+
return this.fetch(url.infoApiUser(id));
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
exports.InfoApi = InfoApi;
|
|
106
|
+
class AuthorizationCode extends Client {
|
|
107
|
+
config;
|
|
108
|
+
oauth2Client;
|
|
109
|
+
accessToken;
|
|
110
|
+
constructor(config) {
|
|
111
|
+
super();
|
|
112
|
+
this.config = config;
|
|
113
|
+
this.oauth2Client = new simple_oauth2_1.default.AuthorizationCode({
|
|
114
|
+
auth: {
|
|
115
|
+
tokenHost: url.GAMMA_ROOT,
|
|
116
|
+
tokenPath: url.TOKEN_PATH,
|
|
117
|
+
authorizeHost: url.GAMMA_ROOT,
|
|
118
|
+
authorizePath: url.AUTHORIZE_PATH,
|
|
119
|
+
},
|
|
120
|
+
client: {
|
|
121
|
+
id: this.config.clientId,
|
|
122
|
+
secret: this.config.clientSecret,
|
|
123
|
+
},
|
|
124
|
+
options: {
|
|
125
|
+
scopeSeparator: ' ',
|
|
126
|
+
},
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Generate a new access token and store it for later
|
|
131
|
+
* @param code Authorization code
|
|
132
|
+
* @returns The generated access token
|
|
133
|
+
*/
|
|
134
|
+
async generateToken(code) {
|
|
135
|
+
const token = await this.oauth2Client.getToken({
|
|
136
|
+
code: code,
|
|
137
|
+
scope: this.config.scope,
|
|
138
|
+
redirect_uri: this.config.redirectUri,
|
|
139
|
+
});
|
|
140
|
+
this.accessToken = token;
|
|
141
|
+
return token;
|
|
142
|
+
}
|
|
143
|
+
authorizeUrl() {
|
|
144
|
+
return this.oauth2Client.authorizeURL({
|
|
145
|
+
scope: this.config.scope,
|
|
146
|
+
redirect_uri: this.config.redirectUri,
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
fetch(url, method = 'GET') {
|
|
150
|
+
if (!this.accessToken) {
|
|
151
|
+
throw new Error('No token has been generated yet, make sure to run `generateToken`');
|
|
152
|
+
}
|
|
153
|
+
return new Promise((resolve, reject) => {
|
|
154
|
+
fetch(url, {
|
|
155
|
+
headers: {
|
|
156
|
+
Authorization: `Bearer ${this.accessToken.token.access_token}`,
|
|
157
|
+
},
|
|
158
|
+
method: method,
|
|
159
|
+
})
|
|
160
|
+
.then(async (res) => {
|
|
161
|
+
if (!res.ok) {
|
|
162
|
+
reject(`Received code ${res.status} during ${method} to ${url}`);
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
if (!res.headers.has('Content-Type') || res.headers.get('Content-Type') !== 'application/json') {
|
|
166
|
+
reject('Response was not JSON');
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
const data = await res.json();
|
|
170
|
+
resolve(data);
|
|
171
|
+
})
|
|
172
|
+
.catch(reason => {
|
|
173
|
+
reject(reason);
|
|
174
|
+
});
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
userInfo() {
|
|
178
|
+
return this.fetch(url.OAUTH2_USERINFO);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
exports.AuthorizationCode = AuthorizationCode;
|
|
182
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBpLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2FwaS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxrRUFBa0M7QUFFbEMsNENBQTZCO0FBRTdCLE1BQWUsTUFBTTtDQUVwQjtBQU1ELE1BQU0sU0FBVSxTQUFRLE1BQU07SUFDMUIsTUFBTSxDQUFpQjtJQUV2QixZQUFZLE1BQXVCO1FBQy9CLEtBQUssRUFBRSxDQUFBO1FBQ1AsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUE7SUFDeEIsQ0FBQztJQUVTLEtBQUssQ0FBbUIsR0FBVyxFQUFFLFNBQWlCLEtBQUs7UUFDakUsT0FBTyxJQUFJLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsRUFBRTtZQUNuQyxLQUFLLENBQUMsR0FBRyxFQUFFO2dCQUNQLE9BQU8sRUFBRTtvQkFDTCxhQUFhLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxhQUFhO2lCQUMzQztnQkFDRCxNQUFNLEVBQUUsTUFBTTthQUNqQixDQUFDO2lCQUNHLElBQUksQ0FBQyxLQUFLLEVBQUMsR0FBRyxFQUFDLEVBQUU7Z0JBQ2QsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsQ0FBQztvQkFDVixNQUFNLENBQUMsaUJBQWlCLEdBQUcsQ0FBQyxNQUFNLFdBQVcsTUFBTSxPQUFPLEdBQUcsRUFBRSxDQUFDLENBQUE7b0JBQ2hFLE9BQU07Z0JBQ1YsQ0FBQztnQkFFRCxJQUFJLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsY0FBYyxDQUFDLElBQUksR0FBRyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsY0FBYyxDQUFDLEtBQUssa0JBQWtCLEVBQUUsQ0FBQztvQkFDN0YsTUFBTSxDQUFDLHVCQUF1QixDQUFDLENBQUE7b0JBQy9CLE9BQU07Z0JBQ1YsQ0FBQztnQkFFRCxNQUFNLElBQUksR0FB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
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAA;AACvB,cAAc,OAAO,CAAA"}
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./types"), exports);
|
|
18
|
+
__exportStar(require("./api"), exports);
|
|
19
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLDBDQUF1QjtBQUN2Qix3Q0FBcUIifQ==
|
package/lib/types.d.ts
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { UUID } from 'crypto';
|
|
2
|
+
import * as url from './urls';
|
|
3
|
+
export type UserId = UUID;
|
|
4
|
+
export type GroupId = UUID;
|
|
5
|
+
export type SuperGroupId = UUID;
|
|
6
|
+
export type PostId = UUID;
|
|
7
|
+
export interface User {
|
|
8
|
+
id: UserId;
|
|
9
|
+
cid: string;
|
|
10
|
+
nick: string;
|
|
11
|
+
firstName: string;
|
|
12
|
+
lastName: string;
|
|
13
|
+
acceptanceYear: number;
|
|
14
|
+
}
|
|
15
|
+
export interface Group {
|
|
16
|
+
id: GroupId;
|
|
17
|
+
name: string;
|
|
18
|
+
prettyName: string;
|
|
19
|
+
superGroup: SuperGroup;
|
|
20
|
+
}
|
|
21
|
+
export interface SuperGroup {
|
|
22
|
+
id: SuperGroupId;
|
|
23
|
+
name: string;
|
|
24
|
+
prettyName: string;
|
|
25
|
+
type: string;
|
|
26
|
+
svDescription: string;
|
|
27
|
+
enDescription: string;
|
|
28
|
+
}
|
|
29
|
+
export interface Post extends Versioned {
|
|
30
|
+
id: PostId;
|
|
31
|
+
svName: string;
|
|
32
|
+
enName: string;
|
|
33
|
+
}
|
|
34
|
+
export interface PostInfo extends Post {
|
|
35
|
+
emailPrefix: string;
|
|
36
|
+
order: number;
|
|
37
|
+
}
|
|
38
|
+
export interface Versioned {
|
|
39
|
+
version: number;
|
|
40
|
+
}
|
|
41
|
+
export interface VersionedGroup extends Group, Versioned {
|
|
42
|
+
superGroup: VersionedSuperGroup;
|
|
43
|
+
}
|
|
44
|
+
export interface VersionedSuperGroup extends SuperGroup, Versioned {
|
|
45
|
+
}
|
|
46
|
+
export type Scope = 'openid' | 'profile' | 'email';
|
|
47
|
+
export interface ClientConfig {
|
|
48
|
+
clientId: string;
|
|
49
|
+
clientSecret: string;
|
|
50
|
+
scope: Scope;
|
|
51
|
+
}
|
|
52
|
+
export type UserAvatarUrl = `${typeof url.IMAGES_USER_AVATAR}/${UserId}`;
|
|
53
|
+
export type GroupAvatarUrl = `${typeof url.IMAGES_GROUP_AVATAR}/${GroupId}`;
|
|
54
|
+
export type GroupBannerUrl = `${typeof url.IMAGES_GROUP_BANNER}/${GroupId}`;
|
|
55
|
+
export type SuperGroupAvatarUrl = `${typeof url.IMAGES_SUPER_GROUP_AVATAR}/${SuperGroupId}`;
|
|
56
|
+
export type SuperGroupBannerUrl = `${typeof url.IMAGES_SUPER_GROUP_BANNER}/${SuperGroupId}`;
|
|
57
|
+
export type ClientApiUserUrl = `${typeof url.CLIENT_API_USERS}/${UserId}`;
|
|
58
|
+
export type ClientApiGroupsForUrl = `${typeof url.CLIENT_API_GROUPS_FOR}/${UserId}`;
|
|
59
|
+
export type ClientApiAuthoritiesForUrl = `${typeof url.CLIENT_API_AUTHORITIES_FOR}/${UserId}`;
|
|
60
|
+
export type InfoApiUserUrl = `${typeof url.INFO_API_USERS}/${UserId}`;
|
|
61
|
+
export interface UserInfo {
|
|
62
|
+
sub: UserId;
|
|
63
|
+
cid: string;
|
|
64
|
+
name: string;
|
|
65
|
+
given_name: string;
|
|
66
|
+
family_name: string;
|
|
67
|
+
nickname: string;
|
|
68
|
+
picture: UserAvatarUrl;
|
|
69
|
+
scope: Scope[];
|
|
70
|
+
iss: typeof url.GAMMA_ROOT;
|
|
71
|
+
aud: string[];
|
|
72
|
+
nbf: number;
|
|
73
|
+
exp: number;
|
|
74
|
+
iat: number;
|
|
75
|
+
jti: UUID;
|
|
76
|
+
}
|
|
77
|
+
export interface UserWithGroups {
|
|
78
|
+
user: User;
|
|
79
|
+
groups: {
|
|
80
|
+
group: VersionedGroup;
|
|
81
|
+
post: PostInfo;
|
|
82
|
+
}[];
|
|
83
|
+
}
|
|
84
|
+
export interface GroupWithPost extends Group {
|
|
85
|
+
post: Post;
|
|
86
|
+
}
|
|
87
|
+
export type ClientAuthority = string;
|
|
88
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/lib/types.js
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
// #endregion API responses
|
|
4
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUEySEEsMkJBQTJCIn0=
|
package/lib/urls.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { ClientApiAuthoritiesForUrl, ClientApiGroupsForUrl, ClientApiUserUrl, GroupAvatarUrl, GroupBannerUrl, GroupId, InfoApiUserUrl, SuperGroupAvatarUrl, SuperGroupBannerUrl, SuperGroupId, UserAvatarUrl, UserId } from './types';
|
|
2
|
+
export declare const GAMMA_ROOT: "https://auth.chalmers.it";
|
|
3
|
+
export declare const OAUTH2_ROOT: "https://auth.chalmers.it/oauth2";
|
|
4
|
+
export declare const AUTHORIZE_PATH: "/oauth2/authorize";
|
|
5
|
+
export declare const AUTHORIZE: "https://auth.chalmers.it/oauth2/authorize";
|
|
6
|
+
export declare const TOKEN_PATH: "/oauth2/token";
|
|
7
|
+
export declare const TOKEN: "https://auth.chalmers.it/oauth2/token";
|
|
8
|
+
export declare const OAUTH2_USERINFO: "https://auth.chalmers.it/oauth2/userinfo";
|
|
9
|
+
export declare const CLIENT_API_ROOT: "https://auth.chalmers.it/api/client/v1";
|
|
10
|
+
export declare const CLIENT_API_GROUPS: "https://auth.chalmers.it/api/client/v1/groups";
|
|
11
|
+
export declare const CLIENT_API_GROUPS_FOR: "https://auth.chalmers.it/api/client/v1/groups/for";
|
|
12
|
+
export declare function clientApiGroupsFor(id: UserId): ClientApiGroupsForUrl;
|
|
13
|
+
export declare const CLIENT_API_SUPER_GROUPS: "https://auth.chalmers.it/api/client/v1/superGroups";
|
|
14
|
+
export declare const CLIENT_API_USERS: "https://auth.chalmers.it/api/client/v1/users";
|
|
15
|
+
export declare function clientApiUser(id: UserId): ClientApiUserUrl;
|
|
16
|
+
export declare const CLIENT_API_AUTHORITIES: "https://auth.chalmers.it/api/client/v1/authorities";
|
|
17
|
+
export declare const CLIENT_API_AUTHORITIES_FOR: "https://auth.chalmers.it/api/client/v1/authorities/for";
|
|
18
|
+
export declare function clientApiAuthoritiesFor(id: UserId): ClientApiAuthoritiesForUrl;
|
|
19
|
+
export declare const INFO_API_ROOT: "https://auth.chalmers.it/api/info/v1";
|
|
20
|
+
export declare const INFO_API_USERS: "https://auth.chalmers.it/api/info/v1/users";
|
|
21
|
+
export declare function infoApiUser(id: UserId): InfoApiUserUrl;
|
|
22
|
+
export declare const INFO_API_BLOB: "https://auth.chalmers.it/api/info/v1/blob";
|
|
23
|
+
export declare const IMAGES: "https://auth.chalmers.it/images";
|
|
24
|
+
export declare const IMAGES_USER_AVATAR: "https://auth.chalmers.it/images/user/avatar";
|
|
25
|
+
export declare function userAvatarUrl(id: UserId): UserAvatarUrl;
|
|
26
|
+
export declare const IMAGES_GROUP_AVATAR: "https://auth.chalmers.it/images/group/avatar";
|
|
27
|
+
export declare function groupAvatarUrl(id: GroupId): GroupAvatarUrl;
|
|
28
|
+
export declare const IMAGES_GROUP_BANNER: "https://auth.chalmers.it/images/group/banner";
|
|
29
|
+
export declare function groupBannerUrl(id: GroupId): GroupBannerUrl;
|
|
30
|
+
export declare const IMAGES_SUPER_GROUP_AVATAR: "https://auth.chalmers.it/images/super-group/avatar";
|
|
31
|
+
export declare function superGroupAvatarUrl(id: SuperGroupId): SuperGroupAvatarUrl;
|
|
32
|
+
export declare const IMAGES_SUPER_GROUP_BANNER: "https://auth.chalmers.it/images/super-group/banner";
|
|
33
|
+
export declare function superGroupBannerUrl(id: SuperGroupId): SuperGroupBannerUrl;
|
|
34
|
+
//# sourceMappingURL=urls.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"urls.d.ts","sourceRoot":"","sources":["../src/urls.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,0BAA0B,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,cAAc,EAAE,cAAc,EAAE,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAErO,eAAO,MAAM,UAAU,EAAG,0BAAmC,CAAA;AAG7D,eAAO,MAAM,WAAW,mCAAkC,CAAA;AAC1D,eAAO,MAAM,cAAc,EAAG,mBAA4B,CAAA;AAC1D,eAAO,MAAM,SAAS,6CAA4C,CAAA;AAClE,eAAO,MAAM,UAAU,EAAG,eAAwB,CAAA;AAClD,eAAO,MAAM,KAAK,yCAAwC,CAAA;AAI1D,eAAO,MAAM,eAAe,4CAAqC,CAAA;AAIjE,eAAO,MAAM,eAAe,0CAAyC,CAAA;AACrE,eAAO,MAAM,iBAAiB,iDAAuC,CAAA;AACrE,eAAO,MAAM,qBAAqB,qDAAsC,CAAA;AACxE,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,qBAAqB,CAEpE;AACD,eAAO,MAAM,uBAAuB,sDAA4C,CAAA;AAChF,eAAO,MAAM,gBAAgB,gDAAsC,CAAA;AACnE,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,gBAAgB,CAE1D;AACD,eAAO,MAAM,sBAAsB,sDAA4C,CAAA;AAC/E,eAAO,MAAM,0BAA0B,0DAA2C,CAAA;AAClF,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,MAAM,GAAG,0BAA0B,CAE9E;AAID,eAAO,MAAM,aAAa,wCAAuC,CAAA;AACjE,eAAO,MAAM,cAAc,8CAAoC,CAAA;AAC/D,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,cAAc,CAEtD;AACD,eAAO,MAAM,aAAa,6CAAmC,CAAA;AAI7D,eAAO,MAAM,MAAM,mCAAkC,CAAA;AACrD,eAAO,MAAM,kBAAkB,+CAAmC,CAAA;AAClE,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,aAAa,CAEvD;AACD,eAAO,MAAM,mBAAmB,gDAAoC,CAAA;AACpE,wBAAgB,cAAc,CAAC,EAAE,EAAE,OAAO,GAAG,cAAc,CAE1D;AACD,eAAO,MAAM,mBAAmB,gDAAoC,CAAA;AACpE,wBAAgB,cAAc,CAAC,EAAE,EAAE,OAAO,GAAG,cAAc,CAE1D;AACD,eAAO,MAAM,yBAAyB,sDAA0C,CAAA;AAChF,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,YAAY,GAAG,mBAAmB,CAEzE;AACD,eAAO,MAAM,yBAAyB,sDAA0C,CAAA;AAChF,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,YAAY,GAAG,mBAAmB,CAEzE"}
|
package/lib/urls.js
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.IMAGES_SUPER_GROUP_BANNER = exports.IMAGES_SUPER_GROUP_AVATAR = exports.IMAGES_GROUP_BANNER = exports.IMAGES_GROUP_AVATAR = exports.IMAGES_USER_AVATAR = exports.IMAGES = exports.INFO_API_BLOB = exports.INFO_API_USERS = exports.INFO_API_ROOT = exports.CLIENT_API_AUTHORITIES_FOR = exports.CLIENT_API_AUTHORITIES = exports.CLIENT_API_USERS = exports.CLIENT_API_SUPER_GROUPS = exports.CLIENT_API_GROUPS_FOR = exports.CLIENT_API_GROUPS = exports.CLIENT_API_ROOT = exports.OAUTH2_USERINFO = exports.TOKEN = exports.TOKEN_PATH = exports.AUTHORIZE = exports.AUTHORIZE_PATH = exports.OAUTH2_ROOT = exports.GAMMA_ROOT = void 0;
|
|
4
|
+
exports.clientApiGroupsFor = clientApiGroupsFor;
|
|
5
|
+
exports.clientApiUser = clientApiUser;
|
|
6
|
+
exports.clientApiAuthoritiesFor = clientApiAuthoritiesFor;
|
|
7
|
+
exports.infoApiUser = infoApiUser;
|
|
8
|
+
exports.userAvatarUrl = userAvatarUrl;
|
|
9
|
+
exports.groupAvatarUrl = groupAvatarUrl;
|
|
10
|
+
exports.groupBannerUrl = groupBannerUrl;
|
|
11
|
+
exports.superGroupAvatarUrl = superGroupAvatarUrl;
|
|
12
|
+
exports.superGroupBannerUrl = superGroupBannerUrl;
|
|
13
|
+
exports.GAMMA_ROOT = 'https://auth.chalmers.it';
|
|
14
|
+
// #region Authorization
|
|
15
|
+
exports.OAUTH2_ROOT = `${exports.GAMMA_ROOT}/oauth2`;
|
|
16
|
+
exports.AUTHORIZE_PATH = '/oauth2/authorize';
|
|
17
|
+
exports.AUTHORIZE = `${exports.GAMMA_ROOT}${exports.AUTHORIZE_PATH}`;
|
|
18
|
+
exports.TOKEN_PATH = '/oauth2/token';
|
|
19
|
+
exports.TOKEN = `${exports.GAMMA_ROOT}${exports.TOKEN_PATH}`;
|
|
20
|
+
// #endregion Authorization
|
|
21
|
+
// #region OAuth2 Endpoints
|
|
22
|
+
exports.OAUTH2_USERINFO = `${exports.OAUTH2_ROOT}/userinfo`;
|
|
23
|
+
// #endregion
|
|
24
|
+
// #region Client API endpoints
|
|
25
|
+
exports.CLIENT_API_ROOT = `${exports.GAMMA_ROOT}/api/client/v1`;
|
|
26
|
+
exports.CLIENT_API_GROUPS = `${exports.CLIENT_API_ROOT}/groups`;
|
|
27
|
+
exports.CLIENT_API_GROUPS_FOR = `${exports.CLIENT_API_GROUPS}/for`;
|
|
28
|
+
function clientApiGroupsFor(id) {
|
|
29
|
+
return `${exports.CLIENT_API_GROUPS_FOR}/${id}`;
|
|
30
|
+
}
|
|
31
|
+
exports.CLIENT_API_SUPER_GROUPS = `${exports.CLIENT_API_ROOT}/superGroups`;
|
|
32
|
+
exports.CLIENT_API_USERS = `${exports.CLIENT_API_ROOT}/users`;
|
|
33
|
+
function clientApiUser(id) {
|
|
34
|
+
return `${exports.CLIENT_API_USERS}/${id}`;
|
|
35
|
+
}
|
|
36
|
+
exports.CLIENT_API_AUTHORITIES = `${exports.CLIENT_API_ROOT}/authorities`;
|
|
37
|
+
exports.CLIENT_API_AUTHORITIES_FOR = `${exports.CLIENT_API_AUTHORITIES}/for`;
|
|
38
|
+
function clientApiAuthoritiesFor(id) {
|
|
39
|
+
return `${exports.CLIENT_API_AUTHORITIES_FOR}/${id}`;
|
|
40
|
+
}
|
|
41
|
+
// #endregion Client API endpoints
|
|
42
|
+
// #region Info API endpoints
|
|
43
|
+
exports.INFO_API_ROOT = `${exports.GAMMA_ROOT}/api/info/v1`;
|
|
44
|
+
exports.INFO_API_USERS = `${exports.INFO_API_ROOT}/users`;
|
|
45
|
+
function infoApiUser(id) {
|
|
46
|
+
return `${exports.INFO_API_USERS}/${id}`;
|
|
47
|
+
}
|
|
48
|
+
exports.INFO_API_BLOB = `${exports.INFO_API_ROOT}/blob`;
|
|
49
|
+
// #endregion Info API endpoints
|
|
50
|
+
// #region Images
|
|
51
|
+
exports.IMAGES = `${exports.GAMMA_ROOT}/images`;
|
|
52
|
+
exports.IMAGES_USER_AVATAR = `${exports.IMAGES}/user/avatar`;
|
|
53
|
+
function userAvatarUrl(id) {
|
|
54
|
+
return `${exports.IMAGES_USER_AVATAR}/${id}`;
|
|
55
|
+
}
|
|
56
|
+
exports.IMAGES_GROUP_AVATAR = `${exports.IMAGES}/group/avatar`;
|
|
57
|
+
function groupAvatarUrl(id) {
|
|
58
|
+
return `${exports.IMAGES_GROUP_AVATAR}/${id}`;
|
|
59
|
+
}
|
|
60
|
+
exports.IMAGES_GROUP_BANNER = `${exports.IMAGES}/group/banner`;
|
|
61
|
+
function groupBannerUrl(id) {
|
|
62
|
+
return `${exports.IMAGES_GROUP_BANNER}/${id}`;
|
|
63
|
+
}
|
|
64
|
+
exports.IMAGES_SUPER_GROUP_AVATAR = `${exports.IMAGES}/super-group/avatar`;
|
|
65
|
+
function superGroupAvatarUrl(id) {
|
|
66
|
+
return `${exports.IMAGES_SUPER_GROUP_AVATAR}/${id}`;
|
|
67
|
+
}
|
|
68
|
+
exports.IMAGES_SUPER_GROUP_BANNER = `${exports.IMAGES}/super-group/banner`;
|
|
69
|
+
function superGroupBannerUrl(id) {
|
|
70
|
+
return `${exports.IMAGES_SUPER_GROUP_BANNER}/${id}`;
|
|
71
|
+
}
|
|
72
|
+
// #endregion Images
|
|
73
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXJscy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy91cmxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQW9CQSxnREFFQztBQUdELHNDQUVDO0FBR0QsMERBRUM7QUFNRCxrQ0FFQztBQU9ELHNDQUVDO0FBRUQsd0NBRUM7QUFFRCx3Q0FFQztBQUVELGtEQUVDO0FBRUQsa0RBRUM7QUEvRFksUUFBQSxVQUFVLEdBQUcsMEJBQW1DLENBQUE7QUFFN0Qsd0JBQXdCO0FBQ1gsUUFBQSxXQUFXLEdBQUcsR0FBRyxrQkFBVSxTQUFrQixDQUFBO0FBQzdDLFFBQUEsY0FBYyxHQUFHLG1CQUE0QixDQUFBO0FBQzdDLFFBQUEsU0FBUyxHQUFHLEdBQUcsa0JBQVUsR0FBRyxzQkFBYyxFQUFXLENBQUE7QUFDckQsUUFBQSxVQUFVLEdBQUcsZUFBd0IsQ0FBQTtBQUNyQyxRQUFBLEtBQUssR0FBRyxHQUFHLGtCQUFVLEdBQUcsa0JBQVUsRUFBVyxDQUFBO0FBQzFELDJCQUEyQjtBQUUzQiwyQkFBMkI7QUFDZCxRQUFBLGVBQWUsR0FBRyxHQUFHLG1CQUFXLFdBQW9CLENBQUE7QUFDakUsYUFBYTtBQUViLCtCQUErQjtBQUNsQixRQUFBLGVBQWUsR0FBRyxHQUFHLGtCQUFVLGdCQUF5QixDQUFBO0FBQ3hELFFBQUEsaUJBQWlCLEdBQUcsR0FBRyx1QkFBZSxTQUFrQixDQUFBO0FBQ3hELFFBQUEscUJBQXFCLEdBQUcsR0FBRyx5QkFBaUIsTUFBZSxDQUFBO0FBQ3hFLFNBQWdCLGtCQUFrQixDQUFDLEVBQVU7SUFDekMsT0FBTyxHQUFHLDZCQUFxQixJQUFJLEVBQUUsRUFBRSxDQUFBO0FBQzNDLENBQUM7QUFDWSxRQUFBLHVCQUF1QixHQUFHLEdBQUcsdUJBQWUsY0FBdUIsQ0FBQTtBQUNuRSxRQUFBLGdCQUFnQixHQUFHLEdBQUcsdUJBQWUsUUFBaUIsQ0FBQTtBQUNuRSxTQUFnQixhQUFhLENBQUMsRUFBVTtJQUNwQyxPQUFPLEdBQUcsd0JBQWdCLElBQUksRUFBRSxFQUFFLENBQUE7QUFDdEMsQ0FBQztBQUNZLFFBQUEsc0JBQXNCLEdBQUcsR0FBRyx1QkFBZSxjQUF1QixDQUFBO0FBQ2xFLFFBQUEsMEJBQTBCLEdBQUcsR0FBRyw4QkFBc0IsTUFBZSxDQUFBO0FBQ2xGLFNBQWdCLHVCQUF1QixDQUFDLEVBQVU7SUFDOUMsT0FBTyxHQUFHLGtDQUEwQixJQUFJLEVBQUUsRUFBRSxDQUFBO0FBQ2hELENBQUM7QUFDRCxrQ0FBa0M7QUFFbEMsNkJBQTZCO0FBQ2hCLFFBQUEsYUFBYSxHQUFHLEdBQUcsa0JBQVUsY0FBdUIsQ0FBQTtBQUNwRCxRQUFBLGNBQWMsR0FBRyxHQUFHLHFCQUFhLFFBQWlCLENBQUE7QUFDL0QsU0FBZ0IsV0FBVyxDQUFDLEVBQVU7SUFDbEMsT0FBTyxHQUFHLHNCQUFjLElBQUksRUFBRSxFQUFFLENBQUE7QUFDcEMsQ0FBQztBQUNZLFFBQUEsYUFBYSxHQUFHLEdBQUcscUJBQWEsT0FBZ0IsQ0FBQTtBQUM3RCxnQ0FBZ0M7QUFFaEMsaUJBQWlCO0FBQ0osUUFBQSxNQUFNLEdBQUcsR0FBRyxrQkFBVSxTQUFrQixDQUFBO0FBQ3hDLFFBQUEsa0JBQWtCLEdBQUcsR0FBRyxjQUFNLGNBQXVCLENBQUE7QUFDbEUsU0FBZ0IsYUFBYSxDQUFDLEVBQVU7SUFDcEMsT0FBTyxHQUFHLDBCQUFrQixJQUFJLEVBQUUsRUFBRSxDQUFBO0FBQ3hDLENBQUM7QUFDWSxRQUFBLG1CQUFtQixHQUFHLEdBQUcsY0FBTSxlQUF3QixDQUFBO0FBQ3BFLFNBQWdCLGNBQWMsQ0FBQyxFQUFXO0lBQ3RDLE9BQU8sR0FBRywyQkFBbUIsSUFBSSxFQUFFLEVBQUUsQ0FBQTtBQUN6QyxDQUFDO0FBQ1ksUUFBQSxtQkFBbUIsR0FBRyxHQUFHLGNBQU0sZUFBd0IsQ0FBQTtBQUNwRSxTQUFnQixjQUFjLENBQUMsRUFBVztJQUN0QyxPQUFPLEdBQUcsMkJBQW1CLElBQUksRUFBRSxFQUFFLENBQUE7QUFDekMsQ0FBQztBQUNZLFFBQUEseUJBQXlCLEdBQUcsR0FBRyxjQUFNLHFCQUE4QixDQUFBO0FBQ2hGLFNBQWdCLG1CQUFtQixDQUFDLEVBQWdCO0lBQ2hELE9BQU8sR0FBRyxpQ0FBeUIsSUFBSSxFQUFFLEVBQUUsQ0FBQTtBQUMvQyxDQUFDO0FBQ1ksUUFBQSx5QkFBeUIsR0FBRyxHQUFHLGNBQU0scUJBQThCLENBQUE7QUFDaEYsU0FBZ0IsbUJBQW1CLENBQUMsRUFBZ0I7SUFDaEQsT0FBTyxHQUFHLGlDQUF5QixJQUFJLEVBQUUsRUFBRSxDQUFBO0FBQy9DLENBQUM7QUFDRCxvQkFBb0IifQ==
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "gammait",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Interact with the IT-sections account system",
|
|
5
|
+
"main": "lib/index.js",
|
|
6
|
+
"types": "lib/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"/lib",
|
|
9
|
+
"/src"
|
|
10
|
+
],
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"import": "./lib/index.js",
|
|
14
|
+
"require": "./lib/index.js",
|
|
15
|
+
"types": "./lib/index.d.ts"
|
|
16
|
+
},
|
|
17
|
+
"./urls": {
|
|
18
|
+
"import": "./lib/urls.js",
|
|
19
|
+
"require": "./lib/urls.js",
|
|
20
|
+
"types": "./lib/urls.d.ts"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"scripts": {
|
|
24
|
+
"build": "rimraf lib && tsc",
|
|
25
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
26
|
+
},
|
|
27
|
+
"repository": {
|
|
28
|
+
"type": "git",
|
|
29
|
+
"url": "git+https://github.com/olillin/gammait.git"
|
|
30
|
+
},
|
|
31
|
+
"keywords": [
|
|
32
|
+
"oauth2",
|
|
33
|
+
"gamma",
|
|
34
|
+
"chalmers"
|
|
35
|
+
],
|
|
36
|
+
"author": "Oli <oli@olillin.com>",
|
|
37
|
+
"license": "MIT",
|
|
38
|
+
"bugs": {
|
|
39
|
+
"url": "https://github.com/olillin/gammait/issues"
|
|
40
|
+
},
|
|
41
|
+
"homepage": "https://github.com/olillin/gammait#readme",
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"simple-oauth2": "^5.1.0",
|
|
44
|
+
"typescript": "^5.7.3"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@types/node": "^22.13.1",
|
|
48
|
+
"@types/simple-oauth2": "^5.0.7",
|
|
49
|
+
"rimraf": "^6.0.1"
|
|
50
|
+
}
|
|
51
|
+
}
|
package/src/api.ts
ADDED
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import oauth2 from 'simple-oauth2'
|
|
2
|
+
import { ClientAuthority, Group, GroupWithPost, Scope, SuperGroup, User, UserId, UserInfo, UserWithGroups } from './types'
|
|
3
|
+
import * as url from './urls'
|
|
4
|
+
|
|
5
|
+
abstract class Client {
|
|
6
|
+
protected abstract fetch<T extends object>(url: string, method: string): Promise<T>
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
interface ApiClientConfig {
|
|
10
|
+
authorization: string
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
class ApiClient extends Client {
|
|
14
|
+
config: ApiClientConfig
|
|
15
|
+
|
|
16
|
+
constructor(config: ApiClientConfig) {
|
|
17
|
+
super()
|
|
18
|
+
this.config = config
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
protected fetch<T extends object>(url: string, method: string = 'GET'): Promise<T> {
|
|
22
|
+
return new Promise((resolve, reject) => {
|
|
23
|
+
fetch(url, {
|
|
24
|
+
headers: {
|
|
25
|
+
Authorization: this.config.authorization,
|
|
26
|
+
},
|
|
27
|
+
method: method,
|
|
28
|
+
})
|
|
29
|
+
.then(async res => {
|
|
30
|
+
if (!res.ok) {
|
|
31
|
+
reject(`Received code ${res.status} during ${method} to ${url}`)
|
|
32
|
+
return
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (!res.headers.has('Content-Type') || res.headers.get('Content-Type') !== 'application/json') {
|
|
36
|
+
reject('Response was not JSON')
|
|
37
|
+
return
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const data: T = await res.json()
|
|
41
|
+
resolve(data)
|
|
42
|
+
})
|
|
43
|
+
.catch(reason => {
|
|
44
|
+
reject(reason)
|
|
45
|
+
})
|
|
46
|
+
})
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export class ClientApi extends ApiClient {
|
|
51
|
+
getUsers(): Promise<User[]> {
|
|
52
|
+
return this.fetch(url.CLIENT_API_USERS)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
getUser(id: UserId): Promise<User> {
|
|
56
|
+
return this.fetch(url.clientApiUser(id))
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
getGroups(): Promise<Group[]> {
|
|
60
|
+
return this.fetch(url.CLIENT_API_GROUPS)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
getGroupsFor(id: UserId): Promise<GroupWithPost[]> {
|
|
64
|
+
return this.fetch(url.clientApiGroupsFor(id))
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
getSuperGroups(): Promise<SuperGroup[]> {
|
|
68
|
+
return this.fetch(url.CLIENT_API_SUPER_GROUPS)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
getAuthorities(): Promise<ClientAuthority[]> {
|
|
72
|
+
return this.fetch(url.CLIENT_API_AUTHORITIES)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
getAuthoritiesFor(id: UserId): Promise<ClientAuthority[]> {
|
|
76
|
+
return this.fetch(url.clientApiAuthoritiesFor(id))
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export class InfoApi extends ApiClient {
|
|
81
|
+
getUser(id: UserId): Promise<UserWithGroups> {
|
|
82
|
+
return this.fetch(url.infoApiUser(id))
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// getBlob(): Promise<unknown> {
|
|
86
|
+
// return this.fetch(url.INFO_API_BLOB)
|
|
87
|
+
// }
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export interface AuthorizationCodeConfig {
|
|
91
|
+
clientId: string
|
|
92
|
+
clientSecret: string
|
|
93
|
+
redirectUri: string
|
|
94
|
+
scope: Scope[]
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export class AuthorizationCode extends Client {
|
|
98
|
+
config: AuthorizationCodeConfig
|
|
99
|
+
oauth2Client: oauth2.AuthorizationCode
|
|
100
|
+
accessToken: oauth2.AccessToken | undefined
|
|
101
|
+
|
|
102
|
+
constructor(config: AuthorizationCodeConfig) {
|
|
103
|
+
super()
|
|
104
|
+
this.config = config
|
|
105
|
+
this.oauth2Client = new oauth2.AuthorizationCode({
|
|
106
|
+
auth: {
|
|
107
|
+
tokenHost: url.GAMMA_ROOT,
|
|
108
|
+
tokenPath: url.TOKEN_PATH,
|
|
109
|
+
authorizeHost: url.GAMMA_ROOT,
|
|
110
|
+
authorizePath: url.AUTHORIZE_PATH,
|
|
111
|
+
},
|
|
112
|
+
client: {
|
|
113
|
+
id: this.config.clientId,
|
|
114
|
+
secret: this.config.clientSecret,
|
|
115
|
+
},
|
|
116
|
+
options: {
|
|
117
|
+
scopeSeparator: ' ',
|
|
118
|
+
},
|
|
119
|
+
})
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Generate a new access token and store it for later
|
|
124
|
+
* @param code Authorization code
|
|
125
|
+
* @returns The generated access token
|
|
126
|
+
*/
|
|
127
|
+
async generateToken(code: string): Promise<oauth2.AccessToken> {
|
|
128
|
+
const token = await this.oauth2Client.getToken({
|
|
129
|
+
code: code,
|
|
130
|
+
scope: this.config.scope,
|
|
131
|
+
redirect_uri: this.config.redirectUri,
|
|
132
|
+
})
|
|
133
|
+
this.accessToken = token
|
|
134
|
+
return token
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
authorizeUrl() {
|
|
138
|
+
return this.oauth2Client.authorizeURL({
|
|
139
|
+
scope: this.config.scope,
|
|
140
|
+
redirect_uri: this.config.redirectUri,
|
|
141
|
+
})
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
protected fetch<T extends object>(url: string, method: string = 'GET'): Promise<T> {
|
|
145
|
+
if (!this.accessToken) {
|
|
146
|
+
throw new Error('No token has been generated yet, make sure to run `generateToken`')
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
return new Promise((resolve, reject) => {
|
|
150
|
+
fetch(url, {
|
|
151
|
+
headers: {
|
|
152
|
+
Authorization: `Bearer ${this.accessToken!.token.access_token}`,
|
|
153
|
+
},
|
|
154
|
+
method: method,
|
|
155
|
+
})
|
|
156
|
+
.then(async res => {
|
|
157
|
+
if (!res.ok) {
|
|
158
|
+
reject(`Received code ${res.status} during ${method} to ${url}`)
|
|
159
|
+
return
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (!res.headers.has('Content-Type') || res.headers.get('Content-Type') !== 'application/json') {
|
|
163
|
+
reject('Response was not JSON')
|
|
164
|
+
return
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const data: T = await res.json()
|
|
168
|
+
resolve(data)
|
|
169
|
+
})
|
|
170
|
+
.catch(reason => {
|
|
171
|
+
reject(reason)
|
|
172
|
+
})
|
|
173
|
+
})
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
userInfo(): Promise<UserInfo> {
|
|
177
|
+
return this.fetch(url.OAUTH2_USERINFO)
|
|
178
|
+
}
|
|
179
|
+
}
|
package/src/index.ts
ADDED
package/src/types.ts
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { UUID } from 'crypto'
|
|
2
|
+
import * as url from './urls'
|
|
3
|
+
|
|
4
|
+
// #region Basic
|
|
5
|
+
export type UserId = UUID
|
|
6
|
+
export type GroupId = UUID
|
|
7
|
+
export type SuperGroupId = UUID
|
|
8
|
+
export type PostId = UUID
|
|
9
|
+
|
|
10
|
+
export interface User {
|
|
11
|
+
id: UserId
|
|
12
|
+
cid: string
|
|
13
|
+
nick: string
|
|
14
|
+
firstName: string
|
|
15
|
+
lastName: string
|
|
16
|
+
acceptanceYear: number
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface Group {
|
|
20
|
+
id: GroupId
|
|
21
|
+
name: string
|
|
22
|
+
prettyName: string
|
|
23
|
+
superGroup: SuperGroup
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface SuperGroup {
|
|
27
|
+
id: SuperGroupId
|
|
28
|
+
name: string
|
|
29
|
+
prettyName: string
|
|
30
|
+
type: string
|
|
31
|
+
svDescription: string
|
|
32
|
+
enDescription: string
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface Post extends Versioned {
|
|
36
|
+
id: PostId
|
|
37
|
+
svName: string
|
|
38
|
+
enName: string
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface PostInfo extends Post {
|
|
42
|
+
emailPrefix: string
|
|
43
|
+
order: number
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface Versioned {
|
|
47
|
+
version: number
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export interface VersionedGroup extends Group, Versioned {
|
|
51
|
+
superGroup: VersionedSuperGroup
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export interface VersionedSuperGroup extends SuperGroup, Versioned {}
|
|
55
|
+
|
|
56
|
+
// #endregion Basic
|
|
57
|
+
|
|
58
|
+
// #region Authentication
|
|
59
|
+
export type Scope = 'openid' | 'profile' | 'email'
|
|
60
|
+
|
|
61
|
+
export interface ClientConfig {
|
|
62
|
+
clientId: string
|
|
63
|
+
clientSecret: string
|
|
64
|
+
scope: Scope
|
|
65
|
+
}
|
|
66
|
+
// #endregion Authentication
|
|
67
|
+
|
|
68
|
+
// #region URLs
|
|
69
|
+
|
|
70
|
+
// #region Images
|
|
71
|
+
export type UserAvatarUrl = `${typeof url.IMAGES_USER_AVATAR}/${UserId}`
|
|
72
|
+
export type GroupAvatarUrl = `${typeof url.IMAGES_GROUP_AVATAR}/${GroupId}`
|
|
73
|
+
export type GroupBannerUrl = `${typeof url.IMAGES_GROUP_BANNER}/${GroupId}`
|
|
74
|
+
export type SuperGroupAvatarUrl = `${typeof url.IMAGES_SUPER_GROUP_AVATAR}/${SuperGroupId}`
|
|
75
|
+
export type SuperGroupBannerUrl = `${typeof url.IMAGES_SUPER_GROUP_BANNER}/${SuperGroupId}`
|
|
76
|
+
// #endregion Images
|
|
77
|
+
|
|
78
|
+
// #region Client API
|
|
79
|
+
export type ClientApiUserUrl = `${typeof url.CLIENT_API_USERS}/${UserId}`
|
|
80
|
+
export type ClientApiGroupsForUrl = `${typeof url.CLIENT_API_GROUPS_FOR}/${UserId}`
|
|
81
|
+
export type ClientApiAuthoritiesForUrl = `${typeof url.CLIENT_API_AUTHORITIES_FOR}/${UserId}`
|
|
82
|
+
// #endregion Client API
|
|
83
|
+
|
|
84
|
+
// #region Info API
|
|
85
|
+
export type InfoApiUserUrl = `${typeof url.INFO_API_USERS}/${UserId}`
|
|
86
|
+
// #endregion Info API
|
|
87
|
+
|
|
88
|
+
// #endregion URLs
|
|
89
|
+
|
|
90
|
+
// #region API responses
|
|
91
|
+
export interface UserInfo {
|
|
92
|
+
sub: UserId
|
|
93
|
+
cid: string
|
|
94
|
+
|
|
95
|
+
name: string
|
|
96
|
+
given_name: string
|
|
97
|
+
family_name: string
|
|
98
|
+
nickname: string
|
|
99
|
+
picture: UserAvatarUrl
|
|
100
|
+
|
|
101
|
+
scope: Scope[]
|
|
102
|
+
iss: typeof url.GAMMA_ROOT
|
|
103
|
+
|
|
104
|
+
aud: string[]
|
|
105
|
+
nbf: number
|
|
106
|
+
exp: number
|
|
107
|
+
iat: number
|
|
108
|
+
jti: UUID
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export interface UserWithGroups {
|
|
112
|
+
user: User
|
|
113
|
+
groups: {
|
|
114
|
+
group: VersionedGroup
|
|
115
|
+
post: PostInfo
|
|
116
|
+
}[]
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export interface GroupWithPost extends Group {
|
|
120
|
+
post: Post
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export type ClientAuthority = string
|
|
124
|
+
// #endregion API responses
|
package/src/urls.ts
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { ClientApiAuthoritiesForUrl, ClientApiGroupsForUrl, ClientApiUserUrl, GroupAvatarUrl, GroupBannerUrl, GroupId, InfoApiUserUrl, SuperGroupAvatarUrl, SuperGroupBannerUrl, SuperGroupId, UserAvatarUrl, UserId } from './types'
|
|
2
|
+
|
|
3
|
+
export const GAMMA_ROOT = 'https://auth.chalmers.it' as const
|
|
4
|
+
|
|
5
|
+
// #region Authorization
|
|
6
|
+
export const OAUTH2_ROOT = `${GAMMA_ROOT}/oauth2` as const
|
|
7
|
+
export const AUTHORIZE_PATH = '/oauth2/authorize' as const
|
|
8
|
+
export const AUTHORIZE = `${GAMMA_ROOT}${AUTHORIZE_PATH}` as const
|
|
9
|
+
export const TOKEN_PATH = '/oauth2/token' as const
|
|
10
|
+
export const TOKEN = `${GAMMA_ROOT}${TOKEN_PATH}` as const
|
|
11
|
+
// #endregion Authorization
|
|
12
|
+
|
|
13
|
+
// #region OAuth2 Endpoints
|
|
14
|
+
export const OAUTH2_USERINFO = `${OAUTH2_ROOT}/userinfo` as const
|
|
15
|
+
// #endregion
|
|
16
|
+
|
|
17
|
+
// #region Client API endpoints
|
|
18
|
+
export const CLIENT_API_ROOT = `${GAMMA_ROOT}/api/client/v1` as const
|
|
19
|
+
export const CLIENT_API_GROUPS = `${CLIENT_API_ROOT}/groups` as const
|
|
20
|
+
export const CLIENT_API_GROUPS_FOR = `${CLIENT_API_GROUPS}/for` as const
|
|
21
|
+
export function clientApiGroupsFor(id: UserId): ClientApiGroupsForUrl {
|
|
22
|
+
return `${CLIENT_API_GROUPS_FOR}/${id}`
|
|
23
|
+
}
|
|
24
|
+
export const CLIENT_API_SUPER_GROUPS = `${CLIENT_API_ROOT}/superGroups` as const
|
|
25
|
+
export const CLIENT_API_USERS = `${CLIENT_API_ROOT}/users` as const
|
|
26
|
+
export function clientApiUser(id: UserId): ClientApiUserUrl {
|
|
27
|
+
return `${CLIENT_API_USERS}/${id}`
|
|
28
|
+
}
|
|
29
|
+
export const CLIENT_API_AUTHORITIES = `${CLIENT_API_ROOT}/authorities` as const
|
|
30
|
+
export const CLIENT_API_AUTHORITIES_FOR = `${CLIENT_API_AUTHORITIES}/for` as const
|
|
31
|
+
export function clientApiAuthoritiesFor(id: UserId): ClientApiAuthoritiesForUrl {
|
|
32
|
+
return `${CLIENT_API_AUTHORITIES_FOR}/${id}`
|
|
33
|
+
}
|
|
34
|
+
// #endregion Client API endpoints
|
|
35
|
+
|
|
36
|
+
// #region Info API endpoints
|
|
37
|
+
export const INFO_API_ROOT = `${GAMMA_ROOT}/api/info/v1` as const
|
|
38
|
+
export const INFO_API_USERS = `${INFO_API_ROOT}/users` as const
|
|
39
|
+
export function infoApiUser(id: UserId): InfoApiUserUrl {
|
|
40
|
+
return `${INFO_API_USERS}/${id}`
|
|
41
|
+
}
|
|
42
|
+
export const INFO_API_BLOB = `${INFO_API_ROOT}/blob` as const
|
|
43
|
+
// #endregion Info API endpoints
|
|
44
|
+
|
|
45
|
+
// #region Images
|
|
46
|
+
export const IMAGES = `${GAMMA_ROOT}/images` as const
|
|
47
|
+
export const IMAGES_USER_AVATAR = `${IMAGES}/user/avatar` as const
|
|
48
|
+
export function userAvatarUrl(id: UserId): UserAvatarUrl {
|
|
49
|
+
return `${IMAGES_USER_AVATAR}/${id}`
|
|
50
|
+
}
|
|
51
|
+
export const IMAGES_GROUP_AVATAR = `${IMAGES}/group/avatar` as const
|
|
52
|
+
export function groupAvatarUrl(id: GroupId): GroupAvatarUrl {
|
|
53
|
+
return `${IMAGES_GROUP_AVATAR}/${id}`
|
|
54
|
+
}
|
|
55
|
+
export const IMAGES_GROUP_BANNER = `${IMAGES}/group/banner` as const
|
|
56
|
+
export function groupBannerUrl(id: GroupId): GroupBannerUrl {
|
|
57
|
+
return `${IMAGES_GROUP_BANNER}/${id}`
|
|
58
|
+
}
|
|
59
|
+
export const IMAGES_SUPER_GROUP_AVATAR = `${IMAGES}/super-group/avatar` as const
|
|
60
|
+
export function superGroupAvatarUrl(id: SuperGroupId): SuperGroupAvatarUrl {
|
|
61
|
+
return `${IMAGES_SUPER_GROUP_AVATAR}/${id}`
|
|
62
|
+
}
|
|
63
|
+
export const IMAGES_SUPER_GROUP_BANNER = `${IMAGES}/super-group/banner` as const
|
|
64
|
+
export function superGroupBannerUrl(id: SuperGroupId): SuperGroupBannerUrl {
|
|
65
|
+
return `${IMAGES_SUPER_GROUP_BANNER}/${id}`
|
|
66
|
+
}
|
|
67
|
+
// #endregion Images
|