@tumainimosha/nestjs-url-generator
v1.0.5
Published
NestJs library for generating & signing url
Downloads
726
Maintainers
Readme
Description
URL Generation is used to dynamically generate URL that point to NestJS controller method (Route).
nestjs-url-generator can generate plain and signed URLs
Installation
npm i --save @tumainimosha/nestjs-url-generator
Or if you use Yarn:
yarn add @tumainimosha/nestjs-url-generator
Requirements
nestjs-url-generator
is built to work with Nest 7 and newer versions.
Basic Usage
Include Module
First you need to import [UrlGeneratorModule]:
app.module.ts
import { UrlGeneratorModule } from '@tumainimosha/nestjs-url-generator';
@Module({
imports: [
UrlGeneratorModule.forRoot({
secret: 'secret', // optional, required only for signed URL
appUrl: 'https://localhost:3000',
}),
],
})
export class ApplicationModule {}
Or Async Import With .ENV usage
.ENV
APP_KEY=secret
APP_URL=https://localhost:3000
signed-url.config.ts
import { UrlGeneratorModuleOptions } from '@tumainimosha/nestjs-url-generator';
export function urlGeneratorModuleConfig(): UrlGeneratorModuleOptions {
return {
secret: process.env.APP_KEY,
appUrl: process.env.APP_URL,
};
}
app.module.ts
import { UrlGeneratorModule } from '@tumainimosha/nestjs-url-generator';
@Module({
imports: [
ConfigModule.forRoot(),
UrlGeneratorModule.forRootAsync({
useFactory: () => urlGeneratorModuleConfig(),
}),
],
})
export class ApplicationModule {}
Using Service
Now you need to register the service, by injecting it to the constructor. There are two methods for generating url:
generateUrlFromController({
controller,
controllerMethod,
/*?*/ query,
/*?*/ params,
});
generateUrlFromPath({
relativePath,
/*?*/ query,
/*?*/ params,
});
app.controller.ts
import { UrlGeneratorService } from '@tumainimosha/nestjs-url-generator';
@Controller()
export class AppController {
constructor(private readonly urlGeneratorService: UrlGeneratorService) {}
@Get('makeUrl')
async makeUrl(): Promise<string> {
const params = {
version: '1.0',
userId: 12,
};
const query = {
email: 'email@email',
};
// This will generate:
// https://localhost:3000/emailVerification/1.0/12?email=email%40email
return this.urlGeneratorService.generateUrlFromController({
controller: AppController,
controllerMethod: AppController.prototype.emailVerification,
query: query,
params: params,
});
}
}
Generate Signed URL
There are two methods for generating url:
SignControllerUrl({
controller,
controllerMethod,
/*?*/ expirationDate,
/*?*/ query,
/*?*/ params,
});
SignUrl({
relativePath,
/*?*/ expirationDate,
/*?*/ query,
/*?*/ params,
});
app.controller.ts
import { UrlGeneratorService } from '@tumainimosha/nestjs-url-generator';
@Controller()
export class AppController {
constructor(private readonly urlGeneratorService: UrlGeneratorService) {}
@Get('makeSignUrl')
async makeSignUrl(): Promise<string> {
// This will generate:
// https://localhost:3000/emailVerification?
// expirationDate=2021-12-12T00%3A00%3A00.000Z&
// signed=84b5a021c433d0ee961932ac0ec04d5dd5ffd6f7fdb60b46083cfe474dfae3c0
return this.urlGeneratorService.SignControllerUrl({
controller: AppController,
controllerMethod: AppController.prototype.emailVerification,
expirationDate: new Date('2021-12-12'),
// or using DateTime library of your choice
// will be expired 30 minutes after it was created
expirationDate: dayjs().add(30, 'minute').toDate(),
});
}
}
[expirationDate] and [signed] query keys are used for signed URL.
By default, the signed URLs lives forever. You can add expiration date to them at the time of generating one.
Reminder
The difference between params & query in ExpressJS
Using Guard
You can use SignUrlGuard to verify the signed url in controller.
If the url has been tampered or when the expiration date is due, then a Forbidden exception will be thrown.
app.controller.ts
import { SignedUrlGuard } from '@tumainimosha/nestjs-url-generator';
@Controller()
export class AppController {
constructor(private readonly urlGeneratorService: UrlGeneratorService) {}
@Get('emailVerification')
@UseGuards(SignedUrlGuard)
async emailVerification(): Promise<string> {
return 'You emailed has been verified.';
}
}
Note
Changing the secret key will invalidate all signed urls
Signed URL is typically used for unsubscribe email, email verification, sign file permission, and more.
If you are using https with reverse proxy please make sure to enable trust proxy in express
const app = await NestFactory.create<NestExpressApplication>(AppModule);
app.set('trust proxy', true);
// or
expressSession({ proxy: true });
Generating Keys using node REPL
require('crypto').randomBytes(64, (err, buf) => {
if (err) throw err;
console.log(`${buf.length} bytes of random data: ${buf.toString('base64')}`);
process.exit();
});
TODO
[ ] Create unit test (expiration, tampered, with or without globalPrefix, request with or without query & param, if target for signerUrl doesn't have guard)
[ ] Automate CI, npm run build, push, npm publish