Logout user that do not have permissions (#3559)
This commit is contained in:
parent
55337b5998
commit
8a86a32c08
9 changed files with 340 additions and 1143 deletions
654
package-lock.json
generated
654
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -35,7 +35,7 @@
|
|||
"@material-ui/styles": "^4.11.4",
|
||||
"@reach/auto-id": "^0.16.0",
|
||||
"@saleor/macaw-ui": "0.8.0-pre.81",
|
||||
"@saleor/sdk": "^0.5.0",
|
||||
"@saleor/sdk": "0.6.0",
|
||||
"@sentry/react": "^6.0.0",
|
||||
"@types/faker": "^5.1.6",
|
||||
"@uiw/react-color-hue": "0.0.34",
|
||||
|
@ -122,9 +122,6 @@
|
|||
"@graphql-codegen/typescript-react-apollo": "^3.2.5",
|
||||
"@percy/cli": "^1.21.0",
|
||||
"@percy/cypress": "^3.1.2",
|
||||
"@pollyjs/adapter-node-http": "~5.0.0",
|
||||
"@pollyjs/core": "~5.0.0",
|
||||
"@pollyjs/persister-fs": "~5.0.0",
|
||||
"@release-it/bumper": "^2.0.0",
|
||||
"@saleor/app-sdk": "0.37.3",
|
||||
"@types/apollo-upload-client": "^17.0.2",
|
||||
|
|
|
@ -1,133 +0,0 @@
|
|||
{
|
||||
"log": {
|
||||
"_recordingName": "User/will be logged in if has valid credentials",
|
||||
"creator": {
|
||||
"comment": "persister:fs",
|
||||
"name": "Polly.JS",
|
||||
"version": "5.1.0"
|
||||
},
|
||||
"entries": [
|
||||
{
|
||||
"_id": "916a39b70c19064326e4caf3e7a38f9d",
|
||||
"_order": 0,
|
||||
"cache": {},
|
||||
"request": {
|
||||
"bodySize": 620,
|
||||
"cookies": [],
|
||||
"headers": [
|
||||
{
|
||||
"_fromType": "array",
|
||||
"name": "accept",
|
||||
"value": "*/*"
|
||||
},
|
||||
{
|
||||
"_fromType": "array",
|
||||
"name": "content-type",
|
||||
"value": "application/json"
|
||||
},
|
||||
{
|
||||
"_fromType": "array",
|
||||
"name": "content-length",
|
||||
"value": "620"
|
||||
},
|
||||
{
|
||||
"_fromType": "array",
|
||||
"name": "user-agent",
|
||||
"value": "node-fetch/1.0 (+https://github.com/bitinn/node-fetch)"
|
||||
},
|
||||
{
|
||||
"_fromType": "array",
|
||||
"name": "accept-encoding",
|
||||
"value": "gzip,deflate"
|
||||
},
|
||||
{
|
||||
"_fromType": "array",
|
||||
"name": "connection",
|
||||
"value": "close"
|
||||
},
|
||||
{
|
||||
"name": "host",
|
||||
"value": "localhost:8000"
|
||||
}
|
||||
],
|
||||
"headersSize": 254,
|
||||
"httpVersion": "HTTP/1.1",
|
||||
"method": "POST",
|
||||
"postData": {
|
||||
"mimeType": "application/json",
|
||||
"params": [],
|
||||
"text": "{\"operationName\":\"loginWithoutDetails\",\"variables\":{\"email\":\"admin@example.com\",\"password\":\"admin\"},\"query\":\"fragment AccountErrorFragment on AccountError {\\n code\\n field\\n message\\n __typename\\n}\\n\\nfragment UserBaseFragment on User {\\n id\\n email\\n firstName\\n lastName\\n isStaff\\n __typename\\n}\\n\\nmutation loginWithoutDetails($email: String!, $password: String!) {\\n tokenCreate(email: $email, password: $password) {\\n csrfToken\\n token\\n errors {\\n ...AccountErrorFragment\\n __typename\\n }\\n user {\\n ...UserBaseFragment\\n __typename\\n }\\n __typename\\n }\\n}\\n\"}"
|
||||
},
|
||||
"queryString": [],
|
||||
"url": "http://localhost:8000/graphql/"
|
||||
},
|
||||
"response": {
|
||||
"bodySize": 984,
|
||||
"content": {
|
||||
"mimeType": "application/json",
|
||||
"size": 984,
|
||||
"text": "{\"data\": {\"tokenCreate\": {\"csrfToken\": \"0GedAMt3cXdGCfB9rqe7Tqc8ogIRYwvhWgpN2l4pXFOKcQDtXpczhD4CPDO4zV2d\", \"token\": \"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IjEifQ.eyJpYXQiOjE2NDY4MjgwNDgsIm93bmVyIjoic2FsZW9yIiwiZXhwIjoxNjQ2ODI4MzQ4LCJ0b2tlbiI6IlBHSXN0dmFUS2xQcCIsImVtYWlsIjoiYWRtaW5AZXhhbXBsZS5jb20iLCJ0eXBlIjoiYWNjZXNzIiwidXNlcl9pZCI6IlZYTmxjam95TVE9PSIsImlzX3N0YWZmIjp0cnVlfQ.NQPcXACGUynrPfhYA_aoP_afZonMMQbmy_DBGM57HArB1BPQZSJXMJ4ye27buRN1CnwuWhSBHJP6J7XjOdH7F2WzXTldaIbud5TCms00ANde9AdJnJ92zL1vTuB99-oHC8PqJRUTMMn4hetYosKOb9FEAS6tD4u529Do8YiVnxcsdGxPmfEaN5HiwJ4HE76lfZH2rU6uin9Vdk14dmJKF-Rr_P_efCckgkvNwr3GAyX7L9zeVeJeDR4W1jeUY-f05OQKx9_qZazpWBVk1558JX1kBu6wQ2kFCiCLuUcv0L13GanLesP-FCDwgntTCwNmFXdqTdADAXzYc8KpoScpfg\", \"errors\": [], \"user\": {\"id\": \"VXNlcjoyMQ==\", \"email\": \"admin@example.com\", \"firstName\": \"\", \"lastName\": \"\", \"isStaff\": true, \"__typename\": \"User\"}, \"__typename\": \"CreateToken\"}}, \"extensions\": {\"cost\": {\"requestedQueryCost\": 0, \"maximumAvailable\": 50000}}}"
|
||||
},
|
||||
"cookies": [
|
||||
{
|
||||
"httpOnly": true,
|
||||
"name": "refreshToken",
|
||||
"path": "/",
|
||||
"sameSite": "Lax",
|
||||
"value": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IjEifQ.eyJpYXQiOjE2NDY4MjgwNDgsIm93bmVyIjoic2FsZW9yIiwiZXhwIjoxNjQ5NDIwMDQ4LCJ0b2tlbiI6IlBHSXN0dmFUS2xQcCIsImVtYWlsIjoiYWRtaW5AZXhhbXBsZS5jb20iLCJ0eXBlIjoicmVmcmVzaCIsInVzZXJfaWQiOiJWWE5sY2pveU1RPT0iLCJpc19zdGFmZiI6dHJ1ZSwiY3NyZlRva2VuIjoiMEdlZEFNdDNjWGRHQ2ZCOXJxZTdUcWM4b2dJUll3dmhXZ3BOMmw0cFhGT0tjUUR0WHBjemhENENQRE80elYyZCJ9.eKJ4g02HziNjuKjxi_zEl5iz3EnrjzqWJjNYgVXxHMcXcJozOk5CrBpVFmM1ZUzdbXyPoHxW_UQeK0mVsMI9_owiYMfZcCyrOh1sDZB4oZVGA7Q_oYMLqc0Z81o_W-ZIN6Z3UNK4UKl7-1IRltJxVr4qmVtC7R5B_3Hnjs8xrEkcN0Q6sS0NyXYL9xVnazhDIRgrRQu4lU4co3eBCu0svyo7z5xESZmCRxsJZ1tfnoC-Gjx-6zO2hOFP4OrsbNWZcQhtoTDu5IbG8qthWI0eGvAkuK6jje0pnGrswuW_LlG1moBCy01C8K9WIYtYoT6BFnNMDc00W9MBNzGiN9rCXQ"
|
||||
}
|
||||
],
|
||||
"headers": [
|
||||
{
|
||||
"name": "date",
|
||||
"value": "Wed, 09 Mar 2022 12:14:08 GMT"
|
||||
},
|
||||
{
|
||||
"name": "server",
|
||||
"value": "WSGIServer/0.2 CPython/3.9.10"
|
||||
},
|
||||
{
|
||||
"name": "content-type",
|
||||
"value": "application/json"
|
||||
},
|
||||
{
|
||||
"name": "content-length",
|
||||
"value": "984"
|
||||
},
|
||||
{
|
||||
"name": "x-content-type-options",
|
||||
"value": "nosniff"
|
||||
},
|
||||
{
|
||||
"name": "referrer-policy",
|
||||
"value": "same-origin"
|
||||
},
|
||||
{
|
||||
"_fromType": "array",
|
||||
"name": "set-cookie",
|
||||
"value": "refreshToken=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IjEifQ.eyJpYXQiOjE2NDY4MjgwNDgsIm93bmVyIjoic2FsZW9yIiwiZXhwIjoxNjQ5NDIwMDQ4LCJ0b2tlbiI6IlBHSXN0dmFUS2xQcCIsImVtYWlsIjoiYWRtaW5AZXhhbXBsZS5jb20iLCJ0eXBlIjoicmVmcmVzaCIsInVzZXJfaWQiOiJWWE5sY2pveU1RPT0iLCJpc19zdGFmZiI6dHJ1ZSwiY3NyZlRva2VuIjoiMEdlZEFNdDNjWGRHQ2ZCOXJxZTdUcWM4b2dJUll3dmhXZ3BOMmw0cFhGT0tjUUR0WHBjemhENENQRE80elYyZCJ9.eKJ4g02HziNjuKjxi_zEl5iz3EnrjzqWJjNYgVXxHMcXcJozOk5CrBpVFmM1ZUzdbXyPoHxW_UQeK0mVsMI9_owiYMfZcCyrOh1sDZB4oZVGA7Q_oYMLqc0Z81o_W-ZIN6Z3UNK4UKl7-1IRltJxVr4qmVtC7R5B_3Hnjs8xrEkcN0Q6sS0NyXYL9xVnazhDIRgrRQu4lU4co3eBCu0svyo7z5xESZmCRxsJZ1tfnoC-Gjx-6zO2hOFP4OrsbNWZcQhtoTDu5IbG8qthWI0eGvAkuK6jje0pnGrswuW_LlG1moBCy01C8K9WIYtYoT6BFnNMDc00W9MBNzGiN9rCXQ; HttpOnly; Path=/; SameSite=Lax"
|
||||
}
|
||||
],
|
||||
"headersSize": 967,
|
||||
"httpVersion": "HTTP/1.1",
|
||||
"redirectURL": "",
|
||||
"status": 200,
|
||||
"statusText": "OK"
|
||||
},
|
||||
"startedDateTime": "2022-03-09T12:14:07.734Z",
|
||||
"time": 539,
|
||||
"timings": {
|
||||
"blocked": -1,
|
||||
"connect": -1,
|
||||
"dns": -1,
|
||||
"receive": 0,
|
||||
"send": 0,
|
||||
"ssl": -1,
|
||||
"wait": 539
|
||||
}
|
||||
}
|
||||
],
|
||||
"pages": [],
|
||||
"version": "1.2"
|
||||
}
|
||||
}
|
|
@ -1,226 +0,0 @@
|
|||
{
|
||||
"log": {
|
||||
"_recordingName": "User/will not be logged in if doesn't have valid credentials",
|
||||
"creator": {
|
||||
"comment": "persister:fs",
|
||||
"name": "Polly.JS",
|
||||
"version": "5.1.0"
|
||||
},
|
||||
"entries": [
|
||||
{
|
||||
"_id": "916a39b70c19064326e4caf3e7a38f9d",
|
||||
"_order": 0,
|
||||
"cache": {},
|
||||
"request": {
|
||||
"bodySize": 636,
|
||||
"cookies": [],
|
||||
"headers": [
|
||||
{
|
||||
"_fromType": "array",
|
||||
"name": "accept",
|
||||
"value": "*/*"
|
||||
},
|
||||
{
|
||||
"_fromType": "array",
|
||||
"name": "content-type",
|
||||
"value": "application/json"
|
||||
},
|
||||
{
|
||||
"_fromType": "array",
|
||||
"name": "content-length",
|
||||
"value": "636"
|
||||
},
|
||||
{
|
||||
"_fromType": "array",
|
||||
"name": "user-agent",
|
||||
"value": "node-fetch/1.0 (+https://github.com/bitinn/node-fetch)"
|
||||
},
|
||||
{
|
||||
"_fromType": "array",
|
||||
"name": "accept-encoding",
|
||||
"value": "gzip,deflate"
|
||||
},
|
||||
{
|
||||
"_fromType": "array",
|
||||
"name": "connection",
|
||||
"value": "close"
|
||||
},
|
||||
{
|
||||
"name": "host",
|
||||
"value": "localhost:8000"
|
||||
}
|
||||
],
|
||||
"headersSize": 254,
|
||||
"httpVersion": "HTTP/1.1",
|
||||
"method": "POST",
|
||||
"postData": {
|
||||
"mimeType": "application/json",
|
||||
"params": [],
|
||||
"text": "{\"operationName\":\"loginWithoutDetails\",\"variables\":{\"email\":\"admin@example.com\",\"password\":\"NotAValidPassword123!\"},\"query\":\"fragment AccountErrorFragment on AccountError {\\n code\\n field\\n message\\n __typename\\n}\\n\\nfragment UserBaseFragment on User {\\n id\\n email\\n firstName\\n lastName\\n isStaff\\n __typename\\n}\\n\\nmutation loginWithoutDetails($email: String!, $password: String!) {\\n tokenCreate(email: $email, password: $password) {\\n csrfToken\\n token\\n errors {\\n ...AccountErrorFragment\\n __typename\\n }\\n user {\\n ...UserBaseFragment\\n __typename\\n }\\n __typename\\n }\\n}\\n\"}"
|
||||
},
|
||||
"queryString": [],
|
||||
"url": "http://localhost:8000/graphql/"
|
||||
},
|
||||
"response": {
|
||||
"bodySize": 321,
|
||||
"content": {
|
||||
"mimeType": "application/json",
|
||||
"size": 321,
|
||||
"text": "{\"data\": {\"tokenCreate\": {\"csrfToken\": null, \"token\": null, \"errors\": [{\"code\": \"INVALID_CREDENTIALS\", \"field\": \"email\", \"message\": \"Please, enter valid credentials\", \"__typename\": \"AccountError\"}], \"user\": null, \"__typename\": \"CreateToken\"}}, \"extensions\": {\"cost\": {\"requestedQueryCost\": 0, \"maximumAvailable\": 50000}}}"
|
||||
},
|
||||
"cookies": [],
|
||||
"headers": [
|
||||
{
|
||||
"name": "date",
|
||||
"value": "Wed, 09 Mar 2022 12:14:08 GMT"
|
||||
},
|
||||
{
|
||||
"name": "server",
|
||||
"value": "WSGIServer/0.2 CPython/3.9.10"
|
||||
},
|
||||
{
|
||||
"name": "content-type",
|
||||
"value": "application/json"
|
||||
},
|
||||
{
|
||||
"name": "content-length",
|
||||
"value": "321"
|
||||
},
|
||||
{
|
||||
"name": "x-content-type-options",
|
||||
"value": "nosniff"
|
||||
},
|
||||
{
|
||||
"name": "referrer-policy",
|
||||
"value": "same-origin"
|
||||
}
|
||||
],
|
||||
"headersSize": 194,
|
||||
"httpVersion": "HTTP/1.1",
|
||||
"redirectURL": "",
|
||||
"status": 200,
|
||||
"statusText": "OK"
|
||||
},
|
||||
"startedDateTime": "2022-03-09T12:14:08.308Z",
|
||||
"time": 365,
|
||||
"timings": {
|
||||
"blocked": -1,
|
||||
"connect": -1,
|
||||
"dns": -1,
|
||||
"receive": 0,
|
||||
"send": 0,
|
||||
"ssl": -1,
|
||||
"wait": 365
|
||||
}
|
||||
},
|
||||
{
|
||||
"_id": "f36c6d9d965b62862363338cf17d6135",
|
||||
"_order": 0,
|
||||
"cache": {},
|
||||
"request": {
|
||||
"bodySize": 324,
|
||||
"cookies": [],
|
||||
"headers": [
|
||||
{
|
||||
"_fromType": "array",
|
||||
"name": "accept",
|
||||
"value": "*/*"
|
||||
},
|
||||
{
|
||||
"_fromType": "array",
|
||||
"name": "content-type",
|
||||
"value": "application/json"
|
||||
},
|
||||
{
|
||||
"_fromType": "array",
|
||||
"name": "content-length",
|
||||
"value": "324"
|
||||
},
|
||||
{
|
||||
"_fromType": "array",
|
||||
"name": "user-agent",
|
||||
"value": "node-fetch/1.0 (+https://github.com/bitinn/node-fetch)"
|
||||
},
|
||||
{
|
||||
"_fromType": "array",
|
||||
"name": "accept-encoding",
|
||||
"value": "gzip,deflate"
|
||||
},
|
||||
{
|
||||
"_fromType": "array",
|
||||
"name": "connection",
|
||||
"value": "close"
|
||||
},
|
||||
{
|
||||
"name": "host",
|
||||
"value": "localhost:8000"
|
||||
}
|
||||
],
|
||||
"headersSize": 254,
|
||||
"httpVersion": "HTTP/1.1",
|
||||
"method": "POST",
|
||||
"postData": {
|
||||
"mimeType": "application/json",
|
||||
"params": [],
|
||||
"text": "[{\"operationName\":\"UserDetails\",\"variables\":{},\"query\":\"fragment User on User {\\n id\\n email\\n firstName\\n lastName\\n isStaff\\n userPermissions {\\n code\\n name\\n __typename\\n }\\n avatar {\\n url\\n __typename\\n }\\n __typename\\n}\\n\\nquery UserDetails {\\n me {\\n ...User\\n __typename\\n }\\n}\\n\"}]"
|
||||
},
|
||||
"queryString": [],
|
||||
"url": "http://localhost:8000/graphql/"
|
||||
},
|
||||
"response": {
|
||||
"bodySize": 102,
|
||||
"content": {
|
||||
"mimeType": "application/json",
|
||||
"size": 102,
|
||||
"text": "[{\"data\": {\"me\": null}, \"extensions\": {\"cost\": {\"requestedQueryCost\": 1, \"maximumAvailable\": 50000}}}]"
|
||||
},
|
||||
"cookies": [],
|
||||
"headers": [
|
||||
{
|
||||
"name": "date",
|
||||
"value": "Wed, 09 Mar 2022 12:14:08 GMT"
|
||||
},
|
||||
{
|
||||
"name": "server",
|
||||
"value": "WSGIServer/0.2 CPython/3.9.10"
|
||||
},
|
||||
{
|
||||
"name": "content-type",
|
||||
"value": "application/json"
|
||||
},
|
||||
{
|
||||
"name": "content-length",
|
||||
"value": "102"
|
||||
},
|
||||
{
|
||||
"name": "x-content-type-options",
|
||||
"value": "nosniff"
|
||||
},
|
||||
{
|
||||
"name": "referrer-policy",
|
||||
"value": "same-origin"
|
||||
}
|
||||
],
|
||||
"headersSize": 194,
|
||||
"httpVersion": "HTTP/1.1",
|
||||
"redirectURL": "",
|
||||
"status": 200,
|
||||
"statusText": "OK"
|
||||
},
|
||||
"startedDateTime": "2022-03-09T12:14:08.311Z",
|
||||
"time": 70,
|
||||
"timings": {
|
||||
"blocked": -1,
|
||||
"connect": -1,
|
||||
"dns": -1,
|
||||
"receive": 0,
|
||||
"send": 0,
|
||||
"ssl": -1,
|
||||
"wait": 70
|
||||
}
|
||||
}
|
||||
],
|
||||
"pages": [],
|
||||
"version": "1.2"
|
||||
}
|
||||
}
|
|
@ -1,120 +0,0 @@
|
|||
{
|
||||
"log": {
|
||||
"_recordingName": "User/will not be logged in if is non-staff",
|
||||
"creator": {
|
||||
"comment": "persister:fs",
|
||||
"name": "Polly.JS",
|
||||
"version": "5.1.0"
|
||||
},
|
||||
"entries": [
|
||||
{
|
||||
"_id": "916a39b70c19064326e4caf3e7a38f9d",
|
||||
"_order": 0,
|
||||
"cache": {},
|
||||
"request": {
|
||||
"bodySize": 624,
|
||||
"cookies": [],
|
||||
"headers": [
|
||||
{
|
||||
"_fromType": "array",
|
||||
"name": "accept",
|
||||
"value": "*/*"
|
||||
},
|
||||
{
|
||||
"_fromType": "array",
|
||||
"name": "content-type",
|
||||
"value": "application/json"
|
||||
},
|
||||
{
|
||||
"_fromType": "array",
|
||||
"name": "content-length",
|
||||
"value": "624"
|
||||
},
|
||||
{
|
||||
"_fromType": "array",
|
||||
"name": "user-agent",
|
||||
"value": "node-fetch/1.0 (+https://github.com/bitinn/node-fetch)"
|
||||
},
|
||||
{
|
||||
"_fromType": "array",
|
||||
"name": "accept-encoding",
|
||||
"value": "gzip,deflate"
|
||||
},
|
||||
{
|
||||
"_fromType": "array",
|
||||
"name": "connection",
|
||||
"value": "close"
|
||||
},
|
||||
{
|
||||
"name": "host",
|
||||
"value": "localhost:8000"
|
||||
}
|
||||
],
|
||||
"headersSize": 254,
|
||||
"httpVersion": "HTTP/1.1",
|
||||
"method": "POST",
|
||||
"postData": {
|
||||
"mimeType": "application/json",
|
||||
"params": [],
|
||||
"text": "{\"operationName\":\"loginWithoutDetails\",\"variables\":{\"email\":\"client@example.com\",\"password\":\"password\"},\"query\":\"fragment AccountErrorFragment on AccountError {\\n code\\n field\\n message\\n __typename\\n}\\n\\nfragment UserBaseFragment on User {\\n id\\n email\\n firstName\\n lastName\\n isStaff\\n __typename\\n}\\n\\nmutation loginWithoutDetails($email: String!, $password: String!) {\\n tokenCreate(email: $email, password: $password) {\\n csrfToken\\n token\\n errors {\\n ...AccountErrorFragment\\n __typename\\n }\\n user {\\n ...UserBaseFragment\\n __typename\\n }\\n __typename\\n }\\n}\\n\"}"
|
||||
},
|
||||
"queryString": [],
|
||||
"url": "http://localhost:8000/graphql/"
|
||||
},
|
||||
"response": {
|
||||
"bodySize": 321,
|
||||
"content": {
|
||||
"mimeType": "application/json",
|
||||
"size": 321,
|
||||
"text": "{\"data\": {\"tokenCreate\": {\"csrfToken\": null, \"token\": null, \"errors\": [{\"code\": \"INVALID_CREDENTIALS\", \"field\": \"email\", \"message\": \"Please, enter valid credentials\", \"__typename\": \"AccountError\"}], \"user\": null, \"__typename\": \"CreateToken\"}}, \"extensions\": {\"cost\": {\"requestedQueryCost\": 0, \"maximumAvailable\": 50000}}}"
|
||||
},
|
||||
"cookies": [],
|
||||
"headers": [
|
||||
{
|
||||
"name": "date",
|
||||
"value": "Wed, 09 Mar 2022 12:14:08 GMT"
|
||||
},
|
||||
{
|
||||
"name": "server",
|
||||
"value": "WSGIServer/0.2 CPython/3.9.10"
|
||||
},
|
||||
{
|
||||
"name": "content-type",
|
||||
"value": "application/json"
|
||||
},
|
||||
{
|
||||
"name": "content-length",
|
||||
"value": "321"
|
||||
},
|
||||
{
|
||||
"name": "x-content-type-options",
|
||||
"value": "nosniff"
|
||||
},
|
||||
{
|
||||
"name": "referrer-policy",
|
||||
"value": "same-origin"
|
||||
}
|
||||
],
|
||||
"headersSize": 194,
|
||||
"httpVersion": "HTTP/1.1",
|
||||
"redirectURL": "",
|
||||
"status": 200,
|
||||
"statusText": "OK"
|
||||
},
|
||||
"startedDateTime": "2022-03-09T12:14:08.691Z",
|
||||
"time": 121,
|
||||
"timings": {
|
||||
"blocked": -1,
|
||||
"connect": -1,
|
||||
"dns": -1,
|
||||
"receive": 0,
|
||||
"send": 0,
|
||||
"ssl": -1,
|
||||
"wait": 121
|
||||
}
|
||||
}
|
||||
],
|
||||
"pages": [],
|
||||
"version": "1.2"
|
||||
}
|
||||
}
|
|
@ -1,42 +1,12 @@
|
|||
/** @jest-environment setup-polly-jest/jest-environment-jsdom */
|
||||
|
||||
import { getApiUrl } from "@dashboard/config";
|
||||
import { createSaleorClient, SaleorProvider } from "@saleor/sdk";
|
||||
import setupApi from "@test/api";
|
||||
import { useApolloClient } from "@apollo/client";
|
||||
import { useUserDetailsQuery } from "@dashboard/graphql";
|
||||
import useNotifier from "@dashboard/hooks/useNotifier";
|
||||
import { useAuth, useAuthState } from "@saleor/sdk";
|
||||
import { act, renderHook } from "@testing-library/react-hooks";
|
||||
import React from "react";
|
||||
import { IntlProvider } from "react-intl";
|
||||
import { MemoryRouter as Router } from "react-router-dom";
|
||||
import { useIntl } from "react-intl";
|
||||
|
||||
import { useAuthProvider } from "./hooks/useAuthProvider";
|
||||
|
||||
const apolloClient = setupApi();
|
||||
|
||||
function renderAuthProvider() {
|
||||
const intl = {
|
||||
formatMessage: ({ defaultMessage }) => defaultMessage,
|
||||
};
|
||||
const notify = jest.fn();
|
||||
const saleorClient = createSaleorClient({
|
||||
apiUrl: getApiUrl(),
|
||||
channel: "",
|
||||
});
|
||||
const wrapper = ({ children }) => (
|
||||
<IntlProvider defaultLocale="en" locale="en">
|
||||
<Router>
|
||||
<SaleorProvider client={saleorClient}>{children}</SaleorProvider>
|
||||
</Router>
|
||||
</IntlProvider>
|
||||
);
|
||||
|
||||
const { result } = renderHook(
|
||||
() => useAuthProvider({ intl: intl as any, notify, apolloClient }),
|
||||
{ wrapper },
|
||||
);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
const adminCredentials = {
|
||||
email: "admin@example.com",
|
||||
password: "admin",
|
||||
|
@ -53,43 +23,202 @@ beforeEach(() => {
|
|||
sessionStorage.clear();
|
||||
});
|
||||
|
||||
describe("User", () => {
|
||||
it("will be logged in if has valid credentials", async () => {
|
||||
const hook = renderAuthProvider();
|
||||
jest.mock("react-intl", () => ({
|
||||
useIntl: jest.fn(() => ({
|
||||
formatMessage: jest.fn(x => x.defaultMessage),
|
||||
})),
|
||||
defineMessages: jest.fn(x => x),
|
||||
}));
|
||||
|
||||
await act(async () => {
|
||||
const result = await hook.current.login(
|
||||
jest.mock("@saleor/sdk", () => ({
|
||||
useAuth: jest.fn(() => ({
|
||||
login: jest.fn(() => ({
|
||||
data: {
|
||||
tokenCreate: {
|
||||
errors: [],
|
||||
user: {
|
||||
userPermissions: [
|
||||
{
|
||||
code: "MANAGE_USERS",
|
||||
name: "Handle checkouts",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
})),
|
||||
logout: jest.fn(),
|
||||
})),
|
||||
useAuthState: jest.fn(() => undefined),
|
||||
}));
|
||||
jest.mock("@apollo/client", () => ({
|
||||
useApolloClient: jest.fn(() => ({
|
||||
clearStore: jest.fn(),
|
||||
})),
|
||||
ApolloError: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock("@dashboard/graphql", () => ({
|
||||
useUserDetailsQuery: jest.fn(() => ({
|
||||
data: undefined,
|
||||
})),
|
||||
}));
|
||||
|
||||
jest.mock("@dashboard/hooks/useNotifier", () => ({
|
||||
__esModule: true,
|
||||
default: jest.fn(() => () => undefined),
|
||||
}));
|
||||
|
||||
jest.mock("@dashboard/hooks/useNavigator", () => ({
|
||||
__esModule: true,
|
||||
default: jest.fn(() => () => undefined),
|
||||
}));
|
||||
jest.mock("@dashboard/hooks/useLocalStorage", () => ({
|
||||
__esModule: true,
|
||||
default: jest.fn(() => []),
|
||||
}));
|
||||
jest.mock("@dashboard/auth", () => ({
|
||||
useUser: jest.fn(),
|
||||
}));
|
||||
jest.mock("use-react-router", () => ({
|
||||
__esModule: true,
|
||||
default: jest.fn(() => ({
|
||||
location: {},
|
||||
})),
|
||||
}));
|
||||
|
||||
describe("AuthProvider", () => {
|
||||
it("Staff user will be logged in if has valid credentials", async () => {
|
||||
// Arrange
|
||||
const intl = useIntl();
|
||||
const notify = useNotifier();
|
||||
const apolloClient = useApolloClient();
|
||||
|
||||
(useAuthState as jest.Mock).mockImplementation(() => ({
|
||||
authenticated: true,
|
||||
authenticating: false,
|
||||
user: {
|
||||
isStaff: true,
|
||||
},
|
||||
}));
|
||||
(useUserDetailsQuery as jest.Mock).mockImplementation(() => ({
|
||||
data: {
|
||||
me: {
|
||||
email: adminCredentials.email,
|
||||
isStaff: true,
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
// Act
|
||||
const hook = renderHook(() =>
|
||||
useAuthProvider({ intl, notify, apolloClient }),
|
||||
);
|
||||
await act(async () =>
|
||||
hook.result.current.login(
|
||||
adminCredentials.email,
|
||||
adminCredentials.password,
|
||||
);
|
||||
expect(result.user?.email).toBe(adminCredentials.email);
|
||||
});
|
||||
expect(hook.current.authenticated).toBe(true);
|
||||
),
|
||||
);
|
||||
|
||||
// Assert
|
||||
expect(hook.result.current.user?.email).toBe(adminCredentials.email);
|
||||
expect(hook.result.current.authenticated).toBe(true);
|
||||
});
|
||||
|
||||
it("will not be logged in if doesn't have valid credentials", async () => {
|
||||
const hook = renderAuthProvider();
|
||||
it("User will not be logged in if doesn't have valid credentials", async () => {
|
||||
// Arrange
|
||||
const intl = useIntl();
|
||||
const notify = useNotifier();
|
||||
const apolloClient = useApolloClient();
|
||||
|
||||
await act(async () => {
|
||||
const result = await hook.current.login(
|
||||
adminCredentials.email,
|
||||
"NotAValidPassword123!",
|
||||
);
|
||||
expect(result.user).toBe(null);
|
||||
});
|
||||
expect(hook.current.authenticated).toBe(false);
|
||||
(useAuthState as jest.Mock).mockImplementation(() => ({
|
||||
authenticated: false,
|
||||
authenticating: false,
|
||||
}));
|
||||
(useUserDetailsQuery as jest.Mock).mockImplementation(() => ({
|
||||
data: {
|
||||
me: null,
|
||||
},
|
||||
}));
|
||||
|
||||
// Act
|
||||
const hook = renderHook(() =>
|
||||
useAuthProvider({ intl, notify, apolloClient }),
|
||||
);
|
||||
|
||||
// Assert
|
||||
expect(hook.result.current.user).toBe(null);
|
||||
expect(hook.result.current.authenticated).toBe(false);
|
||||
});
|
||||
|
||||
it("will not be logged in if is non-staff", async () => {
|
||||
const hook = renderAuthProvider();
|
||||
it("Non-staff user will not be logged in", async () => {
|
||||
// Arrange
|
||||
const intl = useIntl();
|
||||
const notify = useNotifier();
|
||||
const apolloClient = useApolloClient();
|
||||
|
||||
await act(async () => {
|
||||
const result = await hook.current.login(
|
||||
(useAuthState as jest.Mock).mockImplementation(() => ({
|
||||
authenticated: false,
|
||||
authenticating: false,
|
||||
}));
|
||||
(useUserDetailsQuery as jest.Mock).mockImplementation(() => ({
|
||||
data: {
|
||||
me: {
|
||||
email: nonStaffUserCredentials.email,
|
||||
isStaff: false,
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
// Act
|
||||
const hook = renderHook(() =>
|
||||
useAuthProvider({ intl, notify, apolloClient }),
|
||||
);
|
||||
await act(async () =>
|
||||
hook.result.current.login(
|
||||
nonStaffUserCredentials.email,
|
||||
nonStaffUserCredentials.password,
|
||||
);
|
||||
expect(result.user).toBe(null);
|
||||
});
|
||||
expect(hook.current.authenticated).toBe(false);
|
||||
),
|
||||
);
|
||||
|
||||
// Assert
|
||||
expect(hook.result.current.errors).toEqual([]);
|
||||
expect(hook.result.current.authenticated).toBe(false);
|
||||
});
|
||||
|
||||
it("Should logout user without userPermissions", async () => {
|
||||
const intl = useIntl();
|
||||
const notify = useNotifier();
|
||||
const apolloClient = useApolloClient();
|
||||
|
||||
(useAuth as jest.Mock).mockImplementation(() => ({
|
||||
login: jest.fn(() => ({
|
||||
data: {
|
||||
tokenCreate: {
|
||||
errors: [],
|
||||
user: {
|
||||
userPermissions: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
})),
|
||||
logout: jest.fn(),
|
||||
}));
|
||||
|
||||
// Act
|
||||
const hook = renderHook(() =>
|
||||
useAuthProvider({ intl, notify, apolloClient }),
|
||||
);
|
||||
await act(async () =>
|
||||
hook.result.current.login(
|
||||
nonStaffUserCredentials.email,
|
||||
nonStaffUserCredentials.password,
|
||||
),
|
||||
);
|
||||
|
||||
// Assert
|
||||
expect(hook.result.current.errors).toEqual(["noPermissionsError"]);
|
||||
expect(hook.result.current.authenticated).toBe(false);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -17,6 +17,7 @@ import {
|
|||
useAuth,
|
||||
useAuthState,
|
||||
} from "@saleor/sdk";
|
||||
import isEmpty from "lodash/isEmpty";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { IntlShape } from "react-intl";
|
||||
import urlJoin from "url-join";
|
||||
|
@ -140,10 +141,16 @@ export function useAuthProvider({
|
|||
includeDetails: false,
|
||||
});
|
||||
|
||||
if (isEmpty(result.data?.tokenCreate.user.userPermissions)) {
|
||||
setErrors(["noPermissionsError"]);
|
||||
await handleLogout();
|
||||
}
|
||||
|
||||
if (result && !result.data.tokenCreate.errors.length) {
|
||||
if (DEMO_MODE) {
|
||||
displayDemoMessage(intl, notify);
|
||||
}
|
||||
|
||||
saveCredentials(result.data.tokenCreate.user, password);
|
||||
} else {
|
||||
setErrors(["loginError"]);
|
||||
|
@ -183,6 +190,13 @@ export function useAuthProvider({
|
|||
input: JSON.stringify(input),
|
||||
});
|
||||
|
||||
if (
|
||||
isEmpty(result.data?.externalObtainAccessTokens.user.userPermissions)
|
||||
) {
|
||||
setErrors(["noPermissionsError"]);
|
||||
await handleLogout();
|
||||
}
|
||||
|
||||
if (result && !result.data?.externalObtainAccessTokens.errors.length) {
|
||||
if (DEMO_MODE) {
|
||||
displayDemoMessage(intl, notify);
|
||||
|
@ -223,7 +237,7 @@ export function useAuthProvider({
|
|||
loginByExternalPlugin: handleExternalLogin,
|
||||
logout: handleLogout,
|
||||
authenticating: authenticating && !errors.length,
|
||||
authenticated: authenticated && user?.isStaff,
|
||||
authenticated: authenticated && !!user?.isStaff && !errors.length,
|
||||
user: userDetails.data?.me,
|
||||
errors,
|
||||
};
|
||||
|
|
|
@ -82,6 +82,11 @@ const LoginView: React.FC<LoginViewProps> = ({ params }) => {
|
|||
if (externalAuthParamsExist && externalAuthNotPerformed) {
|
||||
handleExternalAuthentication(code, state);
|
||||
}
|
||||
|
||||
return () => {
|
||||
setRequestedExternalPluginId(null);
|
||||
setFallbackUri(null);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
|
|
|
@ -1,71 +0,0 @@
|
|||
import { ApolloClient, InMemoryCache } from "@apollo/client";
|
||||
import { BatchHttpLink } from "@apollo/client/link/batch-http";
|
||||
import { getApiUrl } from "@dashboard/config";
|
||||
import { createFetch } from "@saleor/sdk";
|
||||
import isCI from "is-ci";
|
||||
import path from "path";
|
||||
import { setupPolly } from "setup-polly-jest";
|
||||
|
||||
const POLLY_MODES = ["replay", "record", "passthrough", "stopped"] as const;
|
||||
|
||||
function getPollyMode() {
|
||||
const env = process.env.POLLY_MODE as (typeof POLLY_MODES)[number];
|
||||
if (!env) {
|
||||
return POLLY_MODES[0]; // replay
|
||||
}
|
||||
if (POLLY_MODES.includes(env)) {
|
||||
return env;
|
||||
}
|
||||
console.warn(`Unrecognised POLLY_MODE env variable value: ${env}`);
|
||||
return POLLY_MODES[0]; // replay
|
||||
}
|
||||
|
||||
function getPollyRecordIfMissing() {
|
||||
const env = process.env.POLLY_RECORD_IF_MISSING;
|
||||
if (!env) {
|
||||
return !isCI;
|
||||
}
|
||||
return env === "true";
|
||||
}
|
||||
|
||||
function setupApi() {
|
||||
setupPolly({
|
||||
adapters: [require("@pollyjs/adapter-node-http")],
|
||||
matchRequestsBy: {
|
||||
headers: false,
|
||||
url: {
|
||||
hash: false,
|
||||
hostname: true,
|
||||
password: false,
|
||||
pathname: true,
|
||||
port: false,
|
||||
protocol: false,
|
||||
query: false,
|
||||
username: false,
|
||||
},
|
||||
body: false,
|
||||
},
|
||||
mode: getPollyMode(),
|
||||
recordIfMissing: getPollyRecordIfMissing(),
|
||||
persister: require("@pollyjs/persister-fs"),
|
||||
persisterOptions: {
|
||||
keepUnusedRequests: false,
|
||||
fs: {
|
||||
recordingsDir: path.resolve(__dirname, "../recordings"),
|
||||
},
|
||||
},
|
||||
});
|
||||
const cache = new InMemoryCache();
|
||||
const link = new BatchHttpLink({
|
||||
fetch: createFetch(),
|
||||
uri: getApiUrl(),
|
||||
});
|
||||
const apolloClient = new ApolloClient({
|
||||
cache,
|
||||
link,
|
||||
});
|
||||
|
||||
return apolloClient;
|
||||
}
|
||||
|
||||
export default setupApi;
|
Loading…
Reference in a new issue