Error: No Keychain password item found for profile - electron

Trying to notarize Electron app.
Generated “App Manager” API key on https://appstoreconnect.apple.com/access/api.
Ran xcrun notarytool store-credentials test referencing AuthKey_*.p8 API key.
Wrote following notarize.js #electron/notarize script.
const { existsSync } = require("fs")
const { homedir } = require("os")
const { join } = require("path")
const electronNotarize = require("#electron/notarize")
module.exports = async function (context) {
if (process.platform !== "darwin") {
return
}
const appId = context.packager.config.appId
const appPath = join(
context.appOutDir,
`${context.packager.appInfo.productFilename}.app`
)
console.log(`Notarizing ${appId} found at ${appPath}…`)
await electronNotarize.notarize({
appPath: appPath,
keychain: `${homedir()}/Library/Keychains/login.keychain-db`,
keychainProfile: "test",
tool: "notarytool",
})
console.log(`Notarized ${appId} found at ${appPath}`)
}
When I run electron-builder build script which triggers afterSign which runs notarize.js, following error is thrown.
Error: No Keychain password item found for profile: test
What am I missing?

Related

{"reason":"BadDeviceToken"} http2 IOS notifications from Nodejs

I am trying to send push notifications using http2 api from my node backend.
I have the following with me from the IOS team .
.p8 AuthKey
Team ID
Key ID
We have generated the build from the production environment.
Key is generated using the AppStore selection.
I dont see any environment mismatch in the key, Device token and the build.
But still I get
:status: 400 apns-id: 91XXXX-XXXX-XXXX-XXXX-3E8XXXXXX7EC
{"reason":"BadDeviceToken"}
Code from Node backend :
const jwt = require('jsonwebtoken');
const http2 = require('http2');
const fs = require('fs');
const key = fs.readFileSync(__dirname + "/AuthKey_XXXXXXXXXX.p8", 'utf8')
const unix_epoch = Math.round(new Date().getTime() / 1000);
const token = jwt.sign(
{
iss: "XXXXXXXXXX", //"team ID" of developer account
iat: unix_epoch
},
key,
{
header: {
alg: "ES256",
kid: "XXXXXXXXXX", //issuer key "key ID" of p8 file
}
}
)
const host = 'https://api.push.apple.com'
const path = '/3/device/<device_token>'
const client = http2.connect(host);
client.on('error', (err) => console.error(err));
const body = {
"aps": {
"alert": "hello",
"content-available": 1
}
}
const headers = {
':method': 'POST',
'apns-topic': 'com.xxxxxx.xxxxxx', //your application bundle ID
':scheme': 'https',
':path': path,
'authorization': `bearer ${token}`
}
const request = client.request(headers);
// request.on('response', response => {
// console.log("apnresponse",JSON.stringify(response));
// });
request.on('response', (headers, flags) => {
for (const name in headers) {
console.log(`${name}: ${headers[name]}`);
}
});
request.setEncoding('utf8');
let data = ''
request.on('data', (chunk) => { data += chunk; });
request.write(JSON.stringify(body))
request.on('end', () => {
console.log(`\n${data}`);
client.close();
});
request.end();
IOS team is able to successfully send notifications to the device using the firebase console.
PUsh notifications fail only when I try from the node backend.
According to the Apple documentation, neither the device token is invalid, nor I am using production certificate for the development server or vice versa;
neither of which are the case here.
How can I make this work?

Expo React Native app. Error using expo-secure-store methods [The method or property SecureStore.setItemAsync is not available on ios]

