Unable to decode jwt with jwt-decode - javascript

I'm trying to decode my token with jwt-decode but I can't. It gives me the following error. Does anyone know why?
ERROR Error: Uncaught (in promise): TypeError: jwt_decode_1.default is
not a function TypeError: jwt_decode_1.default is not a function
at RoleGuardService.canActivate (role-guard.service.ts?d7c4:19)
import jwt_decode from 'jwt-decode';
canActivate(route: ActivatedRouteSnapshot): boolean {
// this will be passed from the route config
// on the data property
const expectedRole = route.data.expectedRole;
const token = localStorage.getItem('token');
// decode the token to get its payload
const tokenPayload = jwt_decode(token);
console.log(tokenPayload);
if (
!this.auth.isAuthenticated() ||
tokenPayload.role !== expectedRole
) {
this.router.navigate(['login']);
return false;
}
return true;
}

I think you should import it like this:
import * as jwt_decode from 'jwt-decode';

According to documentation + internet search, the correct way is:
1. Install the package + types
npm install --save jwt-decode
npm install --save #types/jwt-decode
When you import the jwt_decode, you should surpass a rule from tslint, your code will look exactly like this (with commented line above)
// #ts-ignore
import jwt_decode from "jwt-decode";
Otherwise you will get an error like this
You can add also the rule for that on tsconfig.json , but is 1 time exception :)

I had the same error but after many attempts I did manage to solve this problem by using another method:
private decode(token: string) {
try {
return JSON.parse(atob(token.split(".")[1]));
} catch (e) {
console.log("error decoding token");
}
}
function atob() references

jwt_decode has always been a CommonJS module which generally are imported as const jwt_decode = require('jwt-decode');, it's what Node.js uses.
The way to import CommonJS libraries with a JS import statement is import * as library-name from 'library-name;.
Modern frameworks like Angular 10 throw a warning when using packages with the CommonJS format, because they generally speaking can't be tree-shaked.
Version 3 (now in beta) of this library includes a more modern ESM build, which is what JS import statements are meant for, so importing the modern ESM package can be done the regular way using import jwt_decode from 'jwt-decode';. This is a breaking change, that's why I've created a new major version 3.
We still have a CommonJS build, but by default most modern build systems for the web (not node) will use the ESM build.
if you checkout the package.json file when installing the lib, you'll notice both builds in there.
{
...
"main": "build/jwt-decode.cjs.js",
"module": "build/jwt-decode.esm.js",
...
}
references

npm install --legacy-peer-deps
npm install --save jwt-decode
npm install --save #types/jwt-decode
This solves mine problem
reference

Related

Can't generate Nuxt website with #googlemaps/js-api-loader

