@opengis/fastify-table 2.1.13 → 2.1.15

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.
@@ -1,7 +1,10 @@
1
1
  export declare function scryptHash(code: string): Promise<string>;
2
2
  export declare function scryptVerify(stored: string, code: string): Promise<boolean>;
3
- export declare function sign(uid: string, secret?: any, exp?: number): string;
4
- export declare function verify(token: string, secret?: any): boolean;
3
+ export declare function sign(uid: string, secret: string, exp: number | undefined, ip: string): string;
4
+ export declare function verify(token: string, secret: string, ip: string): false | {
5
+ payload: any;
6
+ header: any;
7
+ };
5
8
  declare const _default: null;
6
9
  export default _default;
7
10
  //# sourceMappingURL=jwt.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"jwt.d.ts","sourceRoot":"","sources":["../../../../../server/plugins/auth/funcs/jwt.ts"],"names":[],"mappings":"AAkBA,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,mBAI5C;AAED,wBAAsB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,oBAI9D;AAED,wBAAgB,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,MAAY,EAAE,GAAG,SAAQ,UAoBhE;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,MAAY,WA2BvD;;AAED,wBAAoB"}
1
+ {"version":3,"file":"jwt.d.ts","sourceRoot":"","sources":["../../../../../server/plugins/auth/funcs/jwt.ts"],"names":[],"mappings":"AAmBA,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,mBAI5C;AAED,wBAAsB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,oBAI9D;AAED,wBAAgB,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,oBAAQ,EAAE,EAAE,EAAE,MAAM,UAsBxE;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;;;EA8B/D;;AAED,wBAAoB"}
@@ -5,7 +5,7 @@ const scryptAsync = util.promisify(scrypt);
5
5
  const { jwtSecret = "65450754381cfaf768eeb4bb33326529b48a40ffdb6e15d84dc224dff527166f", } = config.auth || {};
6
6
  const jwtHeader = Buffer.from(JSON.stringify({
7
7
  alg: "HS256",
8
- typ: "JWT",
8
+ type: "JWT",
9
9
  })).toString("base64");