I've followed expo documentation to include this library to my expo managed react native application. SecureStore
I am using:
expo: 44.0.5
react-native: 0.64.3 (SDK 44)
expo-secure-store: 11.1.0
expo-dev-client: 0.8.6
react & react-dom 18.0.0
typescript
In my App.tsx:
import 'expo-dev-client'
import { deleteValueFor, getValueFor, save } from './src/core/infrastructure/storage/secureStore'
import { REFRESH_TOKEN } from './src/core/infrastructure/config/constants'
....
export default function App(): JSX.Element | null {
....
useEffect(() => {
;(async () => {
try {
const refreshToken = await getValueFor(REFRESH_TOKEN)
...
// things I do whit refreshToken
...
} catch (e) {
console.warn(e)
}
})()
}, [])
const login = async (authUser: AuthUser) => {
const { token, refreshToken, user } = authUser
if (!user) {
throw 'Error al obtener los datos del usuario desde el context'
}
setToken(token)
save({ key: REFRESH_TOKEN, value: refreshToken }) // <---- The error occurs here
}
}
In secureStore.ts
import * as SecureStore from 'expo-secure-store'
export async function save({ key, value }: { key: string; value: string }): Promise<void> {
await SecureStore.setItemAsync(key, value)
}
export async function getValueFor(key: string): Promise<string | null> {
try {
return await SecureStore.getItemAsync(key)
} catch (error) {
return null
}
}
export async function deleteValueFor(key: string): Promise<void> {
await SecureStore.deleteItemAsync(key)
}
export async function checkAvailability(): Promise<boolean> {
return SecureStore.isAvailableAsync()
}
I execute this command to run the app in simulator:
expo start --dev-client --ios
The application is running fine inside the simulator, no errors with that. And after I fill login credentials and press in login button, this is the error message I'm getting:
[Unhandled promise rejection: Error: The method or property SecureStore.setItemAsync is not available on ios, are you sure you've linked all the native dependencies properly?]
at http://192.168.1.3:8082/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&hot=false&strict=false&minify=false:111339:321 in _createSuperInternal
at node_modules/expo-modules-core/build/errors/CodedError.js:10:8 in constructor
at http://192.168.1.3:8082/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&hot=false&strict=false&minify=false:111384:321 in _createSuperInternal
at node_modules/expo-modules-core/build/errors/UnavailabilityError.js:9:42 in constructor
at node_modules/expo-secure-store/build/SecureStore.js:103:14 in setItemAsync
at node_modules/expo-secure-store/build/SecureStore.js:97:7 in setItemAsync
at src/core/infrastructure/storage/secureStore.ts:4:8 in save
at src/core/infrastructure/storage/secureStore.ts:3:7 in save
at App.tsx:87:4 in login
I don't know what's wrong. Please help.
If anybody is working on a similar issue.
According to this issue
https://github.com/expo/expo/issues/16906
I had to rebuild my application due to expo-dev-client lib I'd being using in order to generate a new artifact. After that I could save my token using the expo-secure-store functions without problem.
I've fixed the error with replacing the expo package with:
https://github.com/react-native-async-storage/async-storage
The other alternatives are:https://reactnative.directory/?search=storage

Capacitor sign in with apple is not working

I am using Capacitor sign in with apple to login with Apple, this is my code:
registerApple(apple: string) {
SignInWithApple.authorize().then(resp => {
this.loginSocial(resp);
console.log("respuesta", resp.response);
if (this.error === true) {
this.activateTabMenu(true);
this.navCtrl.navigateRoot("/home");
} else {
this.register(resp.response, resp.response.user, null, null);
this.user.socialType = apple;
this.viewMode = "view1";
this.progressValue = 0.3;
this.dataDepTp();
}
}).catch((err) => console.log(err));
}
the thing is that when I test it it doesn't work, the Apple GUI doesn't open, and the xcode console prints the next message:
[log] - {"code":"UNIMPLEMENTED"}
I also already enable the Sign In with Apple in xcode and apple developers
what can I do?
Run on physical device or on macOS, iOS has a few issues with this plugin - https://github.com/capacitor-community/apple-sign-in/issues/23
The following example is Capacitor 3/4 related
Signin with apple requires an options field with a nonce.
The example below uses firebase and npm sha.js
Have a look at the https://github.com/capacitor-community/apple-sign-in docs
Also, the Firebase Apple Sign-in Setup guide explains the apple email relay config - https://firebase.google.com/docs/auth/ios/apple?authuser=0&hl=en'
async loginApple() {
if (this.platform.is('capacitor')) {
const rawNonce = 'any random string will do here';
const nonce = shajs('sha256').update(rawNonce).digest('hex');
const options: SignInWithAppleOptions = {
clientId: 'com.example.app',
redirectURI: 'https://your-app-name.firebaseapp.com/__/auth/handler',
scopes: 'email name',
state: '123456',
nonce,
};
try {
const { response } = await SignInWithApple.authorize(options);
console.log('app:auth: loginApple response - ', response);
}
}
}

Firebase database not working with Facebook Expo authentication

I've been developing an app with React Native (with Expo) and Firebase on the backend. When running the project through Expo client on the iPhone, I can normally login with email and password and then fetch data from Firebase database. But when I login with Facebook, database read hands and it does not resolve anything. Important parts of the code look following:
firebase.initializeApp(firebaseConfig);
// This works everywhere
export const login = async (email, password) => {
await firebase.auth().signInWithEmailAndPassword(email, password);
const userId = firebase.auth().currentUser.uid;
return userId + '';
};
export const loginByFacebook = async () => {
const { type, token } = await Expo.Facebook.logInWithReadPermissionsAsync(FB_APP_ID, {
permissions: ['public_profile'],
});
if (type === 'success') {
const credential = firebase.auth.FacebookAuthProvider.credential(token);
try {
await firebase.auth().signInAndRetrieveDataWithCredential(credential);
} catch (error) {
console.log('cannot login ', error);
}
}
};
export const readData = (key) => {
console.log('getWins ');
const userId = firebase.auth().currentUser.uid;
return firebase
.database()
.ref(`/${key}/${userId}`)
.once('value');
};
...
class PostList extends React.Component {
async componentDidMount() {
// it normally resolves when logged with email & password,
// resolves with facebook auth on iPhone simulator
// does not resolve with facebook auth on Expo client on iPhone
const data = await readData('posts');
}
}
However, what is really strange, that it does not work on iPhone + Expo client, but does on the iPhone simulator. The crucial part is in the async componentDidMount().
Database config is still in the dev mode (allow all read & writes):
{
"rules": {
".read": true,
".write": true
}
}
I've used the following guides: https://docs.expo.io/versions/latest/sdk/facebook
https://docs.expo.io/versions/latest/guides/using-firebase#listening-for-authentication
Are there any more prerequisites that I've forgotten to setup? Or Expo client has limitations in terms of properly handling calls with Facebook auth?

How to Update Device Configuration using Google Cloud functions and MQTT bridge

I am using the Google Cloud IoT with Pub/Sub.
I have a device reading sensor data and sending it to a topic in Pub/Sub.
I have a topic cloud function that is triggered by this message and I would like to have the device configuration updated, however I am unable to do so due to the following permission error.
index.js :
/**
* Triggered from a message on a Cloud Pub/Sub topic.
*
* #param {!Object} event The Cloud Functions event.
* #param {!Function} The callback function.
*/
var google = require('googleapis');
//var tt = google.urlshortener('v1');
//console.log(Object.getOwnPropertyNames(google.getAPIs()));
var cloudiot = google.cloudiot('v1');
function handleDeviceGet(authClient, name, device_id, err, data) {
if (err) {
console.log('Error with get device:', device_id);
console.log(err);
return;
}
console.log('Got device:', device_id);
console.log(data);
console.log(data.config);
var data2 = JSON.parse(
Buffer.from(data.config.binaryData, 'base64').toString());
console.log(data2);
data2.on = !data2.on;
console.log(data2);
var request2 = {
name: name,
resource: {
'versionToUpdate' : data.config.version,
'binaryData' : Buffer(JSON.stringify(data2)).toString('base64')
},
auth: authClient
};
console.log('request2' + request2);
var devices = cloudiot.projects.locations.registries.devices;
devices.modifyCloudToDeviceConfig(request2, (err, data) => {
if (err) {
console.log('Error patching device:', device_id);
console.log(err);
} else {
console.log('Patched device:', device_id);
console.log(data);
}
});
}
const handleAuth = (device_id) => {
console.log(device_id);
return (err, authClient) => {
const project_id = 'animated-bonsai-195009';
const cloud_region = 'us-central1';
const registry_id = 'reg1';
const name = `projects / ${project_id} /locations / ${cloud_region} /` +
`registries / ${registry_id} /devices / ${device_id}`;
if (err) {
console.log(err);
}
if (authClient.createScopedRequired &&
authClient.createScopedRequired()) {
authClient = authClient.createScoped(
['https://www.googleapis.com/auth/cloud-platforme']);
}
var request = {
name: name,
auth: authClient
};
// Get device version
var devices = cloudiot.projects.locations.registries.devices;
devices.get(request, (err, data) =>
handleDeviceGet(authClient, name, device_id, err, data));
}
};
exports.subscribe = (event, callback) => {
// The Cloud Pub/Sub Message object.
const pubsubMessage = event.data;
// We're just going to log the message to prove that
// it worked.
var obj = JSON.parse(Buffer.from(pubsubMessage.data, 'base64').toString());
console.log(Buffer.from(pubsubMessage.data, 'base64').toString());
console.log(event);
console.log(Object.getOwnPropertyNames(event));
console.log(callback);
let message = {
"watter": 1
};
message = new Buffer(JSON.stringify(message));
const req = {
name: event.data.deviceId,
resource: message
};
console.log(obj.deviceId);
google.auth.getApplicationDefault(handleAuth(obj['deviceId']));
// Don't forget to call the callback.
callback();
};
package.json :
{
"name": "sample-pubsub",
"version": "0.0.1",
"dependencies": {
"googleapis": "25.0.0"
}
}
Error:
A few options:
Check that you have enabled API access for the Google Cloud IoT Core API for the project used when creating the Google Cloud Function.
Check that you have enabled billing for your project
If you are deploying your Google Cloud Functions with gcloud beta functions deploy ... from the folder with your .js and package.json files, you may want to set the environment variables (GCLOUD_PROJECT and GOOGLE_APPLICATION_CREDENTIALS) or use gcloud auth application-default login before deploying in case you have multiple Google Cloud projects and need to enable the API on the configured one.
Update This community tutorial shows you how to do this - note that there have been some updates to Google Cloud Functions that require you to use a newer version of the Node JS client library as is done in the NodeJS sample and as corrected in this PR, note the version of the client library in package.json.

Resources