I am using #googlemaps/js-api-loader in my Nuxt 3 website. Everything works fine in local development, but when I try to build the project with nuxt generate (no matter if locally or on Vercel) I'm getting following error:
[nuxt] [request error] Named export 'Loader' not found. The requested module 'file:///path/to/website/node_modules/#googlemaps/js-api-loader/dist/index.umd.js' is a CommonJS module, which may not support all module.exports as named exports. CommonJS modules can always be imported via the default export, for example using:
The important part of loading script looks like this:
import { Loader } from '#googlemaps/js-api-loader';
const loader = new Loader({
apiKey: config.googleMapsApiKey,
version: 'weekly',
});
onMounted(async() => {
await loader
.load()
...
so I tried to import this package differently, e.g.:
import * as gmaps from '#googlemaps/js-api-loader';
const { Loader } = gmaps;
and the previous error disappeared, but now I'm getting
[Vue warn]: Unhandled error during execution of setup function
at <DynamicLocations class="contact__map" locations= [
{
id: 1,
...
[nuxt] [request error] gmaps.Loader is not a constructor
at setup (./.nuxt/prerender/chunks/app/server.mjs:5536:20)
at _sfc_main$t.setup (./.nuxt/prerender/chunks/app/server.mjs:5582:25)
at callWithErrorHandling (./.nuxt/prerender/chunks/renderer.mjs:2654:23)
at setupStatefulComponent (./.nuxt/prerender/chunks/renderer.mjs:9548:30)
at setupComponent (./.nuxt/prerender/chunks/renderer.mjs:9503:12)
at renderComponentVNode (./.nuxt/prerender/chunks/renderer.mjs:12068:17)
at Object.ssrRenderComponent (./.nuxt/prerender/chunks/renderer.mjs:12504:12)
at ./.nuxt/prerender/chunks/app/server.mjs:5628:36
at renderComponentSubTree (./.nuxt/prerender/chunks/renderer.mjs:12149:13)
at renderComponentVNode (./.nuxt/prerender/chunks/renderer.mjs:12084:16)
I also can't import package by default export. Do you have any ideas what's going on and how can I fix this?
I found a documentation page related to this problem and there is the following information:
If you encounter these errors, the issue is almost certainly with the upstream library. They need to fix their library to support being imported by Node.
Although they provide a solution to get rid of errors by adding the package to build.transpile:
build: {
transpile: ['#googlemaps/js-api-loader'],
},
It worked for me

Apollo Client "Named export 'remove' not found"

I'm attempting to create an apollo client plugin for a Nuxt 3 application. It's currently throwing an error regarding a package called ts-invariant:
file:///Users/[my name]/Repositories/[project]/node_modules/#apollo/client/utilities/globals/fix-graphql.js:1
import { remove } from "ts-invariant/process/index.js";
^^^^^^
SyntaxError: Named export 'remove' not found. The requested module 'ts-invariant/process/index.js' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:
import pkg from 'ts-invariant/process/index.js';
const { remove } = pkg;
at ModuleJob._instantiate (node:internal/modules/esm/module_job:124:21)
at async ModuleJob.run (node:internal/modules/esm/module_job:181:5)
at async Promise.all (index 0)
at async ESMLoader.import (node:internal/modules/esm/loader:281:24)
at async __instantiateModule__ (file:///Users/[my name]/Repositories/[project]/.nuxt/dist/server/server.mjs:4550:3)
[vite dev] Error loading external "/Users/[my name]/Repositories/[project]/node_modules/#apollo/client/core/index.js".
at file://./.nuxt/dist/server/server.mjs:3170:289
at async __instantiateModule__ (file://./.nuxt/dist/server/server.mjs:4550:3)
I feel like I know enough about this error to know it has something to do with how Nuxt 3 deals with ESM, but I can't be for certain.
Here's the nuxt plugin:
plugins/apollo-client.js
import { defineNuxtPlugin } from "#app"
import { ApolloClient, InMemoryCache } from "#apollo/client/core"
import { DefaultApolloClient } from "#vue/apollo-composable"
export default defineNuxtPlugin((nuxtApp) => {
const config = useRuntimeConfig()
const apolloClient = new ApolloClient({
uri: config.PUBLIC_API_ENDPOINT,
cache: new InMemoryCache(),
})
nuxtApp.vueApp.provide(DefaultApolloClient, apolloClient)
})
In a normal scenario, I might use the nuxt-apollo community module, but it is currently afk regarding a nuxt 3 port, so a plugin it is.
Here's some documentation I relied on for my plugin:
https://v4.apollo.vuejs.org/guide-composable/setup.html#vue-3
https://v3.nuxtjs.org/docs/directory-structure/plugins
Solved by including #apollo/client and ts-invariant/process into the nuxt build transpile like so:
// nuxt.config.js
// ...
build: {
postcss: {
postcssOptions: require('./postcss.config.js')
},
transpile: [
'#apollo/client',
'ts-invariant/process',
],
},
// ...
I think I've pinpointed the underlying issue. Apollo Client (3.5.10 at the time of writing early 2022) is using "module":"index.js" to declare the path of the ESM exports.
However it seems that Webpack 5 based bundlers do not support this. Using exports in the package.json fixes it for good for me.
You should upvote this feature request.
And here is my palliative until then, using a small script to alter the package.json.

TypeScript/Knex: Cannot use import statement outside a module

I'm a newbie to TypeScript and currently using Knex to build a template table in our PostgreSQL database. On this file and others and am continually running in to this same issue with TypeScript, code is as follows:
import * as Knex from 'knex';
exports.up = async (knex: Knex): Promise<void> => {
await knex.schema.raw(`
CREATE TABLE test (
test TEXT NOT NULL,
tes2 INTEGER NOT NULL,
PRIMARY KEY (key, website)
)
`);
}
exports.down = async (knex: Knex): Promise<void> => {
await knex.schema.dropTable('test');
}
and I get this error:
import * as Knex from 'knex';
^^^^^^
SyntaxError: Cannot use import statement outside a module
I have also tried these varients:
import * as Knex = require('knex');
import { * as Knex } from 'knex';
const * = require('knex');
const { * as Knex } = require('knex');
But I cannot find any solution online which seems to solve the problem.
Any help on this would be awesome.
Tried alot of things and nothing helped, trying to change the type to module only made things worse.
After all what was missing was ts-node:
yarn add ts-node -D
And you're done =]
You're mixing two different kinds of modules. import/export is JavaScript standard module syntax ("ESM" for "ECMAScript Module"), but assigning to properties on exports is CommonJS module syntax (aka "CJS"). You need to use one or the other, and if you're using ESM, you need to tell Node.js that by using "type": "module" in package.json or using the .mjs file extension — or, since you're using TypeScript, you might want "module": "ES2020" or similar (more here).
The error tells us that Node.js and/or TypeScript think you're using CJS. If you want to keep doing that, it would probably be:
const Knex = require("knex");
...but see the documentation, as they show calling that export as a function. (Perhaps you're doing that later.)
This error can occur if you setup knex without specifying you'll be using typescript.
Make sure you use the following command to initialize knex, if you're creating typescript migrations:
knex init -x ts
At first make sure you've instantiate a typescript project so you may need to add typescript to your dependencies
yarn add -D typescript
Make sure to also have a tsconfig.json file
Add a knexfile.ts to your project root dir with this command
knex init -x ts

ES6 imports for JWT

I'm making a nodeJS web app and I'm using JWT for authentication. All my work is in ES6 modules and I wanted to import JWT in the same way, but apparently it isn't yet supported by the package. I can't use the older require() format as it throws an error since I've set it to modules in my package.json. Is there a way around this or do I have to find another library altogether?
Edit: I have fixed the issue with destructuring but it's still not working. Apparently it can't find the module at all. I made sure the package is in fact installed and updated, still not working
Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'jsonwebtoken' imported from /path/to/file.js
import jwt from ' jsonwebtoken'
const { sign } = jwt
class sampleClass {
static func(user) {
return sign(
{
_id: user._id,
name: user.name,
},
'sample key',
{
expiresIn: '7d',
},
)
}
}
Your gonna need to import it and then assign it like this
import jwt from 'jsonwebtoken';
const { sign, verify } = jwt;
const token = sign({"d":"dd"}, "secret", {expiresIn: 300})
console.log(token);
const verifycode = verify(token, "secret");
console.log(verifycode);
Could you try something:
Create a folder
Do npm init
Create a file app.js
install json web token npm i jsonwebtoken
Go to package.json and add "type": "module"
write in your app.js this here: import jwt from "jsonwebtoken"
Execute it: node --experimental-modules app.js
Tell me then if you get an error
If you are using jwt v8, just import the jsonwebtoken this way:
import * as jwt from 'jsonwebtoken'
or
import { sign, decode, verify } from 'jsonwebtoken'
You have an extra space in import jwt from ' jsonwebtoken'
Should just be import jwt from 'jsonwebtoken'
I just tested it and it works fine on my computer
I am using typescript to write my node server and jwt implementation.
This is the suggestion on my terminal:
Try npm i --save-dev #types/jsonwebtoken if it exists or add a new declaration (.d.ts) file containing `declare module 'jsonwebtoken';
I just typed: npm i --save-dev #types/jsonwebtoken
Then in my file I added imports: import jwt from "jsonwebtoken"
Hope that helps.

Import nodejs module with version number into typescript

So I have a node module which seems to use a versioning system. Using nodejs I simply used
const Package = require('package-name').V1;
which worked without issues. Typescript however does not like the .V1 so I use
import { Package } from 'package-name';
which complies fine but the typescript output to javascript is
const package_name_1 = require("package-name");
Which means that any function or properties of package_name_1 are undefined since the module doesn't seem to load V1.js file (i assume that is how it works..)
So I tried
import * as Package from 'package-name';
But it outputs the same javascript as before..
The actual folder structure of the package I am using is
-node_modules
--package-name
---client
----v1
----v1.js
with the v1.js file looking like
var PackageV1 = {}
PackageV1.CONSTANTS = require('./v1/constants');
PackageV1.Request = require('./v1/request');
PackageV1.Session = require('./v1/session');
...
module.exports = PackageV1;
Of course things like
const Package = require('package-name.V1');
do not work
Error: Cannot find module 'package-name.V1'
How can I require this V1.js file / directory using the typescript method?
As was hinted at in the comments
import * as Package from 'package-name';
is fine but when using the package I had to use
Package.V1.Request()
rather than
Package.Request()

Categories