10
10
  export async function scryptHash(code) {
11
11
  const salt = randomBytes(16).toString("hex");
@@ -17,42 +17,45 @@ export async function scryptVerify(stored, code) {
17
17
  const derived = (await scryptAsync(code, salt, 64));
18
18
  return keyHex === derived.toString("hex");
19
19
  }
20
- export function sign(uid, secret = jwtSecret, exp = 90000) {
20
+ export function sign(uid, secret, exp = 90000, ip) {
21
21
  if (typeof uid !== "string")
22
22
  throw new Error("uid must be a string");
23
- if (secret && typeof secret !== "string")
23
+ if (secret && typeof secret !== "string") {
24
24
  throw new Error("secret must be a string");
25
+ }
25
26
  if (typeof exp !== "number")
26
27
  throw new Error("exp must be a number");
27
28
  const jwtPayload = Buffer.from(JSON.stringify({
29
+ ip,
28
30
  uid,
29
- exp,
31
+ expires: Date.now() + exp,
30
32
  created: Date.now(),
31
33
  })).toString("base64");
32
34
  const jwtEncrypted = [jwtHeader, jwtPayload].join(".");
33
- const signature = createHmac("sha256", secret)
35
+ const signature = createHmac("sha256", secret || jwtSecret)
34
36
  .update(jwtEncrypted)
35
37
  .digest("base64");
36
38
  return `${jwtEncrypted}.${signature}`;
37
39
  }
38
- export function verify(token, secret = jwtSecret) {
40
+ export function verify(token, secret, ip) {
39
41
  if (!token)
40
42
  throw new Error("not enough params: token");
41
- if (!secret)
43
+ if (secret && typeof secret !== "string") {
42
44
  throw new Error("not enough params: secret");
45
+ }
43
46
  const split = token.split(".");
44
47
  const signature = split[2];
45
48
  try {
46
49
  const header = JSON.parse(Buffer.from(split[0], "base64").toString());
47
50
  const payload = JSON.parse(Buffer.from(split[1], "base64").toString());
48
- const jwtHeader = Buffer.from(JSON.stringify(header)).toString("base64");
49
- const jwtPayload = Buffer.from(JSON.stringify(payload)).toString("base64");
50
- const jwtEncryptedExpected = [jwtHeader, jwtPayload].join(".");
51
- const expectedSignature = createHmac("sha256", secret)
51
+ const jwtEncryptedExpected = [split[0], split[1]].join(".");
52
+ const expectedSignature = createHmac("sha256", secret || jwtSecret)
52
53
  .update(jwtEncryptedExpected)
53
54
  .digest("base64");
54
- if (signature === expectedSignature) {
55
- return true;
55
+ if (signature === expectedSignature &&
56
+ payload.expires > Date.now() &&
57
+ payload.ip === ip) {
58
+ return { payload, header };
56
59
  }
57
60
  return false;
58
61
  }
@@ -21,7 +21,7 @@ export default async function checkPermissions(req) {
21
21
  permissions?.length &&
22
22
  permissions.length ===
23
23
  permissions.filter(([key, value]) => userPermissions[key]?.includes(value)).length;
24
- if (!havePermission) {
24
+ if (!user?.user_type?.includes?.("admin") && !havePermission) {
25
25
  logger.file("policy/permissions", {
26
26
  path,
27
27
  method,
@@ -52,10 +52,10 @@ export default async function authorize(req, reply) {
52
52
  return reply.code(404).send({ error: "user not found", code: 404 });
53
53
  }
54
54
  const href1 = await authorizeUser(user, req, "jwt", expireMsec);
55
+ const ip = getIp(req);
55
56
  // Generate authorization code
56
- const code = sign(userId, secret, expireMsec);
57
+ const code = sign(userId, secret, expireMsec, ip);
57
58
  const tokenHash = await scryptHash(code);
58
- const ip = getIp(req);
59
59
  // disable access via old tokens
60
60
  if (pg.pk?.["oauth.tokens"]) {
61
61
  await pg.query("update oauth.tokens set revoked_at = now(), revocation_reason='refresh' where client_id=$1", [client_id]);
@@ -32,10 +32,10 @@ export default async function oauthToken(req, reply) {
32
32
  .query(q, [client_id, "private_key_jwt"])
33
33
  .then((el) => el.rows?.[0] || {})
34
34
  : {};
35
- const isCodeValid = verify(code, secret);
35
+ const ip = getIp(req);
36
+ const isCodeValid = verify(code, secret, ip);
36
37
  const q1 = "select token_hash, expires_at, ip from oauth.tokens where client_id=$1 and revoked_at is null and expires_at > now()";
37
38
  const { token_hash: stored, expires_at, ip: storedIp, } = await pg.query(q1, [client_id]).then((el) => el.rows?.[0] || {});
38
- const ip = getIp(req);
39
39
  if (storedIp !== ip) {
40
40
  return reply
41
41
  .code(403)
@@ -1 +1 @@
1
- {"version":3,"file":"getData.d.ts","sourceRoot":"","sources":["../../../../../server/routes/table/functions/getData.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAkFzD,wBAA8B,OAAO,CACnC,EACE,EAAqB,EACrB,MAAM,EACN,KAAK,EACL,EAAE,EACF,OAAY,EACZ,KAAU,EACV,IAAS,EACT,YAAY,EACZ,YAAY,EACZ,KAAY,EACZ,UAAU,EACV,OAAO,EAAE,YAAY,EACrB,WAAW,EAAE,gBAAgB,EAC7B,OAAO,EAAE,YAAY,EACrB,QAAgB,GACjB,EAAE;IACD,EAAE,CAAC,EAAE,UAAU,CAAC;IAChB,MAAM,CAAC,EAAE;QAAE,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IACxD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,UAAU,CAAC,EAAE,GAAG,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,EACD,MAAM,CAAC,EAAE,YAAY,EACrB,MAAM,CAAC,EAAE,GAAG,gBA42Bb"}
1
+ {"version":3,"file":"getData.d.ts","sourceRoot":"","sources":["../../../../../server/routes/table/functions/getData.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAkFzD,wBAA8B,OAAO,CACnC,EACE,EAAqB,EACrB,MAAM,EACN,KAAK,EACL,EAAE,EACF,OAAY,EACZ,KAAU,EACV,IAAS,EACT,YAAY,EACZ,YAAY,EACZ,KAAY,EACZ,UAAU,EACV,OAAO,EAAE,YAAY,EACrB,WAAW,EAAE,gBAAgB,EAC7B,OAAO,EAAE,YAAY,EACrB,QAAgB,GACjB,EAAE;IACD,EAAE,CAAC,EAAE,UAAU,CAAC;IAChB,MAAM,CAAC,EAAE;QAAE,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IACxD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,UAAU,CAAC,EAAE,GAAG,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,EACD,MAAM,CAAC,EAAE,YAAY,EACrB,MAAM,CAAC,EAAE,GAAG,gBAk3Bb"}
@@ -163,7 +163,11 @@ export default async function dataAPI({ pg = pgClients.client, params, table, id
163
163
  tokenData?.public ||
164
164
  params?.public ||
165
165
  false;
166
- if (!ispublic && !user?.uid && !called) {
166
+ if (!ispublic &&
167
+ !user?.uid &&
168
+ !called &&
169
+ !accessQueryParam &&
170
+ !actionsParam) {
167
171
  return reply.status(401).send({ error: "unauthorized", code: 401 });
168
172
  }
169
173
  if (!ispublic && !actions.includes("view") && !config?.local && !called) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opengis/fastify-table",
3
- "version": "2.1.13",
3
+ "version": "2.1.15",
4
4
  "type": "module",
5
5
  "description": "core-plugins",
6
6
  "keywords": [