rearrange stuff
This commit is contained in:
parent
9e68698ddc
commit
bb86a25ad4
225
package-lock.json
generated
225
package-lock.json
generated
@ -9,7 +9,7 @@
|
||||
"version": "0.0.1",
|
||||
"license": "UNLICENSED",
|
||||
"dependencies": {
|
||||
"@icynet/oauth2-provider": "git+ssh://git@gitlab.icynet.eu:IcyNetwork/oauth2-provider.git",
|
||||
"@icynet/oauth2-provider": "git+https://gitlab.icynet.eu/IcyNetwork/oauth2-provider.git",
|
||||
"@nestjs/common": "^9.0.11",
|
||||
"@nestjs/core": "^9.0.11",
|
||||
"@nestjs/platform-express": "^9.0.11",
|
||||
@ -34,7 +34,7 @@
|
||||
"otplib": "^12.0.1",
|
||||
"pug": "^3.0.2",
|
||||
"qrcode": "^1.5.1",
|
||||
"redis": "^3.1.2",
|
||||
"redis": "^4.3.0",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"rimraf": "^3.0.2",
|
||||
"rxjs": "^7.5.6",
|
||||
@ -2135,7 +2135,7 @@
|
||||
},
|
||||
"node_modules/@icynet/oauth2-provider": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "git+ssh://git@gitlab.icynet.eu:IcyNetwork/oauth2-provider.git#a440d1f4ac53ccb6989dd25221797490611e240a",
|
||||
"resolved": "git+https://gitlab.icynet.eu/IcyNetwork/oauth2-provider.git#a440d1f4ac53ccb6989dd25221797490611e240a",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"express": "^4.17.3",
|
||||
@ -3147,6 +3147,59 @@
|
||||
"@otplib/plugin-thirty-two": "^12.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@redis/bloom": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-1.0.2.tgz",
|
||||
"integrity": "sha512-EBw7Ag1hPgFzdznK2PBblc1kdlj5B5Cw3XwI9/oG7tSn85/HKy3X9xHy/8tm/eNXJYHLXHJL/pkwBpFMVVefkw==",
|
||||
"peerDependencies": {
|
||||
"@redis/client": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@redis/client": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@redis/client/-/client-1.3.0.tgz",
|
||||
"integrity": "sha512-XCFV60nloXAefDsPnYMjHGtvbtHR8fV5Om8cQ0JYqTNbWcQo/4AryzJ2luRj4blveWazRK/j40gES8M7Cp6cfQ==",
|
||||
"dependencies": {
|
||||
"cluster-key-slot": "1.1.0",
|
||||
"generic-pool": "3.8.2",
|
||||
"yallist": "4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/@redis/graph": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@redis/graph/-/graph-1.0.1.tgz",
|
||||
"integrity": "sha512-oDE4myMCJOCVKYMygEMWuriBgqlS5FqdWerikMoJxzmmTUErnTRRgmIDa2VcgytACZMFqpAOWDzops4DOlnkfQ==",
|
||||
"peerDependencies": {
|
||||
"@redis/client": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@redis/json": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@redis/json/-/json-1.0.3.tgz",
|
||||
"integrity": "sha512-4X0Qv0BzD9Zlb0edkUoau5c1bInWSICqXAGrpwEltkncUwcxJIGEcVryZhLgb0p/3PkKaLIWkjhHRtLe9yiA7Q==",
|
||||
"peerDependencies": {
|
||||
"@redis/client": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@redis/search": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@redis/search/-/search-1.1.0.tgz",
|
||||
"integrity": "sha512-NyFZEVnxIJEybpy+YskjgOJRNsfTYqaPbK/Buv6W2kmFNaRk85JiqjJZA5QkRmWvGbyQYwoO5QfDi2wHskKrQQ==",
|
||||
"peerDependencies": {
|
||||
"@redis/client": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@redis/time-series": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.0.3.tgz",
|
||||
"integrity": "sha512-OFp0q4SGrTH0Mruf6oFsHGea58u8vS/iI5+NpYdicaM+7BgqBZH8FFvNZ8rYYLrUO/QRqMq72NpXmxLVNcdmjA==",
|
||||
"peerDependencies": {
|
||||
"@redis/client": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@sinclair/typebox": {
|
||||
"version": "0.24.28",
|
||||
"resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.28.tgz",
|
||||
@ -4997,6 +5050,14 @@
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/cluster-key-slot": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.0.tgz",
|
||||
"integrity": "sha512-2Nii8p3RwAPiFwsnZvukotvow2rIHM+yQ6ZcBXGHdniadkYGZYiGmkHJIbZPIV9nfv7m/U1IPMVVcAhoWFeklw==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/co": {
|
||||
"version": "4.6.0",
|
||||
"resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
|
||||
@ -6713,6 +6774,14 @@
|
||||
"is-property": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/generic-pool": {
|
||||
"version": "3.8.2",
|
||||
"resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-3.8.2.tgz",
|
||||
"integrity": "sha512-nGToKy6p3PAbYQ7p1UlWl6vSPwfwU6TMSWK7TTu+WUY4ZjyZQGniGGt2oNVvyNSpyZYSB43zMXVLcBm08MTMkg==",
|
||||
"engines": {
|
||||
"node": ">= 4"
|
||||
}
|
||||
},
|
||||
"node_modules/gensync": {
|
||||
"version": "1.0.0-beta.2",
|
||||
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
|
||||
@ -10122,53 +10191,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/redis": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/redis/-/redis-3.1.2.tgz",
|
||||
"integrity": "sha512-grn5KoZLr/qrRQVwoSkmzdbw6pwF+/rwODtrOr6vuBRiR/f3rjSTGupbF90Zpqm2oenix8Do6RV7pYEkGwlKkw==",
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/redis/-/redis-4.3.0.tgz",
|
||||
"integrity": "sha512-RXRUor0iU1vizu4viHoUyLpe1ZO/RngZp0V9DyXBHTI+7tC7rEz6Wzn4Sv9v0tTJeqGAzdJ+q5YVbNKKQ5hX9A==",
|
||||
"dependencies": {
|
||||
"denque": "^1.5.0",
|
||||
"redis-commands": "^1.7.0",
|
||||
"redis-errors": "^1.2.0",
|
||||
"redis-parser": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/node-redis"
|
||||
}
|
||||
},
|
||||
"node_modules/redis-commands": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.7.0.tgz",
|
||||
"integrity": "sha512-nJWqw3bTFy21hX/CPKHth6sfhZbdiHP6bTawSgQBlKOVRG7EZkfHbbHwQJnrE4vsQf0CMNE+3gJ4Fmm16vdVlQ=="
|
||||
},
|
||||
"node_modules/redis-errors": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz",
|
||||
"integrity": "sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==",
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/redis-parser": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz",
|
||||
"integrity": "sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==",
|
||||
"dependencies": {
|
||||
"redis-errors": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/redis/node_modules/denque": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/denque/-/denque-1.5.1.tgz",
|
||||
"integrity": "sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw==",
|
||||
"engines": {
|
||||
"node": ">=0.10"
|
||||
"@redis/bloom": "1.0.2",
|
||||
"@redis/client": "1.3.0",
|
||||
"@redis/graph": "1.0.1",
|
||||
"@redis/json": "1.0.3",
|
||||
"@redis/search": "1.1.0",
|
||||
"@redis/time-series": "1.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/reflect-metadata": {
|
||||
@ -13918,8 +13950,8 @@
|
||||
"dev": true
|
||||
},
|
||||
"@icynet/oauth2-provider": {
|
||||
"version": "git+ssh://git@gitlab.icynet.eu:IcyNetwork/oauth2-provider.git#a440d1f4ac53ccb6989dd25221797490611e240a",
|
||||
"from": "@icynet/oauth2-provider@git+ssh://git@gitlab.icynet.eu:IcyNetwork/oauth2-provider.git",
|
||||
"version": "git+https://gitlab.icynet.eu/IcyNetwork/oauth2-provider.git#a440d1f4ac53ccb6989dd25221797490611e240a",
|
||||
"from": "@icynet/oauth2-provider@git+https://gitlab.icynet.eu/IcyNetwork/oauth2-provider.git",
|
||||
"requires": {
|
||||
"express": "^4.17.3",
|
||||
"express-session": "^1.17.2"
|
||||
@ -14682,6 +14714,46 @@
|
||||
"@otplib/plugin-thirty-two": "^12.0.1"
|
||||
}
|
||||
},
|
||||
"@redis/bloom": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-1.0.2.tgz",
|
||||
"integrity": "sha512-EBw7Ag1hPgFzdznK2PBblc1kdlj5B5Cw3XwI9/oG7tSn85/HKy3X9xHy/8tm/eNXJYHLXHJL/pkwBpFMVVefkw==",
|
||||
"requires": {}
|
||||
},
|
||||
"@redis/client": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@redis/client/-/client-1.3.0.tgz",
|
||||
"integrity": "sha512-XCFV60nloXAefDsPnYMjHGtvbtHR8fV5Om8cQ0JYqTNbWcQo/4AryzJ2luRj4blveWazRK/j40gES8M7Cp6cfQ==",
|
||||
"requires": {
|
||||
"cluster-key-slot": "1.1.0",
|
||||
"generic-pool": "3.8.2",
|
||||
"yallist": "4.0.0"
|
||||
}
|
||||
},
|
||||
"@redis/graph": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@redis/graph/-/graph-1.0.1.tgz",
|
||||
"integrity": "sha512-oDE4myMCJOCVKYMygEMWuriBgqlS5FqdWerikMoJxzmmTUErnTRRgmIDa2VcgytACZMFqpAOWDzops4DOlnkfQ==",
|
||||
"requires": {}
|
||||
},
|
||||
"@redis/json": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@redis/json/-/json-1.0.3.tgz",
|
||||
"integrity": "sha512-4X0Qv0BzD9Zlb0edkUoau5c1bInWSICqXAGrpwEltkncUwcxJIGEcVryZhLgb0p/3PkKaLIWkjhHRtLe9yiA7Q==",
|
||||
"requires": {}
|
||||
},
|
||||
"@redis/search": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@redis/search/-/search-1.1.0.tgz",
|
||||
"integrity": "sha512-NyFZEVnxIJEybpy+YskjgOJRNsfTYqaPbK/Buv6W2kmFNaRk85JiqjJZA5QkRmWvGbyQYwoO5QfDi2wHskKrQQ==",
|
||||
"requires": {}
|
||||
},
|
||||
"@redis/time-series": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.0.3.tgz",
|
||||
"integrity": "sha512-OFp0q4SGrTH0Mruf6oFsHGea58u8vS/iI5+NpYdicaM+7BgqBZH8FFvNZ8rYYLrUO/QRqMq72NpXmxLVNcdmjA==",
|
||||
"requires": {}
|
||||
},
|
||||
"@sinclair/typebox": {
|
||||
"version": "0.24.28",
|
||||
"resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.28.tgz",
|
||||
@ -16157,6 +16229,11 @@
|
||||
"shallow-clone": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"cluster-key-slot": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.0.tgz",
|
||||
"integrity": "sha512-2Nii8p3RwAPiFwsnZvukotvow2rIHM+yQ6ZcBXGHdniadkYGZYiGmkHJIbZPIV9nfv7m/U1IPMVVcAhoWFeklw=="
|
||||
},
|
||||
"co": {
|
||||
"version": "4.6.0",
|
||||
"resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
|
||||
@ -17475,6 +17552,11 @@
|
||||
"is-property": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"generic-pool": {
|
||||
"version": "3.8.2",
|
||||
"resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-3.8.2.tgz",
|
||||
"integrity": "sha512-nGToKy6p3PAbYQ7p1UlWl6vSPwfwU6TMSWK7TTu+WUY4ZjyZQGniGGt2oNVvyNSpyZYSB43zMXVLcBm08MTMkg=="
|
||||
},
|
||||
"gensync": {
|
||||
"version": "1.0.0-beta.2",
|
||||
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
|
||||
@ -20051,39 +20133,16 @@
|
||||
}
|
||||
},
|
||||
"redis": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/redis/-/redis-3.1.2.tgz",
|
||||
"integrity": "sha512-grn5KoZLr/qrRQVwoSkmzdbw6pwF+/rwODtrOr6vuBRiR/f3rjSTGupbF90Zpqm2oenix8Do6RV7pYEkGwlKkw==",
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/redis/-/redis-4.3.0.tgz",
|
||||
"integrity": "sha512-RXRUor0iU1vizu4viHoUyLpe1ZO/RngZp0V9DyXBHTI+7tC7rEz6Wzn4Sv9v0tTJeqGAzdJ+q5YVbNKKQ5hX9A==",
|
||||
"requires": {
|
||||
"denque": "^1.5.0",
|
||||
"redis-commands": "^1.7.0",
|
||||
"redis-errors": "^1.2.0",
|
||||
"redis-parser": "^3.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"denque": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/denque/-/denque-1.5.1.tgz",
|
||||
"integrity": "sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"redis-commands": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.7.0.tgz",
|
||||
"integrity": "sha512-nJWqw3bTFy21hX/CPKHth6sfhZbdiHP6bTawSgQBlKOVRG7EZkfHbbHwQJnrE4vsQf0CMNE+3gJ4Fmm16vdVlQ=="
|
||||
},
|
||||
"redis-errors": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz",
|
||||
"integrity": "sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w=="
|
||||
},
|
||||
"redis-parser": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz",
|
||||
"integrity": "sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==",
|
||||
"requires": {
|
||||
"redis-errors": "^1.0.0"
|
||||
"@redis/bloom": "1.0.2",
|
||||
"@redis/client": "1.3.0",
|
||||
"@redis/graph": "1.0.1",
|
||||
"@redis/json": "1.0.3",
|
||||
"@redis/search": "1.1.0",
|
||||
"@redis/time-series": "1.0.3"
|
||||
}
|
||||
},
|
||||
"reflect-metadata": {
|
||||
|
@ -49,7 +49,7 @@
|
||||
"otplib": "^12.0.1",
|
||||
"pug": "^3.0.2",
|
||||
"qrcode": "^1.5.1",
|
||||
"redis": "^3.1.2",
|
||||
"redis": "^4.3.0",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"rimraf": "^3.0.2",
|
||||
"rxjs": "^7.5.6",
|
||||
|
@ -1,30 +1,15 @@
|
||||
import {
|
||||
MiddlewareConsumer,
|
||||
Module,
|
||||
NestModule,
|
||||
RequestMethod,
|
||||
} from '@nestjs/common';
|
||||
import { Module } from '@nestjs/common';
|
||||
import { ServeStaticModule } from '@nestjs/serve-static';
|
||||
import { ThrottlerModule } from '@nestjs/throttler';
|
||||
import { join } from 'path';
|
||||
import { AppController } from './app.controller';
|
||||
import { AppService } from './app.service';
|
||||
import { CSRFMiddleware } from './middleware/csrf.middleware';
|
||||
import { UserMiddleware } from './middleware/user.middleware';
|
||||
import { ApiModule } from './modules/api/api.module';
|
||||
import { ConfigurationModule } from './modules/config/config.module';
|
||||
import { LoginModule } from './modules/features/login/login.module';
|
||||
import { OAuth2Module } from './modules/features/oauth2/oauth2.module';
|
||||
import { RegisterModule } from './modules/features/register/register.module';
|
||||
import { SettingsModule } from './modules/features/settings/settings.module';
|
||||
import { TwoFactorModule } from './modules/features/two-factor/two-factor.module';
|
||||
|
||||
import { JWTModule } from './modules/jwt/jwt.module';
|
||||
import { DatabaseModule } from './modules/objects/database/database.module';
|
||||
import { EmailModule } from './modules/objects/email/email.module';
|
||||
import { OAuth2ClientModule } from './modules/objects/oauth2-client/oauth2-client.module';
|
||||
import { OAuth2TokenModule } from './modules/objects/oauth2-token/oauth2-token.module';
|
||||
import { PrivilegeModule } from './modules/objects/privilege/privilege.module';
|
||||
import { UploadModule } from './modules/objects/upload/upload.module';
|
||||
import { UserModule } from './modules/objects/user/user.module';
|
||||
import { StaticFrontEndModule } from './modules/static-front-end/static-front-end.module';
|
||||
import { UtilityModule } from './modules/utility/utility.module';
|
||||
|
||||
@Module({
|
||||
@ -39,31 +24,11 @@ import { UtilityModule } from './modules/utility/utility.module';
|
||||
}),
|
||||
ConfigurationModule,
|
||||
UtilityModule,
|
||||
DatabaseModule,
|
||||
EmailModule,
|
||||
UserModule,
|
||||
UploadModule,
|
||||
OAuth2ClientModule,
|
||||
OAuth2TokenModule,
|
||||
LoginModule,
|
||||
RegisterModule,
|
||||
OAuth2Module,
|
||||
JWTModule,
|
||||
TwoFactorModule,
|
||||
SettingsModule,
|
||||
PrivilegeModule,
|
||||
StaticFrontEndModule,
|
||||
ApiModule,
|
||||
],
|
||||
controllers: [AppController],
|
||||
providers: [AppService, CSRFMiddleware],
|
||||
})
|
||||
export class AppModule implements NestModule {
|
||||
configure(consumer: MiddlewareConsumer) {
|
||||
consumer
|
||||
.apply(CSRFMiddleware, UserMiddleware)
|
||||
.exclude(
|
||||
{ path: 'uploads*', method: RequestMethod.ALL },
|
||||
{ path: 'public*', method: RequestMethod.ALL },
|
||||
)
|
||||
.forRoutes('*');
|
||||
}
|
||||
}
|
||||
export class AppModule {}
|
||||
|
13
src/decorators/bearer.decorator.ts
Normal file
13
src/decorators/bearer.decorator.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import { OAuth2AccessToken } from '@icynet/oauth2-provider';
|
||||
import { createParamDecorator, ExecutionContext } from '@nestjs/common';
|
||||
|
||||
/**
|
||||
* Get the OAuth2 bearer token from the response.
|
||||
* Requires the OAuth2 guard or bearer middleware!
|
||||
*/
|
||||
export const Bearer = createParamDecorator(
|
||||
(data: unknown, ctx: ExecutionContext) => {
|
||||
const response = ctx.switchToHttp().getResponse();
|
||||
return response.locals.accessToken as OAuth2AccessToken;
|
||||
},
|
||||
);
|
8
src/decorators/privileges.decorator.ts
Normal file
8
src/decorators/privileges.decorator.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import { SetMetadata } from '@nestjs/common';
|
||||
|
||||
/**
|
||||
* Restrict this route to only these privileges. AND logic!
|
||||
* @param privileges List of privileges for this route
|
||||
*/
|
||||
export const Privileges = (...privileges: string[]) =>
|
||||
SetMetadata('privileges', privileges);
|
14
src/decorators/scope.decorator.ts
Normal file
14
src/decorators/scope.decorator.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { OAuth2AccessToken } from '@icynet/oauth2-provider';
|
||||
import { createParamDecorator, ExecutionContext } from '@nestjs/common';
|
||||
|
||||
/**
|
||||
* Get the OAuth2 access token scope from the response.
|
||||
* Requires the OAuth2 guard or bearer middleware!
|
||||
*/
|
||||
export const Scope = createParamDecorator(
|
||||
(data: unknown, ctx: ExecutionContext) => {
|
||||
const response = ctx.switchToHttp().getResponse();
|
||||
const token = response.locals.accessToken as OAuth2AccessToken;
|
||||
return token.scope;
|
||||
},
|
||||
);
|
7
src/decorators/scopes.decorator.ts
Normal file
7
src/decorators/scopes.decorator.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import { SetMetadata } from '@nestjs/common';
|
||||
|
||||
/**
|
||||
* Restrict this route to only these OAuth2 scopes. AND logic!
|
||||
* @param scopes List of scopes for this route
|
||||
*/
|
||||
export const Scopes = (...scopes: string[]) => SetMetadata('scopes', scopes);
|
11
src/decorators/user.decorator.ts
Normal file
11
src/decorators/user.decorator.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { createParamDecorator, ExecutionContext } from '@nestjs/common';
|
||||
|
||||
/**
|
||||
* Get the User from the current request. Requires a guard or middleware to inject the user.
|
||||
*/
|
||||
export const CurrentUser = createParamDecorator(
|
||||
(data: unknown, ctx: ExecutionContext) => {
|
||||
const request = ctx.switchToHttp().getRequest();
|
||||
return request.user;
|
||||
},
|
||||
);
|
43
src/guards/oauth2.guard.ts
Normal file
43
src/guards/oauth2.guard.ts
Normal file
@ -0,0 +1,43 @@
|
||||
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
|
||||
import { Observable } from 'rxjs';
|
||||
import { OAuth2Service } from 'src/modules/oauth2/oauth2.service';
|
||||
import { UserService } from 'src/modules/objects/user/user.service';
|
||||
|
||||
/**
|
||||
* Injects and validates OAuth2 bearer tokens.
|
||||
*/
|
||||
@Injectable()
|
||||
export class OAuth2Guard implements CanActivate {
|
||||
constructor(private _oauth2: OAuth2Service, private _user: UserService) {}
|
||||
|
||||
canActivate(
|
||||
context: ExecutionContext,
|
||||
): boolean | Promise<boolean> | Observable<boolean> {
|
||||
const http = context.switchToHttp();
|
||||
const request = http.getRequest();
|
||||
const response = http.getResponse();
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
this._oauth2.oauth.bearer(request, response, (content) => {
|
||||
if (content instanceof Error) {
|
||||
return reject(content);
|
||||
}
|
||||
|
||||
this._user
|
||||
.getById(response.locals.accessToken.user_id, [
|
||||
'picture',
|
||||
'privileges',
|
||||
])
|
||||
.then((user) => {
|
||||
request.user = user;
|
||||
resolve(true);
|
||||
})
|
||||
.catch(reject);
|
||||
});
|
||||
} catch (e: any) {
|
||||
reject(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
28
src/guards/privileges.guard.ts
Normal file
28
src/guards/privileges.guard.ts
Normal file
@ -0,0 +1,28 @@
|
||||
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
|
||||
import { Reflector } from '@nestjs/core';
|
||||
|
||||
/**
|
||||
* Validates privileges.
|
||||
*/
|
||||
@Injectable()
|
||||
export class PrivilegesGuard implements CanActivate {
|
||||
constructor(private reflector: Reflector) {}
|
||||
|
||||
canActivate(context: ExecutionContext): boolean {
|
||||
const privileges = this.reflector.get<string[]>(
|
||||
'privileges',
|
||||
context.getHandler(),
|
||||
);
|
||||
if (!privileges) {
|
||||
return true;
|
||||
}
|
||||
const request = context.switchToHttp().getRequest();
|
||||
const user = request.user;
|
||||
return (
|
||||
user.privileges.includes('*') ||
|
||||
privileges.every((item) =>
|
||||
user.privileges.find(({ name }) => name === item),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
26
src/guards/scopes.guard.ts
Normal file
26
src/guards/scopes.guard.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import { OAuth2AccessToken } from '@icynet/oauth2-provider';
|
||||
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
|
||||
import { Reflector } from '@nestjs/core';
|
||||
|
||||
/**
|
||||
* Validates OAuth2 scopes.
|
||||
*/
|
||||
@Injectable()
|
||||
export class ScopesGuard implements CanActivate {
|
||||
constructor(private reflector: Reflector) {}
|
||||
|
||||
canActivate(context: ExecutionContext): boolean {
|
||||
const scopes = this.reflector.get<string[]>('scopes', context.getHandler());
|
||||
if (!scopes) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const response = context.switchToHttp().getResponse();
|
||||
const accessToken = response.locals.accessToken as OAuth2AccessToken;
|
||||
if (!accessToken) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return scopes.every((scope) => accessToken.scope.includes(scope));
|
||||
}
|
||||
}
|
@ -15,9 +15,10 @@ async function bootstrap() {
|
||||
|
||||
const RedisStore = connectRedis(session);
|
||||
const redisClient = redis.createClient({
|
||||
host: 'localhost',
|
||||
port: 6379,
|
||||
url: process.env.REDIS_URL || 'redis://localhost:6379',
|
||||
legacyMode: true,
|
||||
});
|
||||
redisClient.connect();
|
||||
|
||||
// app.use(express.urlencoded());
|
||||
app.use(cookieParser());
|
||||
|
4
src/modules/api/admin/admin.module.ts
Normal file
4
src/modules/api/admin/admin.module.ts
Normal file
@ -0,0 +1,4 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
|
||||
@Module({})
|
||||
export class AdminApiModule {}
|
15
src/modules/api/api.controller.ts
Normal file
15
src/modules/api/api.controller.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { Controller, Get, UseGuards } from '@nestjs/common';
|
||||
import { CurrentUser } from 'src/decorators/user.decorator';
|
||||
import { OAuth2Guard } from 'src/guards/oauth2.guard';
|
||||
import { User } from '../objects/user/user.entity';
|
||||
|
||||
@Controller({
|
||||
path: '/api',
|
||||
})
|
||||
export class ApiController {
|
||||
@Get('/')
|
||||
@UseGuards(OAuth2Guard)
|
||||
index(@CurrentUser() user: User) {
|
||||
return { hello: true, user: user.username };
|
||||
}
|
||||
}
|
26
src/modules/api/api.module.ts
Normal file
26
src/modules/api/api.module.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
|
||||
import { ConfigurationModule } from '../config/config.module';
|
||||
import { JWTModule } from '../jwt/jwt.module';
|
||||
import { OAuth2Module } from '../oauth2/oauth2.module';
|
||||
import { OAuth2Service } from '../oauth2/oauth2.service';
|
||||
import { ObjectsModule } from '../objects/objects.module';
|
||||
import { AdminApiModule } from './admin/admin.module';
|
||||
import { ApiController } from './api.controller';
|
||||
|
||||
@Module({
|
||||
controllers: [ApiController],
|
||||
imports: [
|
||||
ConfigurationModule,
|
||||
JWTModule,
|
||||
ObjectsModule,
|
||||
AdminApiModule,
|
||||
OAuth2Module,
|
||||
],
|
||||
})
|
||||
export class ApiModule implements NestModule {
|
||||
constructor(private _service: OAuth2Service) {}
|
||||
|
||||
configure(consumer: MiddlewareConsumer) {
|
||||
consumer.apply(this._service.oauth.express()).forRoutes('/api*');
|
||||
}
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
|
||||
import { AuthMiddleware } from 'src/middleware/auth.middleware';
|
||||
import { ValidateCSRFMiddleware } from 'src/middleware/validate-csrf.middleware';
|
||||
import { OAuth2ClientModule } from 'src/modules/objects/oauth2-client/oauth2-client.module';
|
||||
import { OAuth2TokenModule } from 'src/modules/objects/oauth2-token/oauth2-token.module';
|
||||
import { UploadModule } from 'src/modules/objects/upload/upload.module';
|
||||
import { UserModule } from 'src/modules/objects/user/user.module';
|
||||
import { OAuth2Controller } from './oauth2.controller';
|
||||
import { OAuth2Service } from './oauth2.service';
|
||||
|
||||
@Module({
|
||||
imports: [UserModule, UploadModule, OAuth2ClientModule, OAuth2TokenModule],
|
||||
controllers: [OAuth2Controller],
|
||||
providers: [OAuth2Service],
|
||||
exports: [OAuth2Service],
|
||||
})
|
||||
export class OAuth2Module implements NestModule {
|
||||
constructor(private _service: OAuth2Service) {}
|
||||
|
||||
configure(consumer: MiddlewareConsumer) {
|
||||
consumer.apply(this._service.oauth.express()).forRoutes('oauth2/*');
|
||||
consumer.apply(this._service.oauth.bearer).forRoutes('oauth2/user');
|
||||
consumer
|
||||
.apply(AuthMiddleware, ValidateCSRFMiddleware)
|
||||
.forRoutes('oauth2/authorize');
|
||||
}
|
||||
}
|
13
src/modules/oauth2/oauth2.module.ts
Normal file
13
src/modules/oauth2/oauth2.module.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { OAuth2ClientModule } from 'src/modules/objects/oauth2-client/oauth2-client.module';
|
||||
import { OAuth2TokenModule } from 'src/modules/objects/oauth2-token/oauth2-token.module';
|
||||
import { UploadModule } from 'src/modules/objects/upload/upload.module';
|
||||
import { UserModule } from 'src/modules/objects/user/user.module';
|
||||
import { OAuth2Service } from './oauth2.service';
|
||||
|
||||
@Module({
|
||||
imports: [UserModule, UploadModule, OAuth2ClientModule, OAuth2TokenModule],
|
||||
providers: [OAuth2Service],
|
||||
exports: [OAuth2Service],
|
||||
})
|
||||
export class OAuth2Module {}
|
@ -1,5 +1,5 @@
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { DeleteResult, Repository } from 'typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
import { User } from '../user/user.entity';
|
||||
import { OAuth2ClientAuthorization } from './oauth2-client-authorization.entity';
|
||||
import {
|
||||
@ -56,8 +56,8 @@ export class OAuth2ClientService {
|
||||
): Promise<OAuth2ClientAuthorization> {
|
||||
const existing = await this.clientAuthRepository.findOne({
|
||||
where: {
|
||||
user,
|
||||
client,
|
||||
user: { id: user.id },
|
||||
client: { id: client.id },
|
||||
},
|
||||
relations: ['user', 'client'],
|
||||
});
|
||||
@ -87,7 +87,7 @@ export class OAuth2ClientService {
|
||||
): Promise<OAuth2ClientAuthorization[]> {
|
||||
return this.clientAuthRepository.find({
|
||||
relations: ['user', 'client', 'client.urls'],
|
||||
where: { user },
|
||||
where: { user: { id: user.id } },
|
||||
});
|
||||
}
|
||||
|
||||
@ -104,7 +104,7 @@ export class OAuth2ClientService {
|
||||
): Promise<OAuth2ClientAuthorization> {
|
||||
return this.clientAuthRepository.findOne({
|
||||
where: {
|
||||
user,
|
||||
user: { id: user.id },
|
||||
id: authId,
|
||||
},
|
||||
relations: ['user'],
|
||||
|
36
src/modules/objects/objects.module.ts
Normal file
36
src/modules/objects/objects.module.ts
Normal file
@ -0,0 +1,36 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { ConfigurationModule } from '../config/config.module';
|
||||
|
||||
import { DatabaseModule } from './database/database.module';
|
||||
import { DocumentModule } from './document/document.module';
|
||||
import { EmailModule } from './email/email.module';
|
||||
import { OAuth2ClientModule } from './oauth2-client/oauth2-client.module';
|
||||
import { OAuth2TokenModule } from './oauth2-token/oauth2-token.module';
|
||||
import { PrivilegeModule } from './privilege/privilege.module';
|
||||
import { UploadModule } from './upload/upload.module';
|
||||
import { UserModule } from './user/user.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
ConfigurationModule,
|
||||
DatabaseModule,
|
||||
EmailModule,
|
||||
OAuth2ClientModule,
|
||||
OAuth2TokenModule,
|
||||
PrivilegeModule,
|
||||
UploadModule,
|
||||
UserModule,
|
||||
DocumentModule,
|
||||
],
|
||||
exports: [
|
||||
DatabaseModule,
|
||||
EmailModule,
|
||||
OAuth2ClientModule,
|
||||
OAuth2TokenModule,
|
||||
PrivilegeModule,
|
||||
UploadModule,
|
||||
UserModule,
|
||||
DocumentModule,
|
||||
],
|
||||
})
|
||||
export class ObjectsModule {}
|
@ -33,7 +33,7 @@ export class UserTOTPService {
|
||||
*/
|
||||
public async getUserTOTP(user: User): Promise<UserToken> {
|
||||
return this.userTokenRepository.findOne({
|
||||
where: { user, type: UserTokenType.TOTP },
|
||||
where: { user: { id: user.id }, type: UserTokenType.TOTP },
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -76,9 +76,11 @@ export class LoginController {
|
||||
|
||||
if (await this.totpService.userHasTOTP(user)) {
|
||||
const challenge = { type: 'verify', user: user.uuid, remember };
|
||||
req.session.challenge = await this.token.encryptChallenge(challenge);
|
||||
const encrypted = await this.token.encryptChallenge(challenge);
|
||||
res.redirect(
|
||||
'/login/verify' + (redirectTo ? '?redirectTo=' + redirectTo : ''),
|
||||
`login/verify?challenge=${encrypted}${
|
||||
redirectTo ? '&redirectTo=' + redirectTo : ''
|
||||
}`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
@ -96,18 +98,19 @@ export class LoginController {
|
||||
|
||||
@Get('verify')
|
||||
public verifyUserTokenView(
|
||||
@Session() session: SessionData,
|
||||
@Req() req: Request,
|
||||
@Res() res: Response,
|
||||
@Query('redirectTo') redirectTo?: string,
|
||||
@Query() query: { redirectTo: string; challenge: string },
|
||||
) {
|
||||
if (!session.challenge) {
|
||||
if (!query.challenge) {
|
||||
req.flash('message', {
|
||||
error: true,
|
||||
text: 'An unexpected error occured, please log in again.',
|
||||
});
|
||||
|
||||
res.redirect('/login' + (redirectTo ? '?redirectTo=' + redirectTo : ''));
|
||||
res.redirect(
|
||||
'/login' + (query.redirectTo ? '?redirectTo=' + query.redirectTo : ''),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -120,34 +123,36 @@ export class LoginController {
|
||||
@Body() body: { totp: string },
|
||||
@Req() req: Request,
|
||||
@Res() res: Response,
|
||||
@Query('redirectTo') redirectTo?: string,
|
||||
@Query() query: { redirectTo: string; challenge: string },
|
||||
) {
|
||||
let user: User;
|
||||
let remember = false;
|
||||
|
||||
try {
|
||||
if (!session.challenge) {
|
||||
if (!query.challenge) {
|
||||
throw new Error('No challenge');
|
||||
}
|
||||
|
||||
const challenge = await this.token.decryptChallenge(session.challenge);
|
||||
if (!challenge || challenge.type !== 'verify' || !challenge.user) {
|
||||
const decrypted = await this.token.decryptChallenge(query.challenge);
|
||||
if (!decrypted || decrypted.type !== 'verify' || !decrypted.user) {
|
||||
throw new Error('Bad challenge');
|
||||
}
|
||||
|
||||
user = await this.userService.getByUUID(challenge.user);
|
||||
user = await this.userService.getByUUID(decrypted.user);
|
||||
if (!user) {
|
||||
throw new Error('Bad challenge');
|
||||
}
|
||||
|
||||
remember = challenge.remember;
|
||||
remember = decrypted.remember;
|
||||
} catch (e: any) {
|
||||
req.flash('message', {
|
||||
error: true,
|
||||
text: 'An unexpected error occured, please log in again.',
|
||||
});
|
||||
|
||||
res.redirect('/login' + (redirectTo ? '?redirectTo=' + redirectTo : ''));
|
||||
res.redirect(
|
||||
'/login' + (query.redirectTo ? '?redirectTo=' + query.redirectTo : ''),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -172,9 +177,8 @@ export class LoginController {
|
||||
req.session.cookie.maxAge = month;
|
||||
}
|
||||
|
||||
session.challenge = null;
|
||||
session.user = user.uuid;
|
||||
res.redirect(redirectTo ? decodeURIComponent(redirectTo) : '/');
|
||||
res.redirect(query.redirectTo ? decodeURIComponent(query.redirectTo) : '/');
|
||||
}
|
||||
|
||||
@Get('activate')
|
||||
@ -231,7 +235,6 @@ export class LoginController {
|
||||
public async recoverView(
|
||||
@Req() req: Request,
|
||||
@Res() res: Response,
|
||||
@Session() session: SessionData,
|
||||
@Query() query: { token: string },
|
||||
) {
|
||||
if (query.token) {
|
@ -1,4 +1,3 @@
|
||||
import { OAuth2AccessToken } from '@icynet/oauth2-provider';
|
||||
import {
|
||||
Controller,
|
||||
Get,
|
||||
@ -7,10 +6,15 @@ import {
|
||||
Post,
|
||||
Req,
|
||||
Res,
|
||||
UseGuards,
|
||||
} from '@nestjs/common';
|
||||
import { NextFunction, Request, Response } from 'express';
|
||||
import { Scope } from 'src/decorators/scope.decorator';
|
||||
import { CurrentUser } from 'src/decorators/user.decorator';
|
||||
import { OAuth2Guard } from 'src/guards/oauth2.guard';
|
||||
import { ConfigurationService } from 'src/modules/config/config.service';
|
||||
import { OAuth2Service } from './oauth2.service';
|
||||
import { User } from 'src/modules/objects/user/user.entity';
|
||||
import { OAuth2Service } from '../../oauth2/oauth2.service';
|
||||
|
||||
@Controller('oauth2')
|
||||
export class OAuth2Controller {
|
||||
@ -61,15 +65,11 @@ export class OAuth2Controller {
|
||||
// TODO: Move to API
|
||||
|
||||
@Get('user')
|
||||
@UseGuards(OAuth2Guard)
|
||||
public async userInfo(
|
||||
@Res({ passthrough: true }) res: Response,
|
||||
@CurrentUser() user: User,
|
||||
@Scope() scope: string,
|
||||
): Promise<Record<string, any>> {
|
||||
const token = res.locals.accessToken as OAuth2AccessToken;
|
||||
const user = await this._service.userService.getById(
|
||||
token.user_id as number,
|
||||
['picture', 'privileges'],
|
||||
);
|
||||
|
||||
if (!user) {
|
||||
throw new NotFoundException('No such user');
|
||||
}
|
||||
@ -86,13 +86,13 @@ export class OAuth2Controller {
|
||||
nickname: user.display_name,
|
||||
};
|
||||
|
||||
if (token.scope.includes('email') || token.scope.includes('user:email')) {
|
||||
if (scope.includes('email') || scope.includes('user:email')) {
|
||||
userData.email = user.email;
|
||||
userData.email_verified = true;
|
||||
}
|
||||
|
||||
if (
|
||||
(token.scope.includes('image') || token.scope.includes('user:image')) &&
|
||||
(scope.includes('image') || scope.includes('user:image')) &&
|
||||
user.picture
|
||||
) {
|
||||
userData.image = `${this._config.get('app.base_url')}/uploads/${
|
||||
@ -102,10 +102,10 @@ export class OAuth2Controller {
|
||||
}
|
||||
|
||||
if (
|
||||
token.scope.includes('privileges') ||
|
||||
(token.scope.includes('user:privileges') && user.privileges?.length)
|
||||
scope.includes('privileges') ||
|
||||
(scope.includes('user:privileges') && user.privileges?.length)
|
||||
) {
|
||||
userData.privileges = user.privileges;
|
||||
userData.privileges = user.privileges.map(({ name }) => name);
|
||||
}
|
||||
|
||||
return userData;
|
@ -0,0 +1,22 @@
|
||||
import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
|
||||
import { AuthMiddleware } from 'src/middleware/auth.middleware';
|
||||
import { ValidateCSRFMiddleware } from 'src/middleware/validate-csrf.middleware';
|
||||
import { OAuth2Module } from 'src/modules/oauth2/oauth2.module';
|
||||
import { OAuth2Service } from 'src/modules/oauth2/oauth2.service';
|
||||
import { UserModule } from 'src/modules/objects/user/user.module';
|
||||
import { OAuth2Controller } from './oauth2-router.controller';
|
||||
|
||||
@Module({
|
||||
controllers: [OAuth2Controller],
|
||||
imports: [OAuth2Module, UserModule],
|
||||
})
|
||||
export class OAuth2RouterModule implements NestModule {
|
||||
constructor(private _service: OAuth2Service) {}
|
||||
|
||||
configure(consumer: MiddlewareConsumer) {
|
||||
consumer.apply(this._service.oauth.express()).forRoutes('oauth2/*');
|
||||
consumer
|
||||
.apply(AuthMiddleware, ValidateCSRFMiddleware)
|
||||
.forRoutes('oauth2/authorize');
|
||||
}
|
||||
}
|
@ -15,7 +15,7 @@ import { ConfigurationModule } from 'src/modules/config/config.module';
|
||||
import { ConfigurationService } from 'src/modules/config/config.service';
|
||||
import { UploadModule } from 'src/modules/objects/upload/upload.module';
|
||||
import { UserModule } from 'src/modules/objects/user/user.module';
|
||||
import { OAuth2Module } from '../oauth2/oauth2.module';
|
||||
import { OAuth2Module } from '../../oauth2/oauth2.module';
|
||||
import { SettingsController } from './settings.controller';
|
||||
import { SettingsService } from './settings.service';
|
||||
import { OAuth2ClientModule } from 'src/modules/objects/oauth2-client/oauth2-client.module';
|
@ -1,6 +1,6 @@
|
||||
import { ConfigurationService } from 'src/modules/config/config.service';
|
||||
import { UserService } from 'src/modules/objects/user/user.service';
|
||||
import { OAuth2Service } from '../oauth2/oauth2.service';
|
||||
import { OAuth2Service } from '../../oauth2/oauth2.service';
|
||||
|
||||
export class SettingsService {
|
||||
constructor(
|
46
src/modules/static-front-end/static-front-end.module.ts
Normal file
46
src/modules/static-front-end/static-front-end.module.ts
Normal file
@ -0,0 +1,46 @@
|
||||
import {
|
||||
MiddlewareConsumer,
|
||||
Module,
|
||||
NestModule,
|
||||
RequestMethod,
|
||||
} from '@nestjs/common';
|
||||
import { CSRFMiddleware } from 'src/middleware/csrf.middleware';
|
||||
import { UserMiddleware } from 'src/middleware/user.middleware';
|
||||
import { ConfigurationModule } from '../config/config.module';
|
||||
import { JWTModule } from '../jwt/jwt.module';
|
||||
import { ObjectsModule } from '../objects/objects.module';
|
||||
|
||||
import { LoginModule } from './login/login.module';
|
||||
import { OAuth2RouterModule } from './oauth2-router/oauth2-router.module';
|
||||
import { RegisterModule } from './register/register.module';
|
||||
import { SettingsModule } from './settings/settings.module';
|
||||
import { TwoFactorModule } from './two-factor/two-factor.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
ConfigurationModule,
|
||||
JWTModule,
|
||||
|
||||
ObjectsModule,
|
||||
|
||||
LoginModule,
|
||||
OAuth2RouterModule,
|
||||
RegisterModule,
|
||||
SettingsModule,
|
||||
TwoFactorModule,
|
||||
],
|
||||
providers: [],
|
||||
exports: [],
|
||||
})
|
||||
export class StaticFrontEndModule implements NestModule {
|
||||
configure(consumer: MiddlewareConsumer) {
|
||||
consumer
|
||||
.apply(CSRFMiddleware, UserMiddleware)
|
||||
.exclude(
|
||||
{ path: 'uploads*', method: RequestMethod.ALL },
|
||||
{ path: 'public*', method: RequestMethod.ALL },
|
||||
{ path: 'api*', method: RequestMethod.ALL },
|
||||
)
|
||||
.forRoutes('*');
|
||||
}
|
||||
}
|
@ -16,9 +16,9 @@ block body
|
||||
.alert.alert-success
|
||||
span #{message.text}
|
||||
|
||||
form(method="post")
|
||||
form(method="post", autocomplete="off")
|
||||
div.form-container
|
||||
input#csrf(type="hidden", name="_csrf", value=csrf)
|
||||
label.form-label(for="totp") Code
|
||||
input.form-control#totp(type="text", name="totp", autofocus, placeholder="xxxxxx")
|
||||
input.form-control#totp(type="text", autocomplete="off", name="totp", autofocus, placeholder="xxxxxx")
|
||||
button.btn.btn-primary(type="submit") Log in
|
||||
|
Reference in New Issue
Block a user