Deno server TLS Alert HandshakeFailure - fetch

I just installed deno to try use it. I wanted to use fetch function to post some data like this :
async function post(url: string, data: FormData): Promise<Response> {
const response = await fetch(url, {
method: 'POST',
body: data,
});
return response;
}
I get this error when I run my code with deno run --allow-net main.ts:
TLS alert received: Message {
typ: Alert,
version: TLSv1_2,
payload: Alert(
AlertMessagePayload {
level: Fatal,
description: HandshakeFailure,
},
),
}
error: Uncaught (in promise) TypeError: error sending request for url (https://***********): error trying to connect: received fatal alert: HandshakeFailure
at handleError (deno:core/core.js:186:12)
at jsonOpParseResult (deno:core/core.js:356:9)
at asyncHandle (deno:core/core.js:223:40)
at Array.asyncHandlers.<computed> (deno:core/core.js:238:9)
at handleAsyncMsgFromRust (deno:core/core.js:207:32)
However, when I use Curl in Command-line to send data instead, it works.
deno --version gives me:
deno 1.8.3 (release, x86_64-apple-darwin)
v8 9.0.257.3
typescript 4.2.2
Why does it work with Curl but not with deno ? How can I fix this problem

You have probably run into this issue
Basically the TLS library that Deno uses (rustls) is quite strict and does not support weak ciphers. You can check what ciphers the server offers using the Qualsys SSL Test.

Related

Unable to start Next 13 app directory (beta) in production mode

Step 1: Automatically create a new Next.js project using the new beta app directory:
npx create-next-app#latest --experimental-app
pages/api/hello.ts
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import type { NextApiRequest, NextApiResponse } from 'next'
type Data = {
name: string
}
export default function handler(
req: NextApiRequest,
res: NextApiResponse<Data>
) {
res.status(200).json({ name: 'John Doe' })
}
This file is identical to the one created automatically created by npx - there are no modifications.
I am trying to build a simple home page, which fetches data from the api which gets data from my database. Either way an await/async will be required. I am following the instructions from here.
In this example I will demonstrate that even awaiting the supplied hello api can't seem to run in production, and I can't work out why.
app/page.tsx
async function getHelloAsync() {
const res = await fetch('http://localhost:3000/api/hello', { cache: 'no-store' });
// The return value is *not* serialized
// You can return Date, Map, Set, etc.
// Recommendation: handle errors
if (!res.ok) {
// This will activate the closest `error.js` Error Boundary
throw new Error('Failed to fetch data');
}
return res.json();
}
export default async function Page() {
const hello = await getHelloAsync();
return (
<main>
<h1>Hello: {hello.name}</h1>
</main>
)
}
To test the hello api works, I confirm that running pn run dev and then curl http://localhost:3000/api/hello the following successful response is received:
{"name":"John Doe"}
Next up we exit the dev server and run:
pn run build
The first headache is that the build will completely fail to build unless one adds { cache: 'no-store' } to the fetch command:
const res = await fetch('http://localhost:3000/api/hello', { cache: 'no-store' });
or adds this to the top of app/page.tsx:
export const fetchCache = 'force-no-store';
I am actually not sure how one would even build this if you wanted to cache the response or use revalidate instead and provide an initial optimistic response, because without cache: no-store it refuses to build outright. Ideally instead it should just cache the result from /api/hello and not fail. Running the dev server at the same idea as doing the build does allow the build to work, but then as soon as you exit the dev server and run pn run start then all the api calls fail anyway. So that is not a good idea.
This leads us to the next problem - why are the api calls not working in production (i.e. when calling pn run start).
Step 2:
pn run build
pn run start
Confirm that the following still works and yes it does:
curl http://localhost:3000/api/hello
Result:
{"name":"John Doe"}
Now we visit http://localhost:3000 in a browser but, surprise! We get the following error:
> next start
ready - started server on 0.0.0.0:3000, url: http://localhost:3000
warn - You have enabled experimental feature (appDir) in next.config.js.
warn - Experimental features are not covered by semver, and may cause unexpected or broken application behavior. Use at your own risk.
info - Thank you for testing `appDir` please leave your feedback at https://nextjs.link/app-feedback
(node:787) ExperimentalWarning: The Fetch API is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
TypeError: fetch failed
at Object.fetch (node:internal/deps/undici/undici:11118:11)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async getHelloAsync (/Users/username/nextjstest/.next/server/app/page.js:229:17)
at async Page (/Users/username/nextjstest/.next/server/app/page.js:242:19) {
cause: Error: connect ECONNREFUSED ::1:3000
at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1300:16)
at TCPConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17) {
errno: -61,
code: 'ECONNREFUSED',
syscall: 'connect',
address: '::1',
port: 3000
}
}
[Error: An error occurred in the Server Components render. The specific message is omitted in production builds to avoid leaking sensitive details. A digest property is included on this error instance which may provide additional details about the nature of the error.] {
digest: '3567993178'
}
Why is it saying that the connection is refused when we know the API is available? I can't get this to run at all. I know this is beta but surely the code should actually run right? How do I make this code work?
Also if anyone knows where where the logs are that I'm supposed to be accessing to see digest '3567993178' please let me know.

