webuntis-client 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/README.md +5 -0
- package/dist/Credentials.d.ts +16 -0
- package/dist/Credentials.d.ts.map +1 -0
- package/dist/Credentials.js +34 -0
- package/dist/WebUntis.d.ts +108 -0
- package/dist/WebUntis.d.ts.map +1 -0
- package/dist/WebUntis.js +192 -0
- package/dist/clients/Api.d.ts +28 -0
- package/dist/clients/Api.d.ts.map +1 -0
- package/dist/clients/Api.js +58 -0
- package/dist/clients/Http.d.ts +22 -0
- package/dist/clients/Http.d.ts.map +1 -0
- package/dist/clients/Http.js +71 -0
- package/dist/clients/JsonRpc.d.ts +23 -0
- package/dist/clients/JsonRpc.d.ts.map +1 -0
- package/dist/clients/JsonRpc.js +62 -0
- package/dist/errors/Authentication.d.ts +5 -0
- package/dist/errors/Authentication.d.ts.map +1 -0
- package/dist/errors/Authentication.js +8 -0
- package/dist/errors/Network.d.ts +6 -0
- package/dist/errors/Network.d.ts.map +1 -0
- package/dist/errors/Network.js +10 -0
- package/dist/errors/Validation.d.ts +5 -0
- package/dist/errors/Validation.d.ts.map +1 -0
- package/dist/errors/Validation.js +8 -0
- package/dist/errors/WebUntis.d.ts +5 -0
- package/dist/errors/WebUntis.d.ts.map +1 -0
- package/dist/errors/WebUntis.js +9 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/managers/Authentication.d.ts +37 -0
- package/dist/managers/Authentication.d.ts.map +1 -0
- package/dist/managers/Authentication.js +65 -0
- package/dist/managers/Token.d.ts +43 -0
- package/dist/managers/Token.d.ts.map +1 -0
- package/dist/managers/Token.js +92 -0
- package/dist/services/AppData.d.ts +76 -0
- package/dist/services/AppData.d.ts.map +1 -0
- package/dist/services/AppData.js +130 -0
- package/dist/services/Profile.d.ts +14 -0
- package/dist/services/Profile.d.ts.map +1 -0
- package/dist/services/Profile.js +16 -0
- package/dist/services/Timetable.d.ts +24 -0
- package/dist/services/Timetable.d.ts.map +1 -0
- package/dist/services/Timetable.js +46 -0
- package/dist/types/app-data.d.ts +72 -0
- package/dist/types/app-data.d.ts.map +1 -0
- package/dist/types/app-data.js +1 -0
- package/dist/types/jsonrpc.d.ts +11 -0
- package/dist/types/jsonrpc.d.ts.map +1 -0
- package/dist/types/jsonrpc.js +1 -0
- package/dist/types/profile.d.ts +31 -0
- package/dist/types/profile.d.ts.map +1 -0
- package/dist/types/profile.js +1 -0
- package/dist/types/session.d.ts +7 -0
- package/dist/types/session.d.ts.map +1 -0
- package/dist/types/session.js +1 -0
- package/dist/types/timetable.d.ts +86 -0
- package/dist/types/timetable.d.ts.map +1 -0
- package/dist/types/timetable.js +1 -0
- package/package.json +49 -0
package/README.md
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare class Credentials {
|
|
2
|
+
private readonly _identity;
|
|
3
|
+
private readonly _school;
|
|
4
|
+
private readonly _username;
|
|
5
|
+
private readonly _password;
|
|
6
|
+
private readonly _url;
|
|
7
|
+
private readonly _schoolBase64;
|
|
8
|
+
constructor(_identity: string, _school: string, _username: string, _password: string);
|
|
9
|
+
get identity(): string;
|
|
10
|
+
get school(): string;
|
|
11
|
+
get username(): string;
|
|
12
|
+
get password(): string;
|
|
13
|
+
get url(): string;
|
|
14
|
+
get schoolBase64(): string;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=Credentials.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Credentials.d.ts","sourceRoot":"","sources":["../src/Credentials.ts"],"names":[],"mappings":"AAAA,qBAAa,WAAW;IAKhB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAP9B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;gBAGlB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM;IAMtC,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED,IAAI,GAAG,IAAI,MAAM,CAEhB;IAED,IAAI,YAAY,IAAI,MAAM,CAEzB;CACJ"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export class Credentials {
|
|
2
|
+
_identity;
|
|
3
|
+
_school;
|
|
4
|
+
_username;
|
|
5
|
+
_password;
|
|
6
|
+
_url;
|
|
7
|
+
_schoolBase64;
|
|
8
|
+
constructor(_identity, _school, _username, _password) {
|
|
9
|
+
this._identity = _identity;
|
|
10
|
+
this._school = _school;
|
|
11
|
+
this._username = _username;
|
|
12
|
+
this._password = _password;
|
|
13
|
+
this._url = `https://${_school}.webuntis.com`;
|
|
14
|
+
this._schoolBase64 = "_" + Buffer.from(_school).toString("base64");
|
|
15
|
+
}
|
|
16
|
+
get identity() {
|
|
17
|
+
return this._identity;
|
|
18
|
+
}
|
|
19
|
+
get school() {
|
|
20
|
+
return this._school;
|
|
21
|
+
}
|
|
22
|
+
get username() {
|
|
23
|
+
return this._username;
|
|
24
|
+
}
|
|
25
|
+
get password() {
|
|
26
|
+
return this._password;
|
|
27
|
+
}
|
|
28
|
+
get url() {
|
|
29
|
+
return this._url;
|
|
30
|
+
}
|
|
31
|
+
get schoolBase64() {
|
|
32
|
+
return this._schoolBase64;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { Credentials } from "./Credentials";
|
|
2
|
+
import { AppData, CurrentSchoolYear, Holiday, OneDriveData, Tenant, User } from './types/app-data';
|
|
3
|
+
import { Profile } from "./types/profile";
|
|
4
|
+
import { SessionInfo } from "./types/session";
|
|
5
|
+
import { TimetableResponse } from "./types/timetable";
|
|
6
|
+
export declare class WebUntisClient {
|
|
7
|
+
private readonly _httpClient;
|
|
8
|
+
private readonly _apiClient;
|
|
9
|
+
private readonly _rpcClient;
|
|
10
|
+
private readonly _authManager;
|
|
11
|
+
private readonly _tokenManager;
|
|
12
|
+
private readonly _appDataService;
|
|
13
|
+
private readonly _profileService;
|
|
14
|
+
private readonly _timetableService;
|
|
15
|
+
constructor(credentials: Credentials);
|
|
16
|
+
/**
|
|
17
|
+
* Login to WebUntis
|
|
18
|
+
*/
|
|
19
|
+
login(): Promise<SessionInfo>;
|
|
20
|
+
/**
|
|
21
|
+
* Logout and end session
|
|
22
|
+
*/
|
|
23
|
+
logout(): Promise<void>;
|
|
24
|
+
/**
|
|
25
|
+
* Check if currently authenticated
|
|
26
|
+
*/
|
|
27
|
+
isAuthenticated(): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Get current session info
|
|
30
|
+
*/
|
|
31
|
+
getSession(): SessionInfo | null;
|
|
32
|
+
/**
|
|
33
|
+
* Get app data
|
|
34
|
+
*/
|
|
35
|
+
getAppData(): Promise<AppData>;
|
|
36
|
+
/**
|
|
37
|
+
* Get current school year from cache
|
|
38
|
+
*/
|
|
39
|
+
getCurrentSchoolYear(): CurrentSchoolYear;
|
|
40
|
+
/**
|
|
41
|
+
* Get current school year id from cache
|
|
42
|
+
*/
|
|
43
|
+
getCurrentSchoolYearId(): string;
|
|
44
|
+
/**
|
|
45
|
+
* Get departments from cache
|
|
46
|
+
*/
|
|
47
|
+
getDepartments(): unknown[];
|
|
48
|
+
/**
|
|
49
|
+
* Check if playground mode is enabled
|
|
50
|
+
*/
|
|
51
|
+
isPlayground(): boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Get OneDrive data from cache
|
|
54
|
+
*/
|
|
55
|
+
getOneDriveData(): OneDriveData;
|
|
56
|
+
/**
|
|
57
|
+
* Get tenant information from cache
|
|
58
|
+
*/
|
|
59
|
+
getTenant(): Tenant;
|
|
60
|
+
/**
|
|
61
|
+
* Check if UI 2020 is enabled
|
|
62
|
+
*/
|
|
63
|
+
isUi2020(): boolean;
|
|
64
|
+
/**
|
|
65
|
+
* Get user information from cache
|
|
66
|
+
*/
|
|
67
|
+
getUser(): User;
|
|
68
|
+
/**
|
|
69
|
+
* Get user permissions from cache
|
|
70
|
+
*/
|
|
71
|
+
getPermissions(): string[];
|
|
72
|
+
/**
|
|
73
|
+
* Get settings from cache
|
|
74
|
+
*/
|
|
75
|
+
getSettings(): string[];
|
|
76
|
+
/**
|
|
77
|
+
* Get polling jobs from cache
|
|
78
|
+
*/
|
|
79
|
+
getPollingJobs(): unknown[];
|
|
80
|
+
/**
|
|
81
|
+
* Check if support access is open
|
|
82
|
+
*/
|
|
83
|
+
isSupportAccessOpen(): boolean;
|
|
84
|
+
/**
|
|
85
|
+
* Get license expiration date from cache
|
|
86
|
+
*/
|
|
87
|
+
getLicenceExpiresAt(): string;
|
|
88
|
+
/**
|
|
89
|
+
* Get holidays from cache
|
|
90
|
+
*/
|
|
91
|
+
getHolidays(): Holiday[];
|
|
92
|
+
/**
|
|
93
|
+
* Get current user's profile
|
|
94
|
+
*/
|
|
95
|
+
getProfile(): Promise<Profile>;
|
|
96
|
+
/**
|
|
97
|
+
* Get own timetable for date range
|
|
98
|
+
*
|
|
99
|
+
* @param start - Start date
|
|
100
|
+
* @param end - End date
|
|
101
|
+
*/
|
|
102
|
+
getOwnTimetable(start: Date, end: Date): Promise<TimetableResponse>;
|
|
103
|
+
/**
|
|
104
|
+
* Ensure user is authenticated
|
|
105
|
+
*/
|
|
106
|
+
private _ensureAuthenticated;
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=WebUntis.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WebUntis.d.ts","sourceRoot":"","sources":["../src/WebUntis.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAO5C,OAAO,EAAE,OAAO,EAAE,iBAAiB,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACnG,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEtD,qBAAa,cAAc;IAEvB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAa;IACzC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAY;IACvC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAgB;IAG3C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAwB;IACrD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAe;IAG7C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAiB;IACjD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAiB;IACjD,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAmB;gBAEzC,WAAW,EAAE,WAAW;IAgCpC;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,WAAW,CAAC;IASnC;;OAEG;IACG,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAM7B;;OAEG;IACH,eAAe,IAAI,OAAO;IAI1B;;OAEG;IACH,UAAU,IAAI,WAAW,GAAG,IAAI;IAQhC;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC;IAKpC;;OAEG;IACH,oBAAoB,IAAI,iBAAiB;IAIzC;;OAEG;IACH,sBAAsB,IAAI,MAAM;IAIhC;;OAEG;IACH,cAAc,IAAI,OAAO,EAAE;IAI3B;;OAEG;IACH,YAAY,IAAI,OAAO;IAIvB;;OAEG;IACH,eAAe,IAAI,YAAY;IAI/B;;OAEG;IACH,SAAS,IAAI,MAAM;IAInB;;OAEG;IACH,QAAQ,IAAI,OAAO;IAInB;;OAEG;IACH,OAAO,IAAI,IAAI;IAIf;;OAEG;IACH,cAAc,IAAI,MAAM,EAAE;IAI1B;;OAEG;IACH,WAAW,IAAI,MAAM,EAAE;IAIvB;;OAEG;IACH,cAAc,IAAI,OAAO,EAAE;IAI3B;;OAEG;IACH,mBAAmB,IAAI,OAAO;IAI9B;;OAEG;IACH,mBAAmB,IAAI,MAAM;IAI7B;;OAEG;IACH,WAAW,IAAI,OAAO,EAAE;IAQxB;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC;IASpC;;;;;OAKG;IACG,eAAe,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,GAAG,OAAO,CAAC,iBAAiB,CAAC;IASzE;;OAEG;IACH,OAAO,CAAC,oBAAoB;CAS/B"}
|
package/dist/WebUntis.js
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import { ApiClient } from "./clients/Api";
|
|
2
|
+
import { HttpClient } from "./clients/Http";
|
|
3
|
+
import { JsonRpcClient } from "./clients/JsonRpc";
|
|
4
|
+
import { ValidationError } from "./errors/Validation";
|
|
5
|
+
import { AuthenticationManager } from "./managers/Authentication";
|
|
6
|
+
import { TokenManager } from "./managers/Token";
|
|
7
|
+
import { AppDataService } from "./services/AppData";
|
|
8
|
+
import { ProfileService } from "./services/Profile";
|
|
9
|
+
import { TimetableService } from "./services/Timetable";
|
|
10
|
+
export class WebUntisClient {
|
|
11
|
+
// Clients
|
|
12
|
+
_httpClient;
|
|
13
|
+
_apiClient;
|
|
14
|
+
_rpcClient;
|
|
15
|
+
// Managers
|
|
16
|
+
_authManager;
|
|
17
|
+
_tokenManager;
|
|
18
|
+
// Services
|
|
19
|
+
_appDataService;
|
|
20
|
+
_profileService;
|
|
21
|
+
_timetableService;
|
|
22
|
+
constructor(credentials) {
|
|
23
|
+
const { identity, url } = credentials;
|
|
24
|
+
// Clients
|
|
25
|
+
this._httpClient = new HttpClient(url);
|
|
26
|
+
this._rpcClient = new JsonRpcClient(identity, url);
|
|
27
|
+
// Managers
|
|
28
|
+
this._authManager = new AuthenticationManager(credentials, this._rpcClient);
|
|
29
|
+
this._tokenManager = new TokenManager(this._httpClient, () => this._authManager.getCookies());
|
|
30
|
+
// Clients
|
|
31
|
+
this._apiClient = new ApiClient(this._httpClient, () => this._authManager.getCookies(), () => this._tokenManager.getToken(), () => this._tokenManager.getTenantId(), () => this.getCurrentSchoolYearId());
|
|
32
|
+
// Services
|
|
33
|
+
this._appDataService = new AppDataService(this._apiClient);
|
|
34
|
+
this._profileService = new ProfileService(this._apiClient);
|
|
35
|
+
this._timetableService = new TimetableService(this._apiClient, this._authManager);
|
|
36
|
+
}
|
|
37
|
+
//#region Authentication
|
|
38
|
+
/**
|
|
39
|
+
* Login to WebUntis
|
|
40
|
+
*/
|
|
41
|
+
async login() {
|
|
42
|
+
const session = await this._authManager.login();
|
|
43
|
+
await this._tokenManager.getToken();
|
|
44
|
+
await this._appDataService.getAppData();
|
|
45
|
+
return session;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Logout and end session
|
|
49
|
+
*/
|
|
50
|
+
async logout() {
|
|
51
|
+
await this._authManager.logout();
|
|
52
|
+
this._tokenManager.clearToken();
|
|
53
|
+
this._appDataService.clearCache();
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Check if currently authenticated
|
|
57
|
+
*/
|
|
58
|
+
isAuthenticated() {
|
|
59
|
+
return this._authManager.isAuthenticated();
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Get current session info
|
|
63
|
+
*/
|
|
64
|
+
getSession() {
|
|
65
|
+
return this._authManager.getSession();
|
|
66
|
+
}
|
|
67
|
+
//#endregion
|
|
68
|
+
//#region App Data
|
|
69
|
+
/**
|
|
70
|
+
* Get app data
|
|
71
|
+
*/
|
|
72
|
+
async getAppData() {
|
|
73
|
+
this._ensureAuthenticated();
|
|
74
|
+
return await this._appDataService.getAppData();
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Get current school year from cache
|
|
78
|
+
*/
|
|
79
|
+
getCurrentSchoolYear() {
|
|
80
|
+
return this._appDataService.getCurrentSchoolYear();
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Get current school year id from cache
|
|
84
|
+
*/
|
|
85
|
+
getCurrentSchoolYearId() {
|
|
86
|
+
return this._appDataService.getCurrentSchoolYearId();
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Get departments from cache
|
|
90
|
+
*/
|
|
91
|
+
getDepartments() {
|
|
92
|
+
return this._appDataService.getDepartments();
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Check if playground mode is enabled
|
|
96
|
+
*/
|
|
97
|
+
isPlayground() {
|
|
98
|
+
return this._appDataService.isPlayground();
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Get OneDrive data from cache
|
|
102
|
+
*/
|
|
103
|
+
getOneDriveData() {
|
|
104
|
+
return this._appDataService.getOneDriveData();
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Get tenant information from cache
|
|
108
|
+
*/
|
|
109
|
+
getTenant() {
|
|
110
|
+
return this._appDataService.getTenant();
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Check if UI 2020 is enabled
|
|
114
|
+
*/
|
|
115
|
+
isUi2020() {
|
|
116
|
+
return this._appDataService.isUi2020();
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Get user information from cache
|
|
120
|
+
*/
|
|
121
|
+
getUser() {
|
|
122
|
+
return this._appDataService.getUser();
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Get user permissions from cache
|
|
126
|
+
*/
|
|
127
|
+
getPermissions() {
|
|
128
|
+
return this._appDataService.getPermissions();
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Get settings from cache
|
|
132
|
+
*/
|
|
133
|
+
getSettings() {
|
|
134
|
+
return this._appDataService.getSettings();
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Get polling jobs from cache
|
|
138
|
+
*/
|
|
139
|
+
getPollingJobs() {
|
|
140
|
+
return this._appDataService.getPollingJobs();
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Check if support access is open
|
|
144
|
+
*/
|
|
145
|
+
isSupportAccessOpen() {
|
|
146
|
+
return this._appDataService.isSupportAccessOpen();
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Get license expiration date from cache
|
|
150
|
+
*/
|
|
151
|
+
getLicenceExpiresAt() {
|
|
152
|
+
return this._appDataService.getLicenceExpiresAt();
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Get holidays from cache
|
|
156
|
+
*/
|
|
157
|
+
getHolidays() {
|
|
158
|
+
return this._appDataService.getHolidays();
|
|
159
|
+
}
|
|
160
|
+
//#endregion
|
|
161
|
+
//#region User's Profile
|
|
162
|
+
/**
|
|
163
|
+
* Get current user's profile
|
|
164
|
+
*/
|
|
165
|
+
async getProfile() {
|
|
166
|
+
this._ensureAuthenticated();
|
|
167
|
+
return await this._profileService.getProfile();
|
|
168
|
+
}
|
|
169
|
+
//#endregion
|
|
170
|
+
//#region Own Timetable
|
|
171
|
+
/**
|
|
172
|
+
* Get own timetable for date range
|
|
173
|
+
*
|
|
174
|
+
* @param start - Start date
|
|
175
|
+
* @param end - End date
|
|
176
|
+
*/
|
|
177
|
+
async getOwnTimetable(start, end) {
|
|
178
|
+
this._ensureAuthenticated();
|
|
179
|
+
return await this._timetableService.getOwnTimetable(start, end);
|
|
180
|
+
}
|
|
181
|
+
//#endregion
|
|
182
|
+
//#region Helpers
|
|
183
|
+
/**
|
|
184
|
+
* Ensure user is authenticated
|
|
185
|
+
*/
|
|
186
|
+
_ensureAuthenticated() {
|
|
187
|
+
const isNotAuthenticated = !this._authManager.isAuthenticated();
|
|
188
|
+
if (isNotAuthenticated) {
|
|
189
|
+
throw new ValidationError('Not authenticated. Please call login() first.');
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { AppData } from '../types/app-data';
|
|
2
|
+
import { ProfileResponse } from '../types/profile';
|
|
3
|
+
import { TimetableResponse } from '../types/timetable';
|
|
4
|
+
import { HttpClient } from './Http';
|
|
5
|
+
/**
|
|
6
|
+
* Client for WebUntis REST API endpoints
|
|
7
|
+
*/
|
|
8
|
+
export declare class ApiClient {
|
|
9
|
+
private readonly _httpClient;
|
|
10
|
+
private readonly _getCookies;
|
|
11
|
+
private readonly _getToken;
|
|
12
|
+
private readonly _getTenantId;
|
|
13
|
+
private readonly _getSchoolYearId;
|
|
14
|
+
constructor(_httpClient: HttpClient, _getCookies: () => string, _getToken: () => Promise<string>, _getTenantId: () => string | null, _getSchoolYearId: () => string);
|
|
15
|
+
/**
|
|
16
|
+
* Fetch app data
|
|
17
|
+
*/
|
|
18
|
+
fetchAppData(): Promise<AppData>;
|
|
19
|
+
/**
|
|
20
|
+
* Fetch user profile data
|
|
21
|
+
*/
|
|
22
|
+
fetchProfile(): Promise<ProfileResponse>;
|
|
23
|
+
/**
|
|
24
|
+
* Fetch timetable entries
|
|
25
|
+
*/
|
|
26
|
+
fetchOwnTimetable(params: URLSearchParams): Promise<TimetableResponse>;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=Api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Api.d.ts","sourceRoot":"","sources":["../../src/clients/Api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAEpC;;GAEG;AACH,qBAAa,SAAS;IAEd,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,gBAAgB;gBAJhB,WAAW,EAAE,UAAU,EACvB,WAAW,EAAE,MAAM,MAAM,EACzB,SAAS,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,EAChC,YAAY,EAAE,MAAM,MAAM,GAAG,IAAI,EACjC,gBAAgB,EAAE,MAAM,MAAM;IAGnD;;OAEG;IACG,YAAY,IAAI,OAAO,CAAC,OAAO,CAAC;IAmBtC;;OAEG;IACG,YAAY,IAAI,OAAO,CAAC,eAAe,CAAC;IAS9C;;OAEG;IACG,iBAAiB,CACnB,MAAM,EAAE,eAAe,GACxB,OAAO,CAAC,iBAAiB,CAAC;CAoBhC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client for WebUntis REST API endpoints
|
|
3
|
+
*/
|
|
4
|
+
export class ApiClient {
|
|
5
|
+
_httpClient;
|
|
6
|
+
_getCookies;
|
|
7
|
+
_getToken;
|
|
8
|
+
_getTenantId;
|
|
9
|
+
_getSchoolYearId;
|
|
10
|
+
constructor(_httpClient, _getCookies, _getToken, _getTenantId, _getSchoolYearId) {
|
|
11
|
+
this._httpClient = _httpClient;
|
|
12
|
+
this._getCookies = _getCookies;
|
|
13
|
+
this._getToken = _getToken;
|
|
14
|
+
this._getTenantId = _getTenantId;
|
|
15
|
+
this._getSchoolYearId = _getSchoolYearId;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Fetch app data
|
|
19
|
+
*/
|
|
20
|
+
async fetchAppData() {
|
|
21
|
+
const token = await this._getToken();
|
|
22
|
+
const tenantId = this._getTenantId();
|
|
23
|
+
const cookies = this._getCookies();
|
|
24
|
+
if (!tenantId) {
|
|
25
|
+
throw new Error('Tenant ID not available');
|
|
26
|
+
}
|
|
27
|
+
return this._httpClient.get('/WebUntis/api/rest/view/v1/app/data', {
|
|
28
|
+
Authorization: `Bearer ${token}`,
|
|
29
|
+
'tenant-id': tenantId,
|
|
30
|
+
Cookie: cookies,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Fetch user profile data
|
|
35
|
+
*/
|
|
36
|
+
async fetchProfile() {
|
|
37
|
+
const cookies = this._getCookies();
|
|
38
|
+
return this._httpClient.get('/WebUntis/api/profile/general', { Cookie: cookies });
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Fetch timetable entries
|
|
42
|
+
*/
|
|
43
|
+
async fetchOwnTimetable(params) {
|
|
44
|
+
const token = await this._getToken();
|
|
45
|
+
const tenantId = this._getTenantId();
|
|
46
|
+
const cookies = this._getCookies();
|
|
47
|
+
const schoolYearId = this._getSchoolYearId();
|
|
48
|
+
if (!tenantId) {
|
|
49
|
+
throw new Error('Tenant ID not available');
|
|
50
|
+
}
|
|
51
|
+
return await this._httpClient.get(`/WebUntis/api/rest/view/v1/timetable/entries?${params}`, {
|
|
52
|
+
Authorization: `Bearer ${token}`,
|
|
53
|
+
'tenant-id': tenantId,
|
|
54
|
+
'x-webuntis-api-school-year-id': schoolYearId,
|
|
55
|
+
Cookie: cookies,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export declare class HttpClient {
|
|
2
|
+
private readonly _url;
|
|
3
|
+
private readonly _defaultHeaders;
|
|
4
|
+
constructor(_url: string);
|
|
5
|
+
/**
|
|
6
|
+
* Make a GET request
|
|
7
|
+
*/
|
|
8
|
+
get<T>(endpoint: string, headers?: Record<string, string>): Promise<T>;
|
|
9
|
+
/**
|
|
10
|
+
* Make a POST request
|
|
11
|
+
*/
|
|
12
|
+
post<T>(endpoint: string, body?: Record<string, unknown>, headers?: Record<string, string>): Promise<T>;
|
|
13
|
+
/**
|
|
14
|
+
* Make a GET request that returns text
|
|
15
|
+
*/
|
|
16
|
+
getText(endpoint: string, headers?: Record<string, string>): Promise<string>;
|
|
17
|
+
/**
|
|
18
|
+
* Handle HTTP response and errors
|
|
19
|
+
*/
|
|
20
|
+
private _handleResponse;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=Http.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Http.d.ts","sourceRoot":"","sources":["../../src/clients/Http.ts"],"names":[],"mappings":"AAGA,qBAAa,UAAU;IAQP,OAAO,CAAC,QAAQ,CAAC,IAAI;IAPjC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAK9B;gBAE2B,IAAI,EAAE,MAAM;IAEzC;;OAEG;IACG,GAAG,CAAC,CAAC,EACP,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACjC,OAAO,CAAC,CAAC,CAAC;IAeb;;OAEG;IACG,IAAI,CAAC,CAAC,EACR,QAAQ,EAAE,MAAM,EAChB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACjC,OAAO,CAAC,CAAC,CAAC;IAkBb;;OAEG;IACG,OAAO,CACT,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACjC,OAAO,CAAC,MAAM,CAAC;IAsBlB;;OAEG;YACW,eAAe;CAgBhC"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { NetworkError } from "../errors/Network";
|
|
2
|
+
export class HttpClient {
|
|
3
|
+
_url;
|
|
4
|
+
_defaultHeaders = {
|
|
5
|
+
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.79 Safari/537.36',
|
|
6
|
+
'Cache-Control': 'no-cache',
|
|
7
|
+
'X-Requested-With': 'XMLHttpRequest',
|
|
8
|
+
Pragma: 'no-cache',
|
|
9
|
+
};
|
|
10
|
+
constructor(_url) {
|
|
11
|
+
this._url = _url;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Make a GET request
|
|
15
|
+
*/
|
|
16
|
+
async get(endpoint, headers) {
|
|
17
|
+
const response = await fetch(`${this._url}${endpoint}`, {
|
|
18
|
+
method: 'GET',
|
|
19
|
+
headers: {
|
|
20
|
+
...this._defaultHeaders,
|
|
21
|
+
...headers,
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
return this._handleResponse(response);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Make a POST request
|
|
28
|
+
*/
|
|
29
|
+
async post(endpoint, body, headers) {
|
|
30
|
+
const response = await fetch(`${this._url}${endpoint}`, {
|
|
31
|
+
method: 'POST',
|
|
32
|
+
headers: {
|
|
33
|
+
...this._defaultHeaders,
|
|
34
|
+
'Content-Type': 'application/json',
|
|
35
|
+
...headers,
|
|
36
|
+
},
|
|
37
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
38
|
+
redirect: 'manual',
|
|
39
|
+
});
|
|
40
|
+
return this._handleResponse(response);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Make a GET request that returns text
|
|
44
|
+
*/
|
|
45
|
+
async getText(endpoint, headers) {
|
|
46
|
+
const response = await fetch(`${this._url}${endpoint}`, {
|
|
47
|
+
method: 'GET',
|
|
48
|
+
headers: {
|
|
49
|
+
...this._defaultHeaders,
|
|
50
|
+
...headers,
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
if (!response.ok) {
|
|
54
|
+
throw new NetworkError(`HTTP ${response.status}: ${response.statusText}`, response.status);
|
|
55
|
+
}
|
|
56
|
+
return response.text();
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Handle HTTP response and errors
|
|
60
|
+
*/
|
|
61
|
+
async _handleResponse(response) {
|
|
62
|
+
if (response.status < 200 || response.status >= 303) {
|
|
63
|
+
throw new NetworkError(`HTTP ${response.status}: ${response.statusText}`, response.status);
|
|
64
|
+
}
|
|
65
|
+
const contentType = response.headers.get('content-type');
|
|
66
|
+
if (contentType?.includes('application/json')) {
|
|
67
|
+
return response.json();
|
|
68
|
+
}
|
|
69
|
+
return response.text();
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { SessionInfo } from '../types/session';
|
|
2
|
+
/**
|
|
3
|
+
* JSON-RPC client for WebUntis API
|
|
4
|
+
*/
|
|
5
|
+
export declare class JsonRpcClient {
|
|
6
|
+
private readonly _identity;
|
|
7
|
+
private readonly _httpClient;
|
|
8
|
+
private readonly _endpoint;
|
|
9
|
+
constructor(_identity: string, url: string);
|
|
10
|
+
/**
|
|
11
|
+
* Authenticate user and get session
|
|
12
|
+
*/
|
|
13
|
+
authenticate(username: string, password: string, client: string): Promise<SessionInfo>;
|
|
14
|
+
/**
|
|
15
|
+
* Logout and end session
|
|
16
|
+
*/
|
|
17
|
+
logout(cookies: string): Promise<void>;
|
|
18
|
+
/**
|
|
19
|
+
* Make a JSON-RPC call
|
|
20
|
+
*/
|
|
21
|
+
private _call;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=JsonRpc.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"JsonRpc.d.ts","sourceRoot":"","sources":["../../src/clients/JsonRpc.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAG/C;;GAEG;AACH,qBAAa,aAAa;IAKlB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAJ9B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAa;IACzC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA0B;gBAG/B,SAAS,EAAE,MAAM,EAClC,GAAG,EAAE,MAAM;IAKf;;OAEG;IACG,YAAY,CACd,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,GACf,OAAO,CAAC,WAAW,CAAC;IAyBvB;;OAEG;IACG,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI5C;;OAEG;YACW,KAAK;CAiCtB"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { AuthenticationError } from '../errors/Authentication';
|
|
2
|
+
import { HttpClient } from './Http';
|
|
3
|
+
/**
|
|
4
|
+
* JSON-RPC client for WebUntis API
|
|
5
|
+
*/
|
|
6
|
+
export class JsonRpcClient {
|
|
7
|
+
_identity;
|
|
8
|
+
_httpClient;
|
|
9
|
+
_endpoint = '/WebUntis/jsonrpc.do';
|
|
10
|
+
constructor(_identity, url) {
|
|
11
|
+
this._identity = _identity;
|
|
12
|
+
this._httpClient = new HttpClient(url);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Authenticate user and get session
|
|
16
|
+
*/
|
|
17
|
+
async authenticate(username, password, client) {
|
|
18
|
+
try {
|
|
19
|
+
const result = await this._call('authenticate', {
|
|
20
|
+
user: username,
|
|
21
|
+
password: password,
|
|
22
|
+
client: client,
|
|
23
|
+
});
|
|
24
|
+
if (!result.sessionId) {
|
|
25
|
+
throw new AuthenticationError('Authentication failed: No session ID returned');
|
|
26
|
+
}
|
|
27
|
+
return result;
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
if (error instanceof AuthenticationError) {
|
|
31
|
+
throw error;
|
|
32
|
+
}
|
|
33
|
+
throw new AuthenticationError(`Authentication failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Logout and end session
|
|
38
|
+
*/
|
|
39
|
+
async logout(cookies) {
|
|
40
|
+
await this._call('logout', {}, cookies);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Make a JSON-RPC call
|
|
44
|
+
*/
|
|
45
|
+
async _call(method, params, cookies) {
|
|
46
|
+
const headers = {};
|
|
47
|
+
if (cookies) {
|
|
48
|
+
headers.Cookie = cookies;
|
|
49
|
+
}
|
|
50
|
+
const body = {
|
|
51
|
+
id: this._identity,
|
|
52
|
+
jsonrpc: '2.0',
|
|
53
|
+
method,
|
|
54
|
+
params,
|
|
55
|
+
};
|
|
56
|
+
const response = await this._httpClient.post(this._endpoint, body, headers);
|
|
57
|
+
if (response.error) {
|
|
58
|
+
throw new AuthenticationError(`${response.error.message} (${response.error.code})`, response.error.code.toString());
|
|
59
|
+
}
|
|
60
|
+
return response.result;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Authentication.d.ts","sourceRoot":"","sources":["../../src/errors/Authentication.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,qBAAa,mBAAoB,SAAQ,aAAa;gBACtC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM;CAK7C"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { WebUntisError } from "./WebUntis";
|
|
2
|
+
export declare class NetworkError extends WebUntisError {
|
|
3
|
+
readonly statusCode?: number | undefined;
|
|
4
|
+
constructor(message: string, statusCode?: number | undefined, code?: string);
|
|
5
|
+
}
|
|
6
|
+
//# sourceMappingURL=Network.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Network.d.ts","sourceRoot":"","sources":["../../src/errors/Network.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,qBAAa,YAAa,SAAQ,aAAa;aAGvB,UAAU,CAAC,EAAE,MAAM;gBADnC,OAAO,EAAE,MAAM,EACC,UAAU,CAAC,EAAE,MAAM,YAAA,EACnC,IAAI,CAAC,EAAE,MAAM;CAMpB"}
|