Google Fit APi for step count is giving permission denied for first time user - google-fit

i have developed an app which sync user step count from google fit. I have observed that users who are syncing as soon as the installation of google fit app in there mobile and user who haven't installed the app are getting the following error
{
"error": {
"code": 403,
"message": "datasource not found or not readable: derived:com.google.step_count.delta:com.google.android.gms:estimated_steps",
"errors": [
{
"message": "datasource not found or not readable: derived:com.google.step_count.delta:com.google.android.gms:estimated_steps",
"domain": "global",
"reason": "forbidden"
}
],
"status": "PERMISSION_DENIED"
}
}
When they reinstall the app it works fine
If they sync next day it will work
here is the code:
const timeGap = {
endTimeMillis: new Date().getTime() + 1 * 60 * 60 * 1000,
startTimeMillis: new Date('2021-01-01 00:00').getTime(),
};
return gapi.client.fitness.users.dataset
.aggregate({
userId: 'me',
resource: {
aggregateBy: [
{
dataTypeName: 'com.google.step_count.delta',
dataSourceId:
'derived:com.google.step_count.delta:com.google.android.gms:estimated_steps',
},
],
endTimeMillis: timeGap.endTimeMillis,
startTimeMillis: timeGap.startTimeMillis,
bucketByTime: {
durationMillis: 86400000,
},
},
})
.then(
(response) => {
console.log('[[[[[', response);
const stepVals = [];
console.log(response);
observer.next(response.result);
observer.complete();
},
(err: any) => {
observer.error(err);
observer.next(err);
// console.error("ERRRR", err);
observer.complete();
}
);

datasource not found ...
The DataSource you're trying to read won't exist until the user has synced data up to the server.
This error is reasonable to interpret as NOT_FOUND.

Related

Web Application doesn't communicate correctly with Ethereum smart contract deployed through Truffle

