Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/vh13294/nestjs-url-generator
Dynamically generating & signing URL based on controller method reference.
https://github.com/vh13294/nestjs-url-generator
nestjs sign-urls typescript
Last synced: 2 months ago
JSON representation
Dynamically generating & signing URL based on controller method reference.
- Host: GitHub
- URL: https://github.com/vh13294/nestjs-url-generator
- Owner: vh13294
- License: mit
- Created: 2020-10-28T08:15:01.000Z (about 4 years ago)
- Default Branch: main
- Last Pushed: 2024-01-29T12:12:04.000Z (12 months ago)
- Last Synced: 2024-10-03T12:23:15.153Z (3 months ago)
- Topics: nestjs, sign-urls, typescript
- Language: TypeScript
- Homepage:
- Size: 489 KB
- Stars: 44
- Watchers: 1
- Forks: 16
- Open Issues: 4
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
NestJS module for generating & signing URL
# 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
```bash
npm i --save nestjs-url-generator
```Or if you use Yarn:
```bash
yarn add 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
```ts
import { UrlGeneratorModule } from '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
```.env
APP_KEY=secret
APP_URL=https://localhost:3000
```> signed-url.config.ts
```ts
import { UrlGeneratorModuleOptions } from 'nestjs-url-generator';export function urlGeneratorModuleConfig(): UrlGeneratorModuleOptions {
return {
secret: process.env.APP_KEY,
appUrl: process.env.APP_URL,
};
}
```> app.module.ts
```ts
import { UrlGeneratorModule } from '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:```typescript
generateUrlFromController({
controller,
controllerMethod,
/*?*/ query,
/*?*/ params,
});generateUrlFromPath({
relativePath,
/*?*/ query,
/*?*/ params,
});
```> app.controller.ts
```ts
import { UrlGeneratorService } from 'nestjs-url-generator';@Controller()
export class AppController {
constructor(private readonly urlGeneratorService: UrlGeneratorService) {}@Get('makeUrl')
async makeUrl(): Promise {
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:
```typescript
SignControllerUrl({
controller,
controllerMethod,
/*?*/ expirationDate,
/*?*/ query,
/*?*/ params,
});SignUrl({
relativePath,
/*?*/ expirationDate,
/*?*/ query,
/*?*/ params,
});
```> app.controller.ts
```ts
import { UrlGeneratorService } from 'nestjs-url-generator';@Controller()
export class AppController {
constructor(private readonly urlGeneratorService: UrlGeneratorService) {}@Get('makeSignUrl')
async makeSignUrl(): Promise {
// 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
```ts
import { SignedUrlGuard } from 'nestjs-url-generator';@Controller()
export class AppController {
constructor(private readonly urlGeneratorService: UrlGeneratorService) {}@Get('emailVerification')
@UseGuards(SignedUrlGuard)
async emailVerification(): Promise {
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
```typescript
const app = await NestFactory.create(AppModule);app.set('trust proxy', true);
// or
expressSession({ proxy: true });
```## Generating Keys using node REPL
```javascript
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