"error - unhandledRejection: Error: listen EADDRINUSE: address already in use :::3000" when I use Slack Bolt for JavaScript with ngrok and Next.js

Background
We are developing a Slack Bot. This time we are using Bolt for JavaScript (Node.js) provided by Slack, React, Next.js, and ngrok. Here is what each of them does.
Bolt for JavaScript: I don't want to use Slack's bare-bones API, but want to benefit from the function that wraps it.
React: Needed to use Next.js
Next.js: Slack needs a request URL to notify my bot app when events such as mentions occur in Slack, but Next.js makes it easy to create an API endpoint to be set to that URL (e.g. /api/something)
ngrok: In the local development environment, that URL will be http://localhost:3000, so the protocol will be http instead of https. Slack does not allow this, so we need a URL that starts with https that tunnels to the local http://localhost:3000. ngrok provides that easily!
Problem to be solved.
I have already confirmed that if I type #xxxx in a certain workspace in Slack, the event is notified to https://xxxx.jp.ngrok.io/api/slack/events. However, in this API file
app.event("app_mention", async ({ event, say }) => {
.
.
.
}
is not invoked and the following error occurs
error - unhandledRejection: Error: listen EADDRINUSE: address already in use :::3000
I would like to know why and how to resolve this.
Source code
/api/slack/events.ts
import type { NextApiRequest, NextApiResponse } from "next";
require("dotenv").config();
import app from "../../../config/slackAuth";
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
// Unique case for Slack challenge
if (req.body.challenge) return res.status(200).json(req.body);
// Subscribe to 'app_mention' event in your App config
// See https://api.slack.com/tutorials/tracks/responding-to-app-mentions
app.event("app_mention", async ({ event, say }) => {
try {
// Response to the message in the thread where the event was triggered with #${message.user}
// See https://slack.dev/bolt-js/concepts#message-sending
await say({
text: `Hi <#${event.user}>!`,
thread_ts: event.ts,
});
} catch (error) {
await say({
text: `<#${event.user}> ${error.message}.`, // #userName Request failed with status code 429.
thread_ts: event.ts,
});
}
});
(async () => {
// Start this app
await app.start(process.env.PORT || 3000);
console.log("⚡️ Bolt app is running!");
})();
return res.status(404).json({ message: "Unknown event type" });
}
Error code
error - unhandledRejection: Error: listen EADDRINUSE: address already in use :::3000
at Server.setupListenHandle [as _listen2] (net.js:1331:16)
at listenInCluster (net.js:1379:12)
at Server.listen (net.js:1465:7)
at C:\Users\81906\Documents\slackGpt3\node_modules\#slack\bolt\dist\receivers\HTTPReceiver.js:176:25
at new Promise (<anonymous>)
at HTTPReceiver.start (C:\Users\81906\Documents\slackGpt3\node_modules\#slack\bolt\dist\receivers\HTTPReceiver.js:142:16)
at App.start (C:\Users\81906\Documents\slackGpt3\node_modules\#slack\bolt\dist\App.js:241:30)
at eval (webpack-internal:///(api)/./pages/api/slack/events.ts:69:69)
at handler (webpack-internal:///(api)/./pages/api/slack/events.ts:71:7)
at Object.apiResolver (C:\Users\81906\Documents\slackGpt3\node_modules\next\dist\server\api-utils\node.js:363:15) {
code: 'EADDRINUSE',
errno: -4091,
syscall: 'listen',
address: '::',
port: 3000
}
Issue
Using Slack Bolt for JavaScript with Next.js is not straightforward due to the following reasons:
Running npm run dev in a Next.js project starts a server at localhost:3000.
Running app.start() in Slack Bolt for JavaScript starts a server using Express.js, which also tries to use localhost:3000.
This causes an error because two servers are trying to use the same port.
This information was provided by someone at Slack, and the source can be found at https://github.com/slackapi/bolt-js/issues/1687.
Solution
You can change the port number used by Bolt to, for example, 3001.
However, this will make it difficult for the two servers at localhost:3000 and 3001 to communicate with each other.
The request URL registered in the Slack Bolt for JavaScript console is set to 3000, so events received there will not be able to flow to port 3001.

Cloud function throws error when bot fetches my pwa through Rendertron with Firebase middleware

I have deployed a Rendertron instance on GCP (https://rendertron-creatillo.ey.r.appspot.com/)
And set up my middleware as a Cloud Function on Firebase as described here: https://github.com/justinribeiro/pwa-firebase-functions-botrender
When I run it through Google's mobile friendly test page (https://search.google.com/test/mobile-friendly) I get these errors in the log:
2022-08-23T15:49:48.486178Zappi83gp1p4qz98 Unhandled rejection
Error
2022-08-23T15:49:48.490217Zappi83gp1p4qz98 FetchError: redirect location header missing at: https://rendertron-creatillo.ey.r.appspot.com/render/http://creatillo.com/post/how-its-made-hurth-6-march-2208 at ClientRequest.<anonymous> (/workspace/node_modules/node-fetch/index.js:152:13) at ClientRequest.emit (events.js:203:15) at ClientRequest.EventEmitter.emit (domain.js:466:23) at HTTPParser.parserOnIncomingClient [as onIncoming] (_http_client.js:565:21) at HTTPParser.parserOnHeadersComplete (_http_common.js:111:17) at TLSSocket.socketOnData (_http_client.js:451:20) at TLSSocket.emit (events.js:198:13) at TLSSocket.EventEmitter.emit (domain.js:466:23) at addChunk (_stream_readable.js:288:12) at readableAddChunk (_stream_readable.js:269:11)
Debug
2022-08-23T15:49:48.495068257Zappi83gp1p4qz98 Function execution took 11324 ms. Finished with status: crash
Error
2022-08-23T15:49:48.581883Zappi83gp1p4qz98 Error: Process exited with code 16 at process.on.code
And the test results in this:
URL is not available to Google.
It cannot be tested.
What seems strange to me is that a http url is being fetched by Rendertron in these cases, though I'm not sure that's the issue.
I've tried to look for what these GCP error messages stand for, but hadn't run into a similar situation.
Code served for crawlers:
app.get('*', (req, res) => {
const botResult = checkForBots(req.headers['user-agent']);
if (botResult) {
const targetUrl = generateUrl(req);
fetch(`${FIREBASE_CONFIG.rendertron.server}/render/${targetUrl}`)
.then(function(res) {
return res.text();
}).then(function(body) {
res.set('Cache-Control', 'public, max-age=300, s-maxage=600');
res.set('Vary', 'User-Agent');
res.send(body.toString());
});
} else {
res.send(pwaShell());
}
});

why drash with specific version causes error on deno?

I'm exploring deno. I just got an issue while trying to start my (first ::) deno server, output saying "404"
server file is like:
import { Drash } from "https://deno.land/x/drash#v1.0.0-rc1/mod.ts";
const server = new Drash.Http.Server({
response_output: "application/json",
resources: [],
});
server.run({
hostname: "localhost",
port: 2803,
});
Command returned:
➜ helloDeno deno run --allow-net app.ts
Compile file:///home/totone/dev/solo/projects/helloDeno/app.ts
Download https://deno.land/std#v1.0.0-rc1/http/server.ts
Download https://deno.land/std#v1.0.0-rc1/http/http_status.ts
Download https://deno.land/std#v1.0.0-rc1/testing/asserts.ts
Download https://deno.land/std#v1.0.0-rc1/io/bufio.ts
Download https://deno.land/std#v1.0.0-rc1/io/readers.ts
Download https://deno.land/std#v1.0.0-rc1/mime/multipart.ts
Download https://deno.land/std#v1.0.0-rc1/http/cookie.ts
error: Uncaught Error: Import 'https://deno.land/std#v1.0.0-rc1/io/readers.ts' failed: 404 Not Found
at unwrapResponse ($deno$/ops/dispatch_json.ts:43:11)
at Object.sendAsync ($deno$/ops/dispatch_json.ts:98:10)
at async processImports ($deno$/compiler.ts:736:23)
at async processImports ($deno$/compiler.ts:753:7)
at async processImports ($deno$/compiler.ts:753:7)
at async processImports ($deno$/compiler.ts:753:7)
at async processImports ($deno$/compiler.ts:753:7)
at async compile ($deno$/compiler.ts:1316:31)
at async tsCompilerOnMessage ($deno$/compiler.ts:1548:22)
at async workerMessageRecvCallback ($deno$/runtime_worker.ts:74:9)
At beginning, I though that it was a bad use of --allow-net deno permission, but I tried once to reload server without a specific version for drash & it worked.
➜ helloDeno deno run --allow-net app.ts
Compile file:///home/totone/dev/solo/projects/helloDeno/app.ts
So the issue is near #v1.0.0-rc1 package version. Who can help me understanding the reason of this behaviour?
Thanks
drash is trying to import https://deno.land/std#v1.0.0-rc1/io/readers.ts (and other std/#v1.0.0-rc1) which does not exist.
std current version is v0.51.0.
You should use drash#v1.0.0 which is the latest drash version and uses an existing std version.
import { Drash } from "https://deno.land/x/drash#v1.0.0/mod.ts";

SkypeSDK Video and audio issue - mediaRelayAccessToken not found

I'm having problems with adding an audio or a video service to a coversation.
The chat service works fine for me.
When I add a video or an audio service I get following error:
Error: GET /ucwa/oauth/v1/applications/113925534802/communication/mediaRelayAccessToken failed: 404
{
[functions]: ,
__proto__: { },
code: "RequestFailed",
description: "GET /ucwa/oauth/v1/applications/113925534802/communication/mediaRelayAccessToken failed: 404",
message: "GET /ucwa/oauth/v1/applications/113925534802/communication/mediaRelayAccessToken failed: 404",
name: "Error",
req: { },
rsp: { },
stack: "Error: GET /ucwa/oauth/v1/applications/113925534802/communication/mediaRelayAccessToken failed: 404
at process (https://swx.cdn.skype.com/build2015/v5/SDK-build.js:8079:29)
at Anonymous function (https://swx.cdn.skype.com/build2015/v5/SDK-build.js:8018:29)
at Anonymous function (https://swx.cdn.skype.com/build2015/v5/SDK-build.js:1714:25)
at map (https://swx.cdn.skype.com/build2015/v5/SDK-build.js:1331:25)
at decompose (https://swx.cdn.skype.com/build2015/v5/SDK-build.js:8017:25)
at Anonymous function (https://swx.cdn.skype.com/build2015/v5/SDK-build.js:8007:29)
at handle (https://swx.cdn.skype.com/build2015/v5/SDK-build.js:2220:33)
at Anonymous function (https://swx.cdn.skype.com/build2015/v5/SDK-build.js:698:25)"
}
The Skype For Business Plugin is installed and works fine.
A Skype Edge server is currently not installed.
I'm using Internet Explorer 11.
The error occurs with the Skype Web SDK On Prem Sample from Microsoft as well as on my own website.
When I try to add video or audio for the second time to the same conversation i dont get any error message at all, but it still doesn't work. The request doesnt show up in the dev tools nor in fiddler. I'm using the latest version of the Skype SDk bootstrapper.
Both clients and server are in the same subnet.
Thanks in advance.
I encountered the same problem. Not sure how it happens, but the sdk has troubles to fetch or apply the media config.
You can use the this workaround:
Following line 18,892 in the debug version of the sdk, comment out both calls:
uninit();
throw error;
in the function init() of the section MediaConfig. Resulting in:
function init() {
pcMediaConfig = mediaPlugin.createComponent({
type: 'MediaPlatformConfig',
hide: true,
inproc: false
});
pcMediaConfig.event(onPluginComponentEvent);
pcMediaConfig.state.changed(function (state) {
log('pcMediaConfig.state = ' + state);
});
var p = pcMediaConfig.load().then(getMediaConfig).then(setMediaConfig).then(null, function (error) {
log('MediaConfig::init rejected');
//uninit();
//throw error;
});
return p;
}
Therefore you have to download the bootstrapper and the sdk to permanently apply the patch. To do this just fetch both in the debug version (bootstrapper version 1.2.5) and replace in function onConfig(config) line 48
}, config.corsScript && (scriptAttributes.crossOrigin = ""), loader.loadScript(getPackageUrl(config), null, handleError, scriptAttributes);
with
}, config.corsScript && (scriptAttributes.crossOrigin = ""), loader.loadScript("./scripts/SkypeSDK.js", null, handleError, scriptAttributes);
or your equivalent path
This is currently a limitation of the Skype Web SDK: it has a dependency on the mediaRelayAccessToken to proceed with audio/video calls. The dev team is aware of this issue and it may be fixed in a future release of Skype Web SDK.
The hacky way recommended above is basically to allow the SDK to continue the call upon missing mediaRelayAccessToken, so it may let you bypass the issue.
The media relay access token is returned by an edge server, so you may also try to deploy an edge server to work around this issue.

Resources