I coded this really simple smart contract in Solidity which allows users to add todo tasks to their personal list, to fetch their list of todos, and so on.
pragma solidity ^0.8.0;
contract ToDo {
struct Task {
string content;
bool completed;
}
mapping(address => Task[]) private tasks;
function addTask(string memory content) public {
tasks[msg.sender].push(Task(content, false));
}
function changeTaskState(uint256 taskId) public {
tasks[msg.sender][taskId].completed = !tasks[msg.sender][taskId].completed;
}
function editTaskContent(uint256 taskId, string memory content) public {
tasks[msg.sender][taskId].content = content;
}
function getTasks() public view returns(Task[] memory) {
return tasks[msg.sender];
}
}
This works exactly as intended when deployed through Truffle and tested in the Truffle(develop) terminal:
truffle(develop)> const todo = await ToDo.deployed()
undefined
truffle(develop)> todo.getTasks()
[]
truffle(develop)> todo.addTask("Hello, world!")
{
tx: '0x7e607352c1ab8f6532c5b43e282eb20f29d5bfa451dfbb873bac3506df00cb1a',
receipt: {
transactionHash: '0x7e607352c1ab8f6532c5b43e282eb20f29d5bfa451dfbb873bac3506df00cb1a',
transactionIndex: 0,
blockHash: '0x98b361190eadf1905c3e15b5054aa4ace8eaa33a2b4d35898f78e2165ea996a2',
blockNumber: 5,
from: '0x3455100c0b0617afbf0f53db5e5c07366e20791b',
to: '0x645a78fe8eb3529291ba63a8e420d26c7baf61a0',
gasUsed: 66634,
cumulativeGasUsed: 66634,
contractAddress: null,
logs: [],
status: true,
logsBloom: '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
rawLogs: []
},
logs: []
}
truffle(develop)> todo.changeTaskState(0)
{
tx: '0xddb313978411cd3f1429f1eb61b9bbde816e3a874d765aa5588a69508d226b44',
receipt: {
transactionHash: '0xddb313978411cd3f1429f1eb61b9bbde816e3a874d765aa5588a69508d226b44',
transactionIndex: 0,
blockHash: '0xbae43abf22ca06de65a41e3e54493ad944f4b997b12a3ed407bc5f778d00a3be',
blockNumber: 6,
from: '0x3455100c0b0617afbf0f53db5e5c07366e20791b',
to: '0x645a78fe8eb3529291ba63a8e420d26c7baf61a0',
gasUsed: 45320,
cumulativeGasUsed: 45320,
contractAddress: null,
logs: [],
status: true,
logsBloom: '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
rawLogs: []
},
logs: []
}
truffle(develop)> todo.getTasks()
[
[ 'Hello, world!', true, content: 'Hello, world!', completed: true ]
]
However, when I try to call these contract's functions from a web-app, it seems like there are some kind of communication errors with the local blockchain provided by Truffle.
Of course I've installed Metamask in my browser and I've connected it to http://127.0.0.1:9545 (as Truffle tells me to do upon executing the truffle develop command). I've also imported the private phrase provided by Truffle, so that I could access the 10 test addresses on that local network.
I've also found the contract's address and ABI in the build/contracts directory and set up a simple front end in React.
import Web3 from 'web3';
import React, { useState, useEffect } from "react";
const TODO_ABI =
[
{
"inputs": [
{
"internalType": "string",
"name": "content",
"type": "string"
}
],
"name": "addTask",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "taskId",
"type": "uint256"
}
],
"name": "changeTaskState",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "taskId",
"type": "uint256"
},
{
"internalType": "string",
"name": "content",
"type": "string"
}
],
"name": "editTaskContent",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "getTasks",
"outputs": [
{
"components": [
{
"internalType": "string",
"name": "content",
"type": "string"
},
{
"internalType": "bool",
"name": "completed",
"type": "bool"
}
],
"internalType": "struct ToDo.Task[]",
"name": "",
"type": "tuple[]"
}
],
"stateMutability": "view",
"type": "function",
"constant": true
}
];
const TODO_ADDRESS = "0x645a78fe8eb3529291ba63a8e420d26c7baf61a0";
function ChangeTaskStateButton(props) {
return (
<button onClick={ () => props.contract.methods.changeTaskState(props.id).call() }>{ props.state }</button>
);
}
function Task(props) {
return (
<li>
{ props.content } | <ChangeTaskStateButton contract={ props.contract } id={ props.id } state={ props.completed ? "Completed" : "Pending "}></ChangeTaskStateButton>
</li>
);
}
function TasksList(props) {
let tasks = [];
const tasksData = props.tasks;
for(let i = 0; i < tasksData.length; i++) {
tasks.push(<Task id={i} content={ tasksData[i].content } completed={ tasksData[i].completed } contract={ props.contract }></Task>);
}
return (
<div>
<ul>
{ tasks }
</ul>
</div>
);
}
function TaskForm(props) {
const [content, setContent] = useState("");
const handleSubmit = (event) => {
event.preventDefault();
props.contract.methods.addTask(content).call()
.then(() => props.setTasks(props.tasks.concat({content: content, completed: false})));
};
const handleChange = (event) => {
setContent(event.target.value);
};
return(
<form onSubmit={ handleSubmit }>
<input type="text" onChange={ handleChange }></input>
<button type="submit">Submit</button>
</form>
);
}
function App() {
const [web3] = useState(new Web3(Web3.givenProvider || "http://localhost:9545"));
const [contract] = useState(new web3.eth.Contract(TODO_ABI, TODO_ADDRESS));
const [tasks, setTasks] = useState([]);
useEffect(() => {
contract.methods.getTasks().call()
.then(tasks => {
setTasks(tasks);
});
}, [contract.methods]);
return (
<div>
<TaskForm contract={contract} setTasks={setTasks} tasks={tasks}></TaskForm>
<TasksList tasks={tasks} contract={contract}></TasksList>
</div>
);
}
The call to getTasks() always returns an empty array, even if I add a task through the terminal with the same address that's currently in use on Metamask, while the call to addTask() doesn't store anything in the smart contracts's map. The call to these two functions don't cause any errors or warnings to appear in the browser's console. However, the call to changeTaskState() does cause two errors do be displayed:
inpage.js:1 MetaMask - RPC Error: Internal JSON-RPC error.
{code: -32603, message: "Internal JSON-RPC error.", data: {…}}
code: -32603
data: {message: "VM Exception while processing transaction: revert", code: -32000, data: {…}}
message: "Internal JSON-RPC error."
__proto__: Object
index.js:50 Uncaught (in promise) Error: Internal JSON-RPC error.
{
"message": "VM Exception while processing transaction: revert",
"code": -32000,
"data": {
"0x359c33ac64b2b3eb0096b40b2d225679d4212f40fc86ef938af49fcc47159f2c": {
"error": "revert",
"program_counter": 994,
"return": "0x4e487b710000000000000000000000000000000000000000000000000000000000000032"
},
"stack": "RuntimeError: VM Exception while processing transaction: revert\n at Function.RuntimeError.fromResults (C:\\Users\\gianm\\AppData\\Roaming\\npm\\node_modules\\truffle\\build\\webpack:\\node_modules\\ganache-core\\lib\\utils\\runtimeerror.js:94:1)\n at C:\\Users\\gianm\\AppData\\Roaming\\npm\\node_modules\\truffle\\build\\webpack:\\node_modules\\ganache-core\\lib\\blockchain_double.js:568:1",
"name": "RuntimeError"
}
}
at Object._fireError (index.js:50)
at sendTxCallback (index.js:540)
at cb (util.js:689)
at callbackifyOnRejected (util.js:666)
at Item.push../node_modules/process/browser.js.Item.run (browser.js:153)
at drainQueue (browser.js:123)
I've also tried to use Ganache, instead of Truffle's built-in local blockchain, and I even tried to change browser, but nothing seems to work. I've also checked whether Metamask was actually connected to the webapp and sure enough it was. What am I missing here?
There are two main ways to interact with a smart contract. A call (read-only, free) and a transaction (read-write, requires gas fees).
Your react code uses the .call() method for addTask() and changeTaskState(), which doesn't allow writing in the contract storage.
Since you're working with MetaMask, you should use the Ethereum Provider API and submit a request to MM that will ask the user to confirm the transaction.
So instead of the props.contract.methods.addTask(content).call() you can get the contents of the data field and then generate the transaction request.
const data = props.contract.methods.addTask(content).encodeABI();
ethereum.request({
method: 'eth_sendTransaction',
params: [{
from: senderAddress,
to: contractAddress,
data: data
}],
});
Note: You can set the senderAddress after connecting to MM.
Another way is to use the web3 .send() method, but this requires passing the private key of the sender to web3 (bad idea in a frontend JS app) or unlocked provider account (local providers usually have few unlocked accounts, but production ones don't).

setDiscoverTargets is not allowed for chrome extension

I am trying to develop a chrome extension and in this extension, I need the target related events (targetCreated/targetInfoChanged/targetDestroyed).
To achieve that goal I am using setDiscoverTargets method from the devtools protocol by means of chrome.debugger API. Here is the pseudocode that I am using:
// attach the debugger
chrome.debugger.attach(debuggeeId, version, onAttach);
// when attach is successful send setAuthAttach to make setDiscoverTargets command work
const onAttach = (debuggeeId) => {
if (chrome.runtime.lastError) {
alert(chrome.runtime.lastError.message);
return;
}
console.log(`onAttach: ${JSON.stringify(debuggeeId)}`);
chrome.debugger.sendCommand({ tabId: myTabId }, "Target.setAutoAttach", { autoAttach: false, waitForDebuggerOnStart: false, flatten: true }, setAutoAttachHandler);
}
// when auto attach handler is successful send setDiscoverTargets method
// to enable targetCreated/targetInfoChanged/targetDestroyed events
const setAutoAttachHandler = (result) => {
if (chrome.runtime.lastError) {
console.log("error in setAutoAttachHandler:" + chrome.runtime.lastError.message);
return;
}
console.log(`setAutoAttachHandler result: ${JSON.stringify(result)}`);
chrome.debugger.sendCommand({ tabId: myTabId }, 'Target.setDiscoverTargets', { discover: true }, setDiscoverTargetsHandler);
}
// see the result of command
const setDiscoverTargetsHandler = (result) => {
if (chrome.runtime.lastError) {
console.log("error in setDiscoverTargetsHandler:" + chrome.runtime.lastError.message);
return;
}
console.log(`setDiscoverTargets result: ${JSON.stringify(result)}`);
}
As per execute the code above I am always getting not allowed error
error in setDiscoverTargetsHandler:{"code":-32000,"message":"Not
allowed"}
And the events related to the target are not fired. Is there anything else I should do to get those events?
thank you.
Methods under Target and Browser domain(except for Browser.getVersion) are not allowed when sending command from chrome.debugger api. But if you want to observe for tabs to which debugger is attached or tabs in which developer tools is opened then you can poll chrome.debugger.getTargets at regular intervals. You will get response, something like this :-
[{
"attached": true,
"faviconUrl": "https://www.wikipedia.org/static/favicon/wikipedia.ico",
"id": "DEA9ED6A4A3DFB9A6FC315AF7110465B",
"tabId": 88,
"title": "Wikipedia",
"type": "page",
"url": "https://www.wikipedia.org/,
}, {
"attached": false,
"faviconUrl": "https://github.githubassets.com/favicons/favicon.svg",
"id": "3314432045C3EC141D4C7D7023606122",
"tabId": 87,
"title": "GitHub",
"type": "page",
"url": "https://github.com/"
}]

Can't get Auth0 integration working with feathers

I'm having a hard time getting Auth0 integration working. I'm getting the response shown below
{
"name": "NotAuthenticated",
"message": "error:0909006C:PEM routines:get_name:no start line",
"code": 401,
"className": "not-authenticated",
"data": {
"library": "PEM routines",
"function": "get_name",
"reason": "no start line",
"code": "ERR_OSSL_PEM_NO_START_LINE"
},
"errors": {}
}
When doing a GET to https://localhost:433/users with headers
{
Authorization: Bearer REMOVED
}
The REMOVED part above was the token returned from calling
curl 'http://localhost:3030/users/' -H 'Content-Type: application/json'
Here is my default.json
{
"host": "localhost",
"port": 433,
"public": "../public/",
"paginate": {
"default": 10,
"max": 50
},
"authentication": {
"entity": "user",
"service": "users",
"secret": "REMOVED",
"authStrategies": [
"jwt",
"local"
],
"jwtOptions": {
"header": {
"typ": "access"
},
"audience": "http://vice-node-boilerplate",
"issuer": "feathers",
"algorithm": "RS256",
"expiresIn": "1d"
},
"local": {
"usernameField": "email",
"passwordField": "password"
},
"oauth": {
"redirect": "/",
"auth0": {
"key": "REMOVED",
"secret": "REMOVED",
"subdomain": "vicesoftware"
}
}
},
"postgres": "postgres://postgres:#localhost:5432/vice_node_boilerplate"
}
I've updated authentication.js as shown below
const { AuthenticationService, JWTStrategy } = require('#feathersjs/authentication');
const { LocalStrategy } = require('#feathersjs/authentication-local');
const { expressOauth, OAuthStrategy } = require('#feathersjs/authentication-oauth');
class Auth0Strategy extends OAuthStrategy {
async getEntityData(profile) {
const baseData = await super.getEntityData(profile);
return {
...baseData,
email: profile.email
};
}
}
module.exports = app => {
const authentication = new AuthenticationService(app);
authentication.register('jwt', new JWTStrategy());
authentication.register('local', new LocalStrategy());
authentication.register('auth0', new Auth0Strategy());
app.use('/authentication', authentication);
app.configure(expressOauth());
};
and I've updated index.js as shown below
/* eslint-disable no-console */
const https = require('https');
const fs = require('fs');
const logger = require('./logger');
const app = require('./app');
const port = app.get('port');
const key = fs.readFileSync(__dirname + '/localhost-key.pem');
const cert = fs.readFileSync(__dirname + '/localhost.pem');
if (!key) {
throw Error("Unable to read certificate key file");
}
if (!cert){
throw Error("Unable to read certificate cert key file");
}
const server = https.createServer({
key,
cert
}, app).listen(port);
process.on('unhandledRejection', (reason, p) =>
logger.error('Unhandled Rejection at: Promise ', p, reason)
);
server.on('listening', () =>
logger.info('Feathers application started on http://%s:%d', app.get('host'), port)
);
I generated the local dev cert files localhost-key.pem and localhost.pem following the instructions found here: https://auth0.com/docs/libraries/secure-local-development
Edit 1
Note that I also tried generating a cert using these instructions from node.js docs: https://nodejs.org/en/knowledge/HTTP/servers/how-to-create-a-HTTPS-server/
You changed the jwtOptions.algorithm configuration to RS256. This needs additional configuration, specifically a valid private key. The error indicates that the private key provided is not valid. More information can be found in the node-jsonwebtoken documentation. I recommend to stick with the default HS256/384/512 algorithms if you are not sure.

ASP Net Core IdentityServer, "The issuer is invalid" on production environment

I'm trying to deploy on production (AWS Elasticbeanstalk server) a simple asp net core project that use IdentityServer; my test project is basically the React.js template of Visual Studio 2019 with enabled authentication.
In development all works fine, but in production I have an error when a try to use the jwt token to authenticate to my api.
WWW-Authenticate: Bearer error="invalid_token", error_description="The issuer 'http://***.elasticbeanstalk.com' is invalid"
The access_token used is what was returned from the call
POST http://***.elasticbeanstalk.com/connect/token
The strange behavior is that the following request to
GET http://***.elasticbeanstalk.com/connect/userinfo
It correctly returns the user data, access_token is used here, so I think the token is correct.
Unfortunately, the request to my api fails with the error above.
My Startup.cs code is this:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddDefaultIdentity<ApplicationUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
services.AddIdentityServer()
.AddApiAuthorization<ApplicationUser, ApplicationDbContext>();
services.AddAuthentication()
.AddIdentityServerJwt();
services.AddControllersWithViews();
services.AddRazorPages();
// In production, the React files will be served from this directory
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/build";
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseSpaStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseIdentityServer();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller}/{action=Index}/{id?}");
endpoints.MapRazorPages();
});
app.UseSpa(spa =>
{
spa.Options.SourcePath = "ClientApp";
if (env.IsDevelopment())
{
spa.UseReactDevelopmentServer(npmScript: "start");
}
});
}
The appsetting.json file contains this:
{
"ConnectionStrings": {
"DefaultConnection": "***"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"IdentityServer": {
"Clients": {
"myapp": {
"Profile": "IdentityServerSPA",
"RedirectUris": [ "/signin-oidc" ]
}
},
"Key": {
"Type": "Store",
"StoreName": "My",
"StoreLocation": "LocalMachine",
"Name": "CN=http://***.elasticbeanstalk.com"
}
},
"AllowedHosts": "*"
}
In your startup set your domain's address
services.AddIdentityServer(options =>
{
options.IssuerUri = "http://***.elasticbeanstalk.com";
})

Need to add more than usernameField in feathersjs

I'm new to feathersjs I'm building a backend server using it, and need to add 2 ways of local authentication, by email, or mobile
I've already added new local to the config/default.json as the following
"local-mobile": {
"usernameField": "mobile",
"passwordField": "password"
},
here's my authentication.js file
const { AuthenticationService, JWTStrategy } = require('#feathersjs/authentication');
const { LocalStrategy } = require('#feathersjs/authentication-local');
const { expressOauth } = require('#feathersjs/authentication-oauth');
module.exports = app => {
const authentication = new AuthenticationService(app);
authentication.register('jwt', new JWTStrategy());
authentication.register('local', new LocalStrategy());
authentication.register('local-mobile', new LocalStrategy());
app.use('/authentication', authentication);
app.configure(expressOauth());
};
in src/authentication
But when I send a post request to the authentication endpoint using postman with the following body
{
"strategy":"local-mobile",
"mobile":".......",
"password":"........"
}
the response is coming
{
"name": "NotAuthenticated",
"message": "Invalid authentication information",
"code": 401,
"className": "not-authenticated",
"errors": {}
}
any Idea ?
If you want to allow authentication through the authenticate endpoint, the strategy also has to be added to the authStrategies configuration setting in your config/default.json (feathers-chat example):
{
"authentication": {
// ...
"authStrategies": [
"jwt",
"local",
"local-mobile",
]
}
// ...
}