@iotready/nextjs-components-library 1.0.0-preview1
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/components/accounts/AccountMenu.d.ts +9 -0
- package/components/accounts/AccountMenu.js +37 -0
- package/components/accounts/AccountProfile.d.ts +15 -0
- package/components/accounts/AccountProfile.js +153 -0
- package/components/accounts/index.d.ts +2 -0
- package/components/accounts/index.js +2 -0
- package/components/charts/TrendChart.d.ts +17 -0
- package/components/charts/TrendChart.js +454 -0
- package/components/charts/index.d.ts +1 -0
- package/components/charts/index.js +1 -0
- package/components/groups/GroupUpdate.d.ts +24 -0
- package/components/groups/GroupUpdate.js +134 -0
- package/components/groups/GroupsDevices.d.ts +37 -0
- package/components/groups/GroupsDevices.js +299 -0
- package/components/groups/Map.d.ts +14 -0
- package/components/groups/Map.js +17 -0
- package/components/groups/index.d.ts +3 -0
- package/components/groups/index.js +3 -0
- package/components/index.d.ts +5 -0
- package/components/index.js +5 -0
- package/components/settings/DynamicMenu.d.ts +17 -0
- package/components/settings/DynamicMenu.js +42 -0
- package/components/settings/index.d.ts +1 -0
- package/components/settings/index.js +1 -0
- package/components/users/UserUpdate.d.ts +11 -0
- package/components/users/UserUpdate.js +26 -0
- package/components/users/UsersDataGrid.d.ts +23 -0
- package/components/users/UsersDataGrid.js +76 -0
- package/components/users/index.d.ts +2 -0
- package/components/users/index.js +2 -0
- package/index.d.ts +3 -0
- package/index.js +4 -0
- package/package.json +45 -0
- package/server-actions/groups.d.ts +22 -0
- package/server-actions/groups.js +109 -0
- package/server-actions/index.d.ts +4 -0
- package/server-actions/index.js +5 -0
- package/server-actions/influx.d.ts +13 -0
- package/server-actions/influx.js +145 -0
- package/server-actions/logto.d.ts +39 -0
- package/server-actions/logto.js +194 -0
- package/server-actions/trackle.d.ts +35 -0
- package/server-actions/trackle.js +158 -0
- package/types/index.d.ts +1 -0
- package/types/index.js +1 -0
- package/types/user.d.ts +12 -0
- package/types/user.js +1 -0
@@ -0,0 +1,22 @@
|
|
1
|
+
export type FirebaseConfig = {
|
2
|
+
apiKey: string;
|
3
|
+
authDomain: string;
|
4
|
+
projectId: string;
|
5
|
+
storageBucket: string;
|
6
|
+
messagingSenderId: string;
|
7
|
+
appId: string;
|
8
|
+
};
|
9
|
+
export declare const getGroups: (firebaseConfig: FirebaseConfig, productID: number, userID?: string) => Promise<{
|
10
|
+
id: string;
|
11
|
+
}[]>;
|
12
|
+
export declare const getGroupById: (firebaseConfig: FirebaseConfig, id: string) => Promise<{
|
13
|
+
id: string;
|
14
|
+
}>;
|
15
|
+
export declare const createGroup: (firebaseConfig: FirebaseConfig, group: any) => Promise<string>;
|
16
|
+
export declare const updateGroup: (firebaseConfig: FirebaseConfig, id: string, group: any) => Promise<any>;
|
17
|
+
export declare const deleteGroup: (firebaseConfig: FirebaseConfig, id: string) => Promise<void>;
|
18
|
+
export declare const getUsersGroup: (firebaseConfig: FirebaseConfig, groupID: string) => Promise<{
|
19
|
+
id: string;
|
20
|
+
}[]>;
|
21
|
+
export declare const addUsersGroup: (firebaseConfig: FirebaseConfig, groupID: string, userName: string, userID: string) => Promise<string>;
|
22
|
+
export declare const removeUserGroup: (firebaseConfig: FirebaseConfig, groupID: string, userID: string) => Promise<string | undefined>;
|
@@ -0,0 +1,109 @@
|
|
1
|
+
"use server";
|
2
|
+
import { initializeApp } from "firebase/app";
|
3
|
+
import { getDoc, doc, updateDoc, deleteDoc, collection, query, orderBy, getDocs, where, addDoc } from "@firebase/firestore";
|
4
|
+
import { getFirestore } from "@firebase/firestore";
|
5
|
+
export const getGroups = async (firebaseConfig, productID, userID) => {
|
6
|
+
// Initialize Firebase
|
7
|
+
const app = initializeApp(firebaseConfig);
|
8
|
+
const db = getFirestore(app);
|
9
|
+
const groupsQuery = query(collection(db, "groups"), where("productID", "==", productID), orderBy("created", "desc"));
|
10
|
+
let groupIds = null;
|
11
|
+
if (userID) {
|
12
|
+
const usersGroupQuery = query(collection(db, "userGroups"), where("user.userId", "==", userID));
|
13
|
+
const userSnapshot = await getDocs(usersGroupQuery);
|
14
|
+
groupIds = userSnapshot.docs.map((ug) => ug.data().groupId);
|
15
|
+
}
|
16
|
+
const groupsSnapshot = await getDocs(groupsQuery);
|
17
|
+
if (groupIds) {
|
18
|
+
return groupsSnapshot.docs
|
19
|
+
.filter((entry) => groupIds?.includes(entry.id))
|
20
|
+
.map((doc) => ({
|
21
|
+
id: doc.id,
|
22
|
+
...doc.data()
|
23
|
+
}));
|
24
|
+
}
|
25
|
+
return groupsSnapshot.docs.map((doc) => ({
|
26
|
+
id: doc.id,
|
27
|
+
...doc.data()
|
28
|
+
}));
|
29
|
+
};
|
30
|
+
export const getGroupById = async (firebaseConfig, id) => {
|
31
|
+
const app = initializeApp(firebaseConfig);
|
32
|
+
const db = getFirestore(app);
|
33
|
+
const groupSnapshot = await getDoc(doc(db, "groups", id));
|
34
|
+
return {
|
35
|
+
id: groupSnapshot.id,
|
36
|
+
...groupSnapshot.data()
|
37
|
+
};
|
38
|
+
};
|
39
|
+
export const createGroup = async (firebaseConfig, group) => {
|
40
|
+
const created = new Date().toISOString();
|
41
|
+
const newGroup = {
|
42
|
+
...group,
|
43
|
+
created
|
44
|
+
};
|
45
|
+
const app = initializeApp(firebaseConfig);
|
46
|
+
const db = getFirestore(app);
|
47
|
+
const docRef = await addDoc(collection(db, "groups"), newGroup);
|
48
|
+
return docRef.id;
|
49
|
+
};
|
50
|
+
export const updateGroup = async (firebaseConfig, id, group) => {
|
51
|
+
const app = initializeApp(firebaseConfig);
|
52
|
+
const db = getFirestore(app);
|
53
|
+
const groupRef = doc(db, "groups", id);
|
54
|
+
await updateDoc(groupRef, group);
|
55
|
+
return group;
|
56
|
+
};
|
57
|
+
export const deleteGroup = async (firebaseConfig, id) => {
|
58
|
+
const app = initializeApp(firebaseConfig);
|
59
|
+
const db = getFirestore(app);
|
60
|
+
const usersGroupQuery = query(collection(db, "userGroups"), where("groupId", "==", id));
|
61
|
+
const groupsSnapshot = await getDocs(usersGroupQuery);
|
62
|
+
groupsSnapshot.docs.forEach(async (ug) => {
|
63
|
+
const userGroupRef = doc(db, "userGroups", ug.id);
|
64
|
+
await deleteDoc(userGroupRef);
|
65
|
+
});
|
66
|
+
const groupRef = doc(db, "groups", id);
|
67
|
+
await deleteDoc(groupRef);
|
68
|
+
};
|
69
|
+
// USERS GROUPS
|
70
|
+
export const getUsersGroup = async (firebaseConfig, groupID) => {
|
71
|
+
// Initialize Firebase
|
72
|
+
const app = initializeApp(firebaseConfig);
|
73
|
+
const db = getFirestore(app);
|
74
|
+
const usersGroupQuery = query(collection(db, "userGroups"), where("groupId", "==", groupID));
|
75
|
+
const groupsSnapshot = await getDocs(usersGroupQuery);
|
76
|
+
return groupsSnapshot.docs.map((doc) => ({
|
77
|
+
id: doc.id,
|
78
|
+
...doc.data()
|
79
|
+
}));
|
80
|
+
};
|
81
|
+
export const addUsersGroup = async (firebaseConfig, groupID, userName, userID) => {
|
82
|
+
// Initialize Firebase
|
83
|
+
const app = initializeApp(firebaseConfig);
|
84
|
+
const db = getFirestore(app);
|
85
|
+
const created = new Date().toISOString();
|
86
|
+
const newUserGroup = {
|
87
|
+
user: {
|
88
|
+
fullName: userName,
|
89
|
+
userId: userID
|
90
|
+
},
|
91
|
+
groupId: groupID,
|
92
|
+
created
|
93
|
+
};
|
94
|
+
const docRef = await addDoc(collection(db, "userGroups"), newUserGroup);
|
95
|
+
return docRef.id;
|
96
|
+
};
|
97
|
+
export const removeUserGroup = async (firebaseConfig, groupID, userID) => {
|
98
|
+
// Initialize Firebase
|
99
|
+
const app = initializeApp(firebaseConfig);
|
100
|
+
const db = getFirestore(app);
|
101
|
+
const usersGroupQuery = query(collection(db, "userGroups"), where("groupId", "==", groupID), where("user.userId", "==", userID));
|
102
|
+
const groupsSnapshot = await getDocs(usersGroupQuery);
|
103
|
+
if (groupsSnapshot.docs[0]) {
|
104
|
+
const userGroupId = groupsSnapshot.docs[0].id;
|
105
|
+
const groupRef = doc(db, "userGroups", userGroupId);
|
106
|
+
await deleteDoc(groupRef);
|
107
|
+
return userGroupId;
|
108
|
+
}
|
109
|
+
};
|
@@ -0,0 +1,13 @@
|
|
1
|
+
export type InfluxConfig = {
|
2
|
+
url: string;
|
3
|
+
accessToken: string;
|
4
|
+
bucket: string;
|
5
|
+
orgId: string;
|
6
|
+
measurement: string;
|
7
|
+
dbName: string;
|
8
|
+
username: string;
|
9
|
+
password: string;
|
10
|
+
};
|
11
|
+
export declare function getInfluxDataV1(influxConfig: InfluxConfig, field: string, timeStart: number, timeEnd: number, deviceID: string, timeGroup: string, raw: boolean): Promise<any>;
|
12
|
+
export declare function getManyMeasuresV1(influxConfig: InfluxConfig, fields: string[], limit: number, offset: number, sort: any, deviceID: string, timeStart?: number, timeEnd?: number): Promise<any>;
|
13
|
+
export declare function getFirstTimestamp(influxConfig: InfluxConfig, deviceID: string): Promise<any>;
|
@@ -0,0 +1,145 @@
|
|
1
|
+
"use server";
|
2
|
+
import moment from "moment";
|
3
|
+
/* export async function getInfluxDataV2(influxConfig: InfluxConfig, field: string, timeStart: string, timeEnd: string, deviceID: string, timeGroup: string, raw: boolean): Promise<Point[]> {
|
4
|
+
const query = `
|
5
|
+
from(bucket: "${influxConfig.bucket}")
|
6
|
+
|> range(start: ${timeStart}, stop: ${timeEnd})
|
7
|
+
|> filter(fn: (r) => r._measurement == "${influxConfig.measurement}")
|
8
|
+
|> filter(fn: (r) => r["_field"] == "${field}")
|
9
|
+
|> filter(fn: (r) => r["deviceid"] == "${deviceID}")
|
10
|
+
|> aggregateWindow(every: ${timeGroup}m, fn: last, createEmpty: false)
|
11
|
+
|> yield(name: "last")
|
12
|
+
`;
|
13
|
+
|
14
|
+
const response = await fetch(`${influxConfig.url}/api/v2/query?org=${influxConfig.orgId}`, {
|
15
|
+
method: 'POST',
|
16
|
+
headers: {
|
17
|
+
'Content-Type': 'application/json',
|
18
|
+
'Authorization': `Token ${influxConfig.accessToken}`,
|
19
|
+
'Accept': 'application/csv'
|
20
|
+
},
|
21
|
+
body: JSON.stringify({
|
22
|
+
query: query
|
23
|
+
})
|
24
|
+
});
|
25
|
+
if (!response.ok) {
|
26
|
+
throw new Error(`Failed to fetch data from InfluxDB: ${response.statusText}`);
|
27
|
+
}
|
28
|
+
const data = await response.text();
|
29
|
+
return data.split('\n').map(line => {
|
30
|
+
const row = line.split(',');
|
31
|
+
const timestamp = row[5];
|
32
|
+
const value = parseFloat(row[6]);
|
33
|
+
console.log(timestamp, value);
|
34
|
+
if (isNaN(value)) {
|
35
|
+
return null;
|
36
|
+
}
|
37
|
+
return { x: new Date(timestamp).getTime(), y: value };
|
38
|
+
}).filter(point => point !== null);
|
39
|
+
}*/ // NOT WORKING, NEED TO FIX
|
40
|
+
export async function getInfluxDataV1(influxConfig, field, timeStart, timeEnd, deviceID, timeGroup, raw) {
|
41
|
+
let query;
|
42
|
+
if (raw) {
|
43
|
+
query = `SELECT ("value") FROM "${influxConfig.measurement}" WHERE "deviceid" = '${deviceID}' AND "valueName" = '${field}' AND time >= '${moment
|
44
|
+
.unix(timeStart)
|
45
|
+
.toISOString()}' AND time <= '${moment.unix(timeEnd).toISOString()}'`;
|
46
|
+
}
|
47
|
+
else {
|
48
|
+
query = `SELECT last("value") FROM "${influxConfig.measurement}" WHERE "deviceid" = '${deviceID}' AND "valueName" = '${field}' AND time >= '${moment
|
49
|
+
.unix(timeStart)
|
50
|
+
.toISOString()}' AND time <= '${moment
|
51
|
+
.unix(timeEnd)
|
52
|
+
.toISOString()}' GROUP BY time(${timeGroup}) fill(null)`;
|
53
|
+
}
|
54
|
+
const response = await fetch(encodeURI(`${influxConfig.url}/query?db=${influxConfig.dbName}&epoch=s&q=${query}`), {
|
55
|
+
headers: {
|
56
|
+
Authorization: `Basic ${btoa(`${influxConfig.username}:${influxConfig.password}`)}`
|
57
|
+
}
|
58
|
+
});
|
59
|
+
if (!response.ok) {
|
60
|
+
console.log(response);
|
61
|
+
throw new Error(`Failed to fetch data from InfluxDB: ${response.statusText}`);
|
62
|
+
}
|
63
|
+
const data = await response.json();
|
64
|
+
// Ensure the name is manually set to the field
|
65
|
+
if (!data.results[0].series) {
|
66
|
+
// Set default value with null time and null value
|
67
|
+
data.results[0].series = [
|
68
|
+
{
|
69
|
+
name: field, // Manually set the series name as the field
|
70
|
+
columns: ["time", "value"],
|
71
|
+
values: [] // Set null point for time and value
|
72
|
+
}
|
73
|
+
];
|
74
|
+
}
|
75
|
+
else {
|
76
|
+
// Always override the name to be the field
|
77
|
+
data.results[0].series.forEach((series) => {
|
78
|
+
series.name = field; // Force the series name to be the field name
|
79
|
+
});
|
80
|
+
}
|
81
|
+
return data;
|
82
|
+
}
|
83
|
+
export async function getManyMeasuresV1(influxConfig, fields, limit, offset, sort, deviceID, timeStart, timeEnd) {
|
84
|
+
if (fields.length > 0) {
|
85
|
+
const conditions = fields
|
86
|
+
.map((field) => `"valueName" = '${field}'`)
|
87
|
+
.join(" OR ");
|
88
|
+
let queryCount = `SELECT count(*) FROM "${influxConfig.measurement}" WHERE "deviceid" = '${deviceID}' AND (${conditions})`;
|
89
|
+
let queryPagination = `SELECT "valueName", "value" FROM "${influxConfig.measurement}" WHERE "deviceid" = '${deviceID}' AND (${conditions})`;
|
90
|
+
if (timeStart) {
|
91
|
+
queryCount += ` AND time >= '${moment.unix(timeStart).toISOString()}'`;
|
92
|
+
queryPagination += ` AND time >= '${moment
|
93
|
+
.unix(timeStart)
|
94
|
+
.toISOString()}'`;
|
95
|
+
}
|
96
|
+
if (timeEnd) {
|
97
|
+
queryCount += ` AND time <= '${moment.unix(timeEnd).toISOString()}'`;
|
98
|
+
queryPagination += ` AND time <= '${moment.unix(timeEnd).toISOString()}'`;
|
99
|
+
}
|
100
|
+
if (sort && sort.field === "time") {
|
101
|
+
queryPagination = `${queryPagination} ORDER BY "${sort.field}" ${sort.sort}`;
|
102
|
+
}
|
103
|
+
queryPagination = `${queryPagination} LIMIT ${limit} OFFSET ${offset}`;
|
104
|
+
const responses = await Promise.all([
|
105
|
+
fetch(encodeURI(`${influxConfig.url}/query?db=${influxConfig.dbName}&epoch=s&q=${queryPagination}`), {
|
106
|
+
headers: {
|
107
|
+
Authorization: `Basic ${btoa(`${influxConfig.username}:${influxConfig.password}`)}`
|
108
|
+
}
|
109
|
+
}),
|
110
|
+
fetch(encodeURI(`${influxConfig.url}/query?db=${influxConfig.dbName}&epoch=s&q=${queryCount}`), {
|
111
|
+
headers: {
|
112
|
+
Authorization: `Basic ${btoa(`${influxConfig.username}:${influxConfig.password}`)}`
|
113
|
+
}
|
114
|
+
})
|
115
|
+
]);
|
116
|
+
if (!responses[0].ok) {
|
117
|
+
throw new Error(`Failed to fetch data from InfluxDB: ${responses[0].statusText}`);
|
118
|
+
}
|
119
|
+
const data = await responses[0].json();
|
120
|
+
const count = await responses[1].json();
|
121
|
+
return { data, count };
|
122
|
+
}
|
123
|
+
else {
|
124
|
+
return null;
|
125
|
+
}
|
126
|
+
}
|
127
|
+
export async function getFirstTimestamp(influxConfig, deviceID) {
|
128
|
+
// Query per ottenere il primo timestamp e il valore ordinato per "time" in modo crescente
|
129
|
+
const query = `SELECT "time", "value" FROM "${influxConfig.measurement}" WHERE "deviceid" = '${deviceID}' ORDER BY time ASC LIMIT 1`;
|
130
|
+
const response = await fetch(encodeURI(`${influxConfig.url}/query?db=${influxConfig.dbName}&epoch=s&q=${query}`), {
|
131
|
+
headers: {
|
132
|
+
Authorization: `Basic ${btoa(`${influxConfig.username}:${influxConfig.password}`)}`
|
133
|
+
}
|
134
|
+
});
|
135
|
+
if (!response.ok) {
|
136
|
+
throw new Error(`Failed to fetch data from InfluxDB: ${response.statusText}`);
|
137
|
+
}
|
138
|
+
const data = await response.json();
|
139
|
+
// Verifica che ci siano risultati nella risposta
|
140
|
+
if (data?.results[0]?.series && data?.results[0]?.series[0]?.values[0]?.[0]) {
|
141
|
+
// Ritorna il primo timestamp
|
142
|
+
return data.results[0].series[0].values[0][0];
|
143
|
+
}
|
144
|
+
return null; // Se non ci sono record, ritorna null
|
145
|
+
}
|
@@ -0,0 +1,39 @@
|
|
1
|
+
export type LogtoConfig = {
|
2
|
+
endpoint: string;
|
3
|
+
appId: string;
|
4
|
+
appSecret: string;
|
5
|
+
baseUrl: string;
|
6
|
+
cookieSecret: string;
|
7
|
+
cookieSecure: boolean;
|
8
|
+
scopes: string[];
|
9
|
+
username: string;
|
10
|
+
password: string;
|
11
|
+
resource: string;
|
12
|
+
};
|
13
|
+
export declare const LogtoManagementClient: (logtoConfig: LogtoConfig) => Promise<{
|
14
|
+
getUser: (uid: string) => Promise<any>;
|
15
|
+
getUserList: (page: number, pageSize: number, filter?: {
|
16
|
+
field?: string;
|
17
|
+
operator?: string;
|
18
|
+
value: string;
|
19
|
+
}) => Promise<{
|
20
|
+
data: any;
|
21
|
+
rowCount: number;
|
22
|
+
}>;
|
23
|
+
searchUsers: (value: string) => Promise<any>;
|
24
|
+
updateUser: (uid: string, info: {
|
25
|
+
name: string;
|
26
|
+
}) => Promise<void>;
|
27
|
+
updateCustomData: (uid: string, info: {
|
28
|
+
role: string;
|
29
|
+
uid?: string;
|
30
|
+
}) => Promise<void>;
|
31
|
+
updateProfileData: (uid: string, info: {
|
32
|
+
givenName?: string;
|
33
|
+
familyName?: string;
|
34
|
+
}) => Promise<void>;
|
35
|
+
updatePassword: (uid: string, password: string) => Promise<void>;
|
36
|
+
unlinkConnectedAccount: (uid: string, target: string) => Promise<void>;
|
37
|
+
deleteUser: (uid: string) => Promise<void>;
|
38
|
+
getUserByEmailAndPassword: (email: string, password: string) => Promise<any>;
|
39
|
+
}>;
|
@@ -0,0 +1,194 @@
|
|
1
|
+
"use server";
|
2
|
+
const getManagementToken = async (logtoConfig) => {
|
3
|
+
if (logtoConfig.username === "" || logtoConfig.password === "") {
|
4
|
+
throw new Error("no valid admin credentials");
|
5
|
+
}
|
6
|
+
const res = await fetch(`${logtoConfig.endpoint}oidc/token`, {
|
7
|
+
method: "POST",
|
8
|
+
body: new URLSearchParams({
|
9
|
+
grant_type: "client_credentials",
|
10
|
+
resource: logtoConfig.resource,
|
11
|
+
scope: "all"
|
12
|
+
}),
|
13
|
+
headers: {
|
14
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
15
|
+
Authorization: `Basic ${btoa(`${logtoConfig.username}:${logtoConfig.password}`)}`
|
16
|
+
}
|
17
|
+
});
|
18
|
+
if (!res.ok) {
|
19
|
+
throw new Error("Failed to fetch management token");
|
20
|
+
}
|
21
|
+
const data = await res.json();
|
22
|
+
return data.access_token;
|
23
|
+
};
|
24
|
+
export const LogtoManagementClient = async (logtoConfig) => ({
|
25
|
+
getUser: async (uid) => {
|
26
|
+
const access_token = await getManagementToken(logtoConfig);
|
27
|
+
const res = await fetch(`${logtoConfig.endpoint}api/users/${uid}?includeSsoIdentities=1`, {
|
28
|
+
method: "GET",
|
29
|
+
headers: {
|
30
|
+
Authorization: `Bearer ${access_token}`
|
31
|
+
}
|
32
|
+
});
|
33
|
+
if (!res.ok) {
|
34
|
+
throw new Error(`Failed to get user with ID ${uid}`);
|
35
|
+
}
|
36
|
+
return await res.json();
|
37
|
+
},
|
38
|
+
getUserList: async (page, pageSize, filter) => {
|
39
|
+
const access_token = await getManagementToken(logtoConfig);
|
40
|
+
const search = filter && filter.value
|
41
|
+
? `&search${filter.field ? `.${filter.field}` : ""}=${filter.operator && filter.operator === "equals"
|
42
|
+
? filter.value
|
43
|
+
: `%${filter.value}%`}`
|
44
|
+
: "";
|
45
|
+
const res = await fetch(`${logtoConfig.endpoint}api/users?page=${page}&page_size=${pageSize}${search}`, {
|
46
|
+
method: "GET",
|
47
|
+
headers: {
|
48
|
+
Authorization: `Bearer ${access_token}`
|
49
|
+
}
|
50
|
+
});
|
51
|
+
if (!res.ok) {
|
52
|
+
throw new Error("Failed to fetch user list");
|
53
|
+
}
|
54
|
+
const data = await res.json();
|
55
|
+
const rowCount = res.headers.get("total-number") || "0";
|
56
|
+
return {
|
57
|
+
data,
|
58
|
+
rowCount: parseInt(rowCount, 10)
|
59
|
+
};
|
60
|
+
},
|
61
|
+
searchUsers: async (value) => {
|
62
|
+
const access_token = await getManagementToken(logtoConfig);
|
63
|
+
const res = await fetch(`${logtoConfig.endpoint}api/users?search=%25${encodeURIComponent(value)}%25`, {
|
64
|
+
method: "GET",
|
65
|
+
headers: {
|
66
|
+
Authorization: `Bearer ${access_token}`
|
67
|
+
}
|
68
|
+
});
|
69
|
+
if (!res.ok) {
|
70
|
+
throw new Error("Failed to search users");
|
71
|
+
}
|
72
|
+
return await res.json();
|
73
|
+
},
|
74
|
+
updateUser: async (uid, info) => {
|
75
|
+
const access_token = await getManagementToken(logtoConfig);
|
76
|
+
const res = await fetch(`${logtoConfig.endpoint}api/users/${uid}`, {
|
77
|
+
method: "PATCH",
|
78
|
+
headers: {
|
79
|
+
"Content-Type": "application/json",
|
80
|
+
Authorization: `Bearer ${access_token}`
|
81
|
+
},
|
82
|
+
body: JSON.stringify(info)
|
83
|
+
});
|
84
|
+
if (!res.ok) {
|
85
|
+
throw new Error(`Failed to update user with ID ${uid}`);
|
86
|
+
}
|
87
|
+
},
|
88
|
+
updateCustomData: async (uid, info) => {
|
89
|
+
const newInfo = {
|
90
|
+
role: info.role,
|
91
|
+
uid: info.uid || undefined
|
92
|
+
};
|
93
|
+
const access_token = await getManagementToken(logtoConfig);
|
94
|
+
const res = await fetch(`${logtoConfig.endpoint}api/users/${uid}/custom-data`, {
|
95
|
+
method: "PATCH",
|
96
|
+
headers: {
|
97
|
+
"Content-Type": "application/json",
|
98
|
+
Authorization: `Bearer ${access_token}`
|
99
|
+
},
|
100
|
+
body: JSON.stringify({ customData: newInfo })
|
101
|
+
});
|
102
|
+
if (!res.ok) {
|
103
|
+
throw new Error(`Failed to update custom data for user with ID ${uid}`);
|
104
|
+
}
|
105
|
+
},
|
106
|
+
updateProfileData: async (uid, info) => {
|
107
|
+
const newInfo = {
|
108
|
+
givenName: info.givenName || undefined,
|
109
|
+
familyName: info.familyName || undefined
|
110
|
+
};
|
111
|
+
const access_token = await getManagementToken(logtoConfig);
|
112
|
+
const res = await fetch(`${logtoConfig.endpoint}api/users/${uid}/profile`, {
|
113
|
+
method: "PATCH",
|
114
|
+
headers: {
|
115
|
+
"Content-Type": "application/json",
|
116
|
+
Authorization: `Bearer ${access_token}`
|
117
|
+
},
|
118
|
+
body: JSON.stringify({ profile: newInfo })
|
119
|
+
});
|
120
|
+
if (!res.ok) {
|
121
|
+
throw new Error(`Failed to update custom data for user with ID ${uid}`);
|
122
|
+
}
|
123
|
+
},
|
124
|
+
updatePassword: async (uid, password) => {
|
125
|
+
const access_token = await getManagementToken(logtoConfig);
|
126
|
+
const res = await fetch(`${logtoConfig.endpoint}api/users/${uid}/password`, {
|
127
|
+
method: "PATCH",
|
128
|
+
headers: {
|
129
|
+
"Content-Type": "application/json",
|
130
|
+
Authorization: `Bearer ${access_token}`
|
131
|
+
},
|
132
|
+
body: JSON.stringify({ password })
|
133
|
+
});
|
134
|
+
if (!res.ok) {
|
135
|
+
throw new Error(`Failed to update password for user with ID ${uid}`);
|
136
|
+
}
|
137
|
+
},
|
138
|
+
unlinkConnectedAccount: async (uid, target) => {
|
139
|
+
const access_token = await getManagementToken(logtoConfig);
|
140
|
+
const res = await fetch(`${logtoConfig.endpoint}api/users/${uid}/identities/${target}`, {
|
141
|
+
method: "DELETE",
|
142
|
+
headers: {
|
143
|
+
Authorization: `Bearer ${access_token}`
|
144
|
+
}
|
145
|
+
});
|
146
|
+
if (!res.ok) {
|
147
|
+
throw new Error(`Failed to unlink connected account '${target}' for user with ID ${uid}`);
|
148
|
+
}
|
149
|
+
},
|
150
|
+
deleteUser: async (uid) => {
|
151
|
+
const access_token = await getManagementToken(logtoConfig);
|
152
|
+
const res = await fetch(`${logtoConfig.endpoint}api/users/${uid}`, {
|
153
|
+
method: "DELETE",
|
154
|
+
headers: {
|
155
|
+
Authorization: `Bearer ${access_token}`
|
156
|
+
}
|
157
|
+
});
|
158
|
+
if (!res.ok) {
|
159
|
+
throw new Error(`Failed to delete user with ID ${uid}`);
|
160
|
+
}
|
161
|
+
},
|
162
|
+
getUserByEmailAndPassword: async (email, password) => {
|
163
|
+
const access_token = await getManagementToken(logtoConfig);
|
164
|
+
const res = await fetch(`${logtoConfig.endpoint}api/users?search.primaryEmail=${encodeURIComponent(email)}`, {
|
165
|
+
method: "GET",
|
166
|
+
headers: {
|
167
|
+
Authorization: `Bearer ${access_token}`
|
168
|
+
}
|
169
|
+
});
|
170
|
+
if (!res.ok) {
|
171
|
+
throw new Error("Failed to fetch user by email");
|
172
|
+
}
|
173
|
+
const data = await res.json();
|
174
|
+
if (data && data[0]) {
|
175
|
+
const user = data[0];
|
176
|
+
// verify password
|
177
|
+
const verifyRes = await fetch(`${logtoConfig.endpoint}/api/users/${user.id}/password/verify`, {
|
178
|
+
method: "POST",
|
179
|
+
headers: {
|
180
|
+
"Content-Type": "application/json",
|
181
|
+
Authorization: `Bearer ${access_token}`
|
182
|
+
},
|
183
|
+
body: JSON.stringify({ password })
|
184
|
+
});
|
185
|
+
if (verifyRes.status !== 204) {
|
186
|
+
throw new Error("no user found by email: password mismatch");
|
187
|
+
}
|
188
|
+
return user;
|
189
|
+
}
|
190
|
+
else {
|
191
|
+
throw new Error("no user found by email: user not found");
|
192
|
+
}
|
193
|
+
}
|
194
|
+
});
|
@@ -0,0 +1,35 @@
|
|
1
|
+
export type TrackleConfig = {
|
2
|
+
apiUrl: string;
|
3
|
+
createCustomerUrl: string;
|
4
|
+
clientId: string;
|
5
|
+
clientSecret: string;
|
6
|
+
tokenUrl: string;
|
7
|
+
cookieName: string;
|
8
|
+
cookieSecure: boolean;
|
9
|
+
apiTimeout: number;
|
10
|
+
};
|
11
|
+
export declare function logOut(trackleConfig: TrackleConfig): Promise<void>;
|
12
|
+
export declare function createCustomer(trackleConfig: TrackleConfig, uid: string): Promise<{
|
13
|
+
organization: string;
|
14
|
+
uid: string;
|
15
|
+
}>;
|
16
|
+
export declare function getDevices(trackleConfig: TrackleConfig, productId?: number, uid?: string, group?: string, selected?: string): Promise<{
|
17
|
+
devices: any[];
|
18
|
+
}>;
|
19
|
+
export declare function getDevice(trackleConfig: TrackleConfig, id: string, productId?: number, uid?: string): Promise<{
|
20
|
+
id: string;
|
21
|
+
state: object;
|
22
|
+
metadata: object;
|
23
|
+
}>;
|
24
|
+
export declare function updateDevice(trackleConfig: TrackleConfig, id: string, body: any, productId?: number, uid?: string): Promise<unknown>;
|
25
|
+
export declare function get(trackleConfig: TrackleConfig, id: string, endpoint: string, params?: string, productId?: number, uid?: string): Promise<{
|
26
|
+
result: any;
|
27
|
+
}>;
|
28
|
+
export declare function post(trackleConfig: TrackleConfig, id: string, endpoint: string, args: string, productId?: number, uid?: string): Promise<{
|
29
|
+
return_value: number;
|
30
|
+
}>;
|
31
|
+
export declare function put(trackleConfig: TrackleConfig, id: string, endpoint: string, value: any, productId?: number, uid?: string): Promise<{
|
32
|
+
return_value: number;
|
33
|
+
}>;
|
34
|
+
export declare function addDevicesToGroup(trackleConfig: TrackleConfig, productId: number, uid: string, group: string, devicesToPatch: any[]): Promise<string[]>;
|
35
|
+
export declare function removeDevicesFromGroup(trackleConfig: TrackleConfig, productId: number, uid: string, group: string, devicesToPatch: any[]): Promise<string[]>;
|