@solidxai/core 0.1.13-beta.19 → 0.1.13-beta.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +584 -0
- package/dist/constants/error-messages.d.ts +7 -0
- package/dist/constants/error-messages.d.ts.map +1 -1
- package/dist/constants/error-messages.js +7 -0
- package/dist/constants/error-messages.js.map +1 -1
- package/dist/constants/success-messages.d.ts +3 -0
- package/dist/constants/success-messages.d.ts.map +1 -1
- package/dist/constants/success-messages.js +3 -0
- package/dist/constants/success-messages.js.map +1 -1
- package/dist/controllers/mpin-authentication.controller.d.ts +44 -0
- package/dist/controllers/mpin-authentication.controller.d.ts.map +1 -0
- package/dist/controllers/mpin-authentication.controller.js +102 -0
- package/dist/controllers/mpin-authentication.controller.js.map +1 -0
- package/dist/dtos/change-mpin.dto.d.ts +6 -0
- package/dist/dtos/change-mpin.dto.d.ts.map +1 -0
- package/dist/dtos/change-mpin.dto.js +39 -0
- package/dist/dtos/change-mpin.dto.js.map +1 -0
- package/dist/dtos/mpin-login.dto.d.ts +5 -0
- package/dist/dtos/mpin-login.dto.d.ts.map +1 -0
- package/dist/dtos/mpin-login.dto.js +33 -0
- package/dist/dtos/mpin-login.dto.js.map +1 -0
- package/dist/dtos/setup-mpin.dto.d.ts +7 -0
- package/dist/dtos/setup-mpin.dto.d.ts.map +1 -0
- package/dist/dtos/setup-mpin.dto.js +47 -0
- package/dist/dtos/setup-mpin.dto.js.map +1 -0
- package/dist/entities/user-device-credential.entity.d.ts +18 -0
- package/dist/entities/user-device-credential.entity.d.ts.map +1 -0
- package/dist/entities/user-device-credential.entity.js +91 -0
- package/dist/entities/user-device-credential.entity.js.map +1 -0
- package/dist/helpers/solid-core-error-codes-provider.service.d.ts.map +1 -1
- package/dist/helpers/solid-core-error-codes-provider.service.js +45 -0
- package/dist/helpers/solid-core-error-codes-provider.service.js.map +1 -1
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/repository/user-device-credential.repository.d.ts +12 -0
- package/dist/repository/user-device-credential.repository.d.ts.map +1 -0
- package/dist/repository/user-device-credential.repository.js +34 -0
- package/dist/repository/user-device-credential.repository.js.map +1 -0
- package/dist/seeders/seed-data/solid-core-metadata.json +158 -0
- package/dist/services/mpin.service.d.ts +67 -0
- package/dist/services/mpin.service.d.ts.map +1 -0
- package/dist/services/mpin.service.js +282 -0
- package/dist/services/mpin.service.js.map +1 -0
- package/dist/services/settings/default-settings-provider.service.d.ts +120 -0
- package/dist/services/settings/default-settings-provider.service.d.ts.map +1 -1
- package/dist/services/settings/default-settings-provider.service.js +66 -0
- package/dist/services/settings/default-settings-provider.service.js.map +1 -1
- package/dist/solid-core.module.d.ts.map +1 -1
- package/dist/solid-core.module.js +8 -0
- package/dist/solid-core.module.js.map +1 -1
- package/package.json +1 -1
- package/postman/mpin.postman_collection.json +1045 -0
- package/src/constants/error-messages.ts +14 -0
- package/src/constants/success-messages.ts +5 -0
- package/src/controllers/mpin-authentication.controller.ts +67 -0
- package/src/dtos/change-mpin.dto.ts +18 -0
- package/src/dtos/mpin-login.dto.ts +24 -0
- package/src/dtos/setup-mpin.dto.ts +51 -0
- package/src/entities/user-device-credential.entity.ts +130 -0
- package/src/helpers/solid-core-error-codes-provider.service.ts +53 -0
- package/src/index.ts +6 -0
- package/src/repository/user-device-credential.repository.ts +17 -0
- package/src/seeders/seed-data/solid-core-metadata.json +158 -0
- package/src/services/mpin.service.ts +447 -0
- package/src/services/settings/default-settings-provider.service.ts +71 -0
- package/src/solid-core.module.ts +8 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error-messages.js","sourceRoot":"","sources":["../../src/constants/error-messages.ts"],"names":[],"mappings":"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","sourcesContent":["// backend/common/constants/error-messages.ts\n\nexport const ERROR_MESSAGES = {\n //authentication errors\n USER_NOT_FOUND: 'User does not exist.',\n USER_NOT_ACTIVE: 'User profile is not activated.',\n USER_INACTIVE: 'User is inactive.',\n ACCOUNT_BLOCKED: 'Your account has been blocked due to multiple failed login attempts.',\n PASSWORD_INCORRECT: 'Password does not match.',\n PUBLIC_REGISTRATION_DISABLED: 'Public registrations are disabled.',\n UNIQUE_CONSTRAINT_VIOLATION: 'A unique constraint violation occurred.',\n PASSWORDLESS_REGISTRATION_DISABLED: 'Passwordless registration is not enabled.',\n REGISTRATION_REQUIRES_CONTACT: 'Either mobile or email is required for initiating registration.',\n EMAIL_REQUIRED_FOR_VALIDATION: 'Email is required for email validation source.',\n MOBILE_REQUIRED_FOR_VALIDATION: 'Mobile is required for mobile validation source.',\n USER_ALREADY_EXISTS: 'User already exists. Please sign in.',\n VALIDATION_SOURCE_REQUIRED: 'At least one validation source is required.',\n INVALID_OTP: 'Invalid OTP.',\n OTP_EXPIRED: 'OTP has expired.',\n INVALID_VERIFICATION_TYPE: 'Invalid type. Must be either email or mobile.',\n NON_LOCAL_PROVIDER: 'User seems to have used a passwordless mode to authenticate.',\n USER_ID_MISMATCH: \"User ID's do not match.\",\n USERNAME_MISMATCH: \"User username's do not match.\",\n INCORRECT_CURRENT_PASSWORD: 'Incorrect current password specified.',\n PASSWORD_REUSED: 'Try a different password',\n INVALID_VERIFICATION_TOKEN: 'Invalid verification token',\n INVALID_REFRESH_TOKEN: 'Invalid refresh token',\n ACCESS_DENIED: 'Access denied',\n INVALID_USER_PROFILE: 'Invalid user profile',\n GOOGLE_OAUTH_PROFILE_FETCH_FAILED: 'Failed to fetch user profile from Google OAuth service',\n MICROSOFT_ACTIVE_DIRECTORY_OAUTH_PROFILE_FETCH_FAILED: 'Failed to fetch user profile from Microsoft Active Directory OAuth service',\n LOGOUT_FAILED: 'Logout failed due to an unexpected error.',\n\n INVALID_CREDENTIALS: 'Invalid credentials',\n LOGIN_FAILED: 'Login Failed',\n OLD_PASSWORD_INCORRECT: 'You have specified an incorrect old password.',\n INVALID_NEW_PASSWORD: 'Invalid new password.',\n PASSWORDS_DO_NOT_MATCH: 'New passwords are not matching.',\n\n // user management errors\n DELETE_SELF_NOT_ALLOWED: 'Deleting logged-in user is not allowed.',\n DELETE_IDS_REQUIRED: 'At least one ID is required for deletion.',\n USER_MISSING_ID: 'User must exist before initializing roles.',\n ROLES_NOT_FOUND: (roles: string[]) => `The following roles were not found: ${roles.join(', ')}`,\n USER_NOT_FOUND_BY_USERNAME: (username: string) => `User with username '${username}' not found.`,\n ROLE_NOT_FOUND: (roleName: string) => `Role '${roleName}' not found.`,\n PERMISSION_NOT_EXIST: (permission: string) => `Permission '${permission}' does not exist.`,\n\n // session errors\n SESSION_INVALID: 'Your session is no longer valid. Please log in again.',\n SESSION_EXPIRED: 'Your session has expired. Please log in again.',\n\n // filter errors\n GROUP_BY_LIMIT: 'buildFilterQuery: Only 1 Group by field is supported currently.',\n INVALID_GROUP_BY_COUNT: 'Exactly one groupBy field is required to count grouped records.',\n\n // general errors\n FORBIDDEN: 'Forbidden',\n RESOURCE_NOT_FOUND: 'The requested resource was not found.',\n\n\n // database errors\n DUPLICATE_ENTRY: 'Duplicate entry. A record with similar unique fields already exists.',\n\n // validation errors\n ID_REQUIRED_FOR_UPDATE: 'Id is required for update.',\n ID_REQUIRED_FOR_DELETE: 'Id is required for deletion.',\n\n // CRUD service errors\n RELATION_TYPE_NOT_SUPPORTED: 'Relation type not supported in CRUD service.',\n NO_SOFT_DELETED_RECORD_FOUND: 'No soft-deleted record found with the given ID.',\n CONFLICTING_RECORD_ON_UNARCHIVE: 'Another record is conflicting with the record you are attempting to Un-Archive, either delete or change the other record so as to avoid this conflict.',\n NO_SOFT_DELETED_RECORDS_FOUND: 'No matching soft-deleted records found.',\n EMPTY_PATH_PARTS: 'Path parts cannot be empty',\n\n\n // CSV/Excel service errors\n MISSING_HEADERS_OR_FUNCTION: 'Either headers or data records function must be provided.',\n INVALID_CHUNK_SIZE: 'Chunk size must be greater than 0 when data records function is provided.',\n INVALID_FORMAT: (format: string) => `Invalid ${format} format`,\n\n\n //field errors\n INVALID_INVERSE_FIELD_TYPE: 'Only relation fields can have inverse fields.',\n MODEL_AND_MODULE_REQUIRED_TO_UPDATE_INVERSE_FIELD: 'Model and module are required to update inverse field.',\n MODEL_NAME_AND_MODULE_NAME_REQUIRED_TO_CREATE_INVERSE_FIELD: 'Model name and module name are required to create inverse field.',\n FIELD_NOT_FOUND: (id: number | string) => `No field with id #${id} exists`,\n PROVIDER_NOT_FOUND: (provider: string) => `Field incorrectly configured. No provider with name ${provider} registered in backend.`,\n FILE_WRITE_FAILED: 'File creation failed, rolling back transaction',\n FILE_DELETE_FAILED: 'File deletion failed, rolling back transaction',\n // file service errors\n FILE_NOT_FOUND: 'File not found',\n FILE_COPY_ERROR: 'Error copying file',\n S3_CLIENT_NOT_INITIALIZED: 'S3 Client not initialized. Please check the S3 configuration.',\n\n // model errors\n MODEL_METADATA_NOT_FOUND: (id: string | number) => `Model metadata with ID ${id} not found.`,\n MODEL_SERVICE_NOT_FOUND: (model: string) => `Model service for ${model} not found.`,\n RELATION_CO_MODEL_NOT_DEFINED_FOR_FIELD: (fieldName: string) => `Relation coModelSingularName is not defined for relation field ${fieldName}`,\n MODEL_NOT_FOUND: (singularName?: string) => `Model${singularName ? ` with singular name \"${singularName}\"` : ''} not found.`,\n MODEL_REQUIRED_FOR_CODE_GENERATION: 'Model ID or Model Name is required for generating code.',\n\n //module errors\n MODULE_NOT_FOUND: (moduleName: string) => `Module with name ${moduleName} not found.`,\n MODULE_ID_NOT_FOUND: (id: string | number) => `Module with ID ${id} not found.`,\n\n //entity errors\n ENTITY_NOT_FOUND: (entity?: string | number) => `Entity${entity ? ' ' + entity : ''} not found.`,\n ENTITY_NAME_REQUIRED: 'Entity name is required to find the entity.',\n ENTITY_ID_REQUIRED: 'Entity ID is required to find the entity.',\n\n // import errors\n NO_ERROR_LOG_FOR_IMPORT: (id: string | number) => `No error log entries found for import transaction ID ${id}.`,\n FILE_READ_FAILED_FROM_URL: (url: string) => `Failed to read file from URL: ${url}`,\n\n // media storage provider errors\n MEDIA_STORAGE_PROVIDER_ID_NOT_FOUND: (id: number | string) => `Media Storage Provider with #${id} not found.`,\n MEDIA_STORAGE_PROVIDER_NOT_FOUND: 'Media Storage Provider not found',\n\n // SQL errors\n UNSUPPORTED_SQL_OPERATOR: (operator: string) => `Unsupported SQL operator: ${operator}`,\n\n // AI interaction errors\n PYTHON_EXECUTABLE_NOT_CONFIGURED: 'SolidX AI MCP python executable or client path not configured.',\n UNABLE_TO_RESOLVE_SOLID_COMMAND: 'Unable to resolve a solid_ command that was used to come up with this response.',\n UNABLE_TO_RESOLVE_MCP_HANDLER: 'Unable to resolve a mcp tool handler.',\n\n DEFAULT_REGEX_PATTERN_NOT_MATCHING_ERROR_MSG: 'Invalid regex pattern.',\n\n PERMISSION_MESSAGES: {\n insertMany: (model?: string) =>\n `You do not have permission to import ${model ?? 'these'} records.`,\n } as Record<string, (model?: string) => string>,\n\n};\n"]}
|
|
1
|
+
{"version":3,"file":"error-messages.js","sourceRoot":"","sources":["../../src/constants/error-messages.ts"],"names":[],"mappings":"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","sourcesContent":["// backend/common/constants/error-messages.ts\n\nexport const ERROR_MESSAGES = {\n //authentication errors\n USER_NOT_FOUND: 'User does not exist.',\n USER_NOT_ACTIVE: 'User profile is not activated.',\n USER_INACTIVE: 'User is inactive.',\n ACCOUNT_BLOCKED: 'Your account has been blocked due to multiple failed login attempts.',\n PASSWORD_INCORRECT: 'Password does not match.',\n PUBLIC_REGISTRATION_DISABLED: 'Public registrations are disabled.',\n UNIQUE_CONSTRAINT_VIOLATION: 'A unique constraint violation occurred.',\n PASSWORDLESS_REGISTRATION_DISABLED: 'Passwordless registration is not enabled.',\n REGISTRATION_REQUIRES_CONTACT: 'Either mobile or email is required for initiating registration.',\n EMAIL_REQUIRED_FOR_VALIDATION: 'Email is required for email validation source.',\n MOBILE_REQUIRED_FOR_VALIDATION: 'Mobile is required for mobile validation source.',\n USER_ALREADY_EXISTS: 'User already exists. Please sign in.',\n VALIDATION_SOURCE_REQUIRED: 'At least one validation source is required.',\n INVALID_OTP: 'Invalid OTP.',\n OTP_EXPIRED: 'OTP has expired.',\n INVALID_VERIFICATION_TYPE: 'Invalid type. Must be either email or mobile.',\n NON_LOCAL_PROVIDER: 'User seems to have used a passwordless mode to authenticate.',\n USER_ID_MISMATCH: \"User ID's do not match.\",\n USERNAME_MISMATCH: \"User username's do not match.\",\n INCORRECT_CURRENT_PASSWORD: 'Incorrect current password specified.',\n PASSWORD_REUSED: 'Try a different password',\n INVALID_VERIFICATION_TOKEN: 'Invalid verification token',\n INVALID_REFRESH_TOKEN: 'Invalid refresh token',\n ACCESS_DENIED: 'Access denied',\n INVALID_USER_PROFILE: 'Invalid user profile',\n GOOGLE_OAUTH_PROFILE_FETCH_FAILED: 'Failed to fetch user profile from Google OAuth service',\n MICROSOFT_ACTIVE_DIRECTORY_OAUTH_PROFILE_FETCH_FAILED: 'Failed to fetch user profile from Microsoft Active Directory OAuth service',\n LOGOUT_FAILED: 'Logout failed due to an unexpected error.',\n\n INVALID_CREDENTIALS: 'Invalid credentials',\n LOGIN_FAILED: 'Login Failed',\n OLD_PASSWORD_INCORRECT: 'You have specified an incorrect old password.',\n INVALID_NEW_PASSWORD: 'Invalid new password.',\n PASSWORDS_DO_NOT_MATCH: 'New passwords are not matching.',\n\n // user management errors\n DELETE_SELF_NOT_ALLOWED: 'Deleting logged-in user is not allowed.',\n DELETE_IDS_REQUIRED: 'At least one ID is required for deletion.',\n USER_MISSING_ID: 'User must exist before initializing roles.',\n ROLES_NOT_FOUND: (roles: string[]) => `The following roles were not found: ${roles.join(', ')}`,\n USER_NOT_FOUND_BY_USERNAME: (username: string) => `User with username '${username}' not found.`,\n ROLE_NOT_FOUND: (roleName: string) => `Role '${roleName}' not found.`,\n PERMISSION_NOT_EXIST: (permission: string) => `Permission '${permission}' does not exist.`,\n\n // session errors\n SESSION_INVALID: 'Your session is no longer valid. Please log in again.',\n SESSION_EXPIRED: 'Your session has expired. Please log in again.',\n\n // filter errors\n GROUP_BY_LIMIT: 'buildFilterQuery: Only 1 Group by field is supported currently.',\n INVALID_GROUP_BY_COUNT: 'Exactly one groupBy field is required to count grouped records.',\n\n // general errors\n FORBIDDEN: 'Forbidden',\n RESOURCE_NOT_FOUND: 'The requested resource was not found.',\n\n\n // database errors\n DUPLICATE_ENTRY: 'Duplicate entry. A record with similar unique fields already exists.',\n\n // validation errors\n ID_REQUIRED_FOR_UPDATE: 'Id is required for update.',\n ID_REQUIRED_FOR_DELETE: 'Id is required for deletion.',\n\n // CRUD service errors\n RELATION_TYPE_NOT_SUPPORTED: 'Relation type not supported in CRUD service.',\n NO_SOFT_DELETED_RECORD_FOUND: 'No soft-deleted record found with the given ID.',\n CONFLICTING_RECORD_ON_UNARCHIVE: 'Another record is conflicting with the record you are attempting to Un-Archive, either delete or change the other record so as to avoid this conflict.',\n NO_SOFT_DELETED_RECORDS_FOUND: 'No matching soft-deleted records found.',\n EMPTY_PATH_PARTS: 'Path parts cannot be empty',\n\n\n // CSV/Excel service errors\n MISSING_HEADERS_OR_FUNCTION: 'Either headers or data records function must be provided.',\n INVALID_CHUNK_SIZE: 'Chunk size must be greater than 0 when data records function is provided.',\n INVALID_FORMAT: (format: string) => `Invalid ${format} format`,\n\n\n //field errors\n INVALID_INVERSE_FIELD_TYPE: 'Only relation fields can have inverse fields.',\n MODEL_AND_MODULE_REQUIRED_TO_UPDATE_INVERSE_FIELD: 'Model and module are required to update inverse field.',\n MODEL_NAME_AND_MODULE_NAME_REQUIRED_TO_CREATE_INVERSE_FIELD: 'Model name and module name are required to create inverse field.',\n FIELD_NOT_FOUND: (id: number | string) => `No field with id #${id} exists`,\n PROVIDER_NOT_FOUND: (provider: string) => `Field incorrectly configured. No provider with name ${provider} registered in backend.`,\n FILE_WRITE_FAILED: 'File creation failed, rolling back transaction',\n FILE_DELETE_FAILED: 'File deletion failed, rolling back transaction',\n // file service errors\n FILE_NOT_FOUND: 'File not found',\n FILE_COPY_ERROR: 'Error copying file',\n S3_CLIENT_NOT_INITIALIZED: 'S3 Client not initialized. Please check the S3 configuration.',\n\n // model errors\n MODEL_METADATA_NOT_FOUND: (id: string | number) => `Model metadata with ID ${id} not found.`,\n MODEL_SERVICE_NOT_FOUND: (model: string) => `Model service for ${model} not found.`,\n RELATION_CO_MODEL_NOT_DEFINED_FOR_FIELD: (fieldName: string) => `Relation coModelSingularName is not defined for relation field ${fieldName}`,\n MODEL_NOT_FOUND: (singularName?: string) => `Model${singularName ? ` with singular name \"${singularName}\"` : ''} not found.`,\n MODEL_REQUIRED_FOR_CODE_GENERATION: 'Model ID or Model Name is required for generating code.',\n\n //module errors\n MODULE_NOT_FOUND: (moduleName: string) => `Module with name ${moduleName} not found.`,\n MODULE_ID_NOT_FOUND: (id: string | number) => `Module with ID ${id} not found.`,\n\n //entity errors\n ENTITY_NOT_FOUND: (entity?: string | number) => `Entity${entity ? ' ' + entity : ''} not found.`,\n ENTITY_NAME_REQUIRED: 'Entity name is required to find the entity.',\n ENTITY_ID_REQUIRED: 'Entity ID is required to find the entity.',\n\n // import errors\n NO_ERROR_LOG_FOR_IMPORT: (id: string | number) => `No error log entries found for import transaction ID ${id}.`,\n FILE_READ_FAILED_FROM_URL: (url: string) => `Failed to read file from URL: ${url}`,\n\n // media storage provider errors\n MEDIA_STORAGE_PROVIDER_ID_NOT_FOUND: (id: number | string) => `Media Storage Provider with #${id} not found.`,\n MEDIA_STORAGE_PROVIDER_NOT_FOUND: 'Media Storage Provider not found',\n\n // SQL errors\n UNSUPPORTED_SQL_OPERATOR: (operator: string) => `Unsupported SQL operator: ${operator}`,\n\n // AI interaction errors\n PYTHON_EXECUTABLE_NOT_CONFIGURED: 'SolidX AI MCP python executable or client path not configured.',\n UNABLE_TO_RESOLVE_SOLID_COMMAND: 'Unable to resolve a solid_ command that was used to come up with this response.',\n UNABLE_TO_RESOLVE_MCP_HANDLER: 'Unable to resolve a mcp tool handler.',\n\n DEFAULT_REGEX_PATTERN_NOT_MATCHING_ERROR_MSG: 'Invalid regex pattern.',\n\n // MPIN errors.\n // MPIN_INVALID is deliberately shared by \"wrong MPIN\" and \"unknown handle\",\n // so a failed sign-in never reveals whether the credential handle was real.\n // MPIN_REVOKED is separate and is returned for any attempt against a\n // deactivated credential - it discloses nothing useful, since a dead\n // credential grants no capability, and it lets the client stop retrying.\n MPIN_INVALID: 'Invalid MPIN.',\n MPIN_LOCKED: 'MPIN sign-in is temporarily locked due to repeated failed attempts.',\n MPIN_REVOKED: 'MPIN sign-in has been disabled for this device. Please sign in normally.',\n MPIN_NOT_ENABLED: 'MPIN sign-in is not enabled.',\n MPIN_FORMAT_INVALID: 'MPIN does not meet the required format.',\n MPIN_TOO_PREDICTABLE: 'MPIN is too easy to guess. Avoid repeated or sequential digits.',\n MPIN_CREDENTIAL_NOT_FOUND: 'MPIN device credential not found.',\n\n PERMISSION_MESSAGES: {\n insertMany: (model?: string) =>\n `You do not have permission to import ${model ?? 'these'} records.`,\n } as Record<string, (model?: string) => string>,\n\n};\n"]}
|
|
@@ -5,6 +5,9 @@ export declare const SUCCESS_MESSAGES: {
|
|
|
5
5
|
FORGOT_PASSWORD_CONFIRMED: string;
|
|
6
6
|
LOGOUT_SUCCESS: string;
|
|
7
7
|
USER_REGISTERED: string;
|
|
8
|
+
MPIN_SETUP_SUCCESS: string;
|
|
9
|
+
MPIN_CHANGED_SUCCESS: string;
|
|
10
|
+
MPIN_DEVICE_REVOKED: string;
|
|
8
11
|
RECORD_RECOVERED: string;
|
|
9
12
|
SELECTED_RECORDS_RECOVERED: string;
|
|
10
13
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"success-messages.d.ts","sourceRoot":"","sources":["../../src/constants/success-messages.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB
|
|
1
|
+
{"version":3,"file":"success-messages.d.ts","sourceRoot":"","sources":["../../src/constants/success-messages.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB;;;;;;;;;;;;CAiB5B,CAAC"}
|
|
@@ -8,6 +8,9 @@ exports.SUCCESS_MESSAGES = {
|
|
|
8
8
|
FORGOT_PASSWORD_CONFIRMED: 'Forgot password confirmed.',
|
|
9
9
|
LOGOUT_SUCCESS: 'Logged out successfully',
|
|
10
10
|
USER_REGISTERED: 'User registered successfully.',
|
|
11
|
+
MPIN_SETUP_SUCCESS: 'MPIN set up successfully.',
|
|
12
|
+
MPIN_CHANGED_SUCCESS: 'MPIN changed successfully.',
|
|
13
|
+
MPIN_DEVICE_REVOKED: 'MPIN sign-in removed for this device.',
|
|
11
14
|
RECORD_RECOVERED: 'Record successfully recovered',
|
|
12
15
|
SELECTED_RECORDS_RECOVERED: 'Selected records successfully recovered',
|
|
13
16
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"success-messages.js","sourceRoot":"","sources":["../../src/constants/success-messages.ts"],"names":[],"mappings":";;;AAAa,QAAA,gBAAgB,GAAG;IAC5B,6BAA6B,EAAE,oDAAoD;IACnF,sBAAsB,EAAE,6CAA6C;IACrE,0BAA0B,EAAE,6CAA6C;IACzE,yBAAyB,EAAE,4BAA4B;IACvD,cAAc,EAAE,yBAAyB;IACzC,eAAe,EAAE,+BAA+B;IAGhD,gBAAgB,EAAE,+BAA+B;IACjD,0BAA0B,EAAE,yCAAyC;CAExE,CAAC","sourcesContent":["export const SUCCESS_MESSAGES = {\n OTP_SENT_SUCCESS_REGISTRATION: 'User registration initiated. OTP sent to the user.',\n OTP_SENT_SUCCESS_LOGIN: 'User login initiated. OTP sent to the user.',\n FORGOT_PASSWORD_TOKEN_SENT: 'Forgot password - token generated and sent.',\n FORGOT_PASSWORD_CONFIRMED: 'Forgot password confirmed.',\n LOGOUT_SUCCESS: 'Logged out successfully',\n USER_REGISTERED: 'User registered successfully.',\n\n // CRUD service messages\n RECORD_RECOVERED: 'Record successfully recovered',\n SELECTED_RECORDS_RECOVERED: 'Selected records successfully recovered',\n\n};\n"]}
|
|
1
|
+
{"version":3,"file":"success-messages.js","sourceRoot":"","sources":["../../src/constants/success-messages.ts"],"names":[],"mappings":";;;AAAa,QAAA,gBAAgB,GAAG;IAC5B,6BAA6B,EAAE,oDAAoD;IACnF,sBAAsB,EAAE,6CAA6C;IACrE,0BAA0B,EAAE,6CAA6C;IACzE,yBAAyB,EAAE,4BAA4B;IACvD,cAAc,EAAE,yBAAyB;IACzC,eAAe,EAAE,+BAA+B;IAGhD,kBAAkB,EAAE,2BAA2B;IAC/C,oBAAoB,EAAE,4BAA4B;IAClD,mBAAmB,EAAE,uCAAuC;IAG5D,gBAAgB,EAAE,+BAA+B;IACjD,0BAA0B,EAAE,yCAAyC;CAExE,CAAC","sourcesContent":["export const SUCCESS_MESSAGES = {\n OTP_SENT_SUCCESS_REGISTRATION: 'User registration initiated. OTP sent to the user.',\n OTP_SENT_SUCCESS_LOGIN: 'User login initiated. OTP sent to the user.',\n FORGOT_PASSWORD_TOKEN_SENT: 'Forgot password - token generated and sent.',\n FORGOT_PASSWORD_CONFIRMED: 'Forgot password confirmed.',\n LOGOUT_SUCCESS: 'Logged out successfully',\n USER_REGISTERED: 'User registered successfully.',\n\n // MPIN messages\n MPIN_SETUP_SUCCESS: 'MPIN set up successfully.',\n MPIN_CHANGED_SUCCESS: 'MPIN changed successfully.',\n MPIN_DEVICE_REVOKED: 'MPIN sign-in removed for this device.',\n\n // CRUD service messages\n RECORD_RECOVERED: 'Record successfully recovered',\n SELECTED_RECORDS_RECOVERED: 'Selected records successfully recovered',\n\n};\n"]}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { ChangeMpinDto } from '../dtos/change-mpin.dto';
|
|
2
|
+
import { MpinLoginDto } from '../dtos/mpin-login.dto';
|
|
3
|
+
import { SetupMpinDto } from '../dtos/setup-mpin.dto';
|
|
4
|
+
import { ActiveUserData } from '../interfaces/active-user-data.interface';
|
|
5
|
+
import { MpinService } from '../services/mpin.service';
|
|
6
|
+
export declare class MpinAuthenticationController {
|
|
7
|
+
private readonly mpinService;
|
|
8
|
+
constructor(mpinService: MpinService);
|
|
9
|
+
setup(setupMpinDto: SetupMpinDto, activeUser: ActiveUserData): Promise<{
|
|
10
|
+
credentialRef: string;
|
|
11
|
+
message: string;
|
|
12
|
+
}>;
|
|
13
|
+
change(changeMpinDto: ChangeMpinDto, activeUser: ActiveUserData): Promise<{
|
|
14
|
+
credentialRef: string;
|
|
15
|
+
message: string;
|
|
16
|
+
}>;
|
|
17
|
+
login(mpinLoginDto: MpinLoginDto): Promise<{
|
|
18
|
+
accessToken: string;
|
|
19
|
+
refreshToken: string;
|
|
20
|
+
user: {
|
|
21
|
+
id: number;
|
|
22
|
+
email: string;
|
|
23
|
+
mobile: string;
|
|
24
|
+
username: string;
|
|
25
|
+
forcePasswordChange: boolean;
|
|
26
|
+
roles: string[];
|
|
27
|
+
};
|
|
28
|
+
}>;
|
|
29
|
+
listDevices(activeUser: ActiveUserData): Promise<{
|
|
30
|
+
id: number;
|
|
31
|
+
deviceId: string;
|
|
32
|
+
deviceName: string;
|
|
33
|
+
platform: string;
|
|
34
|
+
isActive: boolean;
|
|
35
|
+
failedAttempts: number;
|
|
36
|
+
lockedUntil: Date;
|
|
37
|
+
lastUsedAt: Date;
|
|
38
|
+
createdAt: Date;
|
|
39
|
+
}[]>;
|
|
40
|
+
revokeDevice(id: number, activeUser: ActiveUserData): Promise<{
|
|
41
|
+
message: string;
|
|
42
|
+
}>;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=mpin-authentication.controller.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mpin-authentication.controller.d.ts","sourceRoot":"","sources":["../../src/controllers/mpin-authentication.controller.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,0CAA0C,CAAC;AAC1E,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAQvD,qBAEa,4BAA4B;IACzB,OAAO,CAAC,QAAQ,CAAC,WAAW;gBAAX,WAAW,EAAE,WAAW;IAKrD,KAAK,CACO,YAAY,EAAE,YAAY,EACpB,UAAU,EAAE,cAAc;;;;IAQ5C,MAAM,CACM,aAAa,EAAE,aAAa,EACtB,UAAU,EAAE,cAAc;;;;IAU5C,KAAK,CAAS,YAAY,EAAE,YAAY;;;;;;;;;;;;IAMxC,WAAW,CAAe,UAAU,EAAE,cAAc;;;;;;;;;;;IAQpD,YAAY,CACmB,EAAE,EAAE,MAAM,EACvB,UAAU,EAAE,cAAc;;;CAI/C"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.MpinAuthenticationController = void 0;
|
|
16
|
+
const openapi = require("@nestjs/swagger");
|
|
17
|
+
const common_1 = require("@nestjs/common");
|
|
18
|
+
const swagger_1 = require("@nestjs/swagger");
|
|
19
|
+
const active_user_decorator_1 = require("../decorators/active-user.decorator");
|
|
20
|
+
const public_decorator_1 = require("../decorators/public.decorator");
|
|
21
|
+
const change_mpin_dto_1 = require("../dtos/change-mpin.dto");
|
|
22
|
+
const mpin_login_dto_1 = require("../dtos/mpin-login.dto");
|
|
23
|
+
const setup_mpin_dto_1 = require("../dtos/setup-mpin.dto");
|
|
24
|
+
const mpin_service_1 = require("../services/mpin.service");
|
|
25
|
+
let MpinAuthenticationController = class MpinAuthenticationController {
|
|
26
|
+
constructor(mpinService) {
|
|
27
|
+
this.mpinService = mpinService;
|
|
28
|
+
}
|
|
29
|
+
setup(setupMpinDto, activeUser) {
|
|
30
|
+
return this.mpinService.setupMpin(activeUser, setupMpinDto);
|
|
31
|
+
}
|
|
32
|
+
change(changeMpinDto, activeUser) {
|
|
33
|
+
return this.mpinService.changeMpin(activeUser, changeMpinDto);
|
|
34
|
+
}
|
|
35
|
+
login(mpinLoginDto) {
|
|
36
|
+
return this.mpinService.loginWithMpin(mpinLoginDto);
|
|
37
|
+
}
|
|
38
|
+
listDevices(activeUser) {
|
|
39
|
+
return this.mpinService.listDevices(activeUser);
|
|
40
|
+
}
|
|
41
|
+
revokeDevice(id, activeUser) {
|
|
42
|
+
return this.mpinService.revokeDevice(activeUser, id);
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
exports.MpinAuthenticationController = MpinAuthenticationController;
|
|
46
|
+
__decorate([
|
|
47
|
+
(0, swagger_1.ApiBearerAuth)('jwt'),
|
|
48
|
+
(0, common_1.Post)('setup'),
|
|
49
|
+
(0, common_1.HttpCode)(common_1.HttpStatus.OK),
|
|
50
|
+
openapi.ApiResponse({ status: common_1.HttpStatus.OK }),
|
|
51
|
+
__param(0, (0, common_1.Body)()),
|
|
52
|
+
__param(1, (0, active_user_decorator_1.ActiveUser)()),
|
|
53
|
+
__metadata("design:type", Function),
|
|
54
|
+
__metadata("design:paramtypes", [setup_mpin_dto_1.SetupMpinDto, Object]),
|
|
55
|
+
__metadata("design:returntype", void 0)
|
|
56
|
+
], MpinAuthenticationController.prototype, "setup", null);
|
|
57
|
+
__decorate([
|
|
58
|
+
(0, swagger_1.ApiBearerAuth)('jwt'),
|
|
59
|
+
(0, common_1.Post)('change'),
|
|
60
|
+
(0, common_1.HttpCode)(common_1.HttpStatus.OK),
|
|
61
|
+
openapi.ApiResponse({ status: common_1.HttpStatus.OK }),
|
|
62
|
+
__param(0, (0, common_1.Body)()),
|
|
63
|
+
__param(1, (0, active_user_decorator_1.ActiveUser)()),
|
|
64
|
+
__metadata("design:type", Function),
|
|
65
|
+
__metadata("design:paramtypes", [change_mpin_dto_1.ChangeMpinDto, Object]),
|
|
66
|
+
__metadata("design:returntype", void 0)
|
|
67
|
+
], MpinAuthenticationController.prototype, "change", null);
|
|
68
|
+
__decorate([
|
|
69
|
+
(0, public_decorator_1.Public)(),
|
|
70
|
+
(0, common_1.Post)('login'),
|
|
71
|
+
(0, common_1.HttpCode)(common_1.HttpStatus.OK),
|
|
72
|
+
openapi.ApiResponse({ status: common_1.HttpStatus.OK }),
|
|
73
|
+
__param(0, (0, common_1.Body)()),
|
|
74
|
+
__metadata("design:type", Function),
|
|
75
|
+
__metadata("design:paramtypes", [mpin_login_dto_1.MpinLoginDto]),
|
|
76
|
+
__metadata("design:returntype", void 0)
|
|
77
|
+
], MpinAuthenticationController.prototype, "login", null);
|
|
78
|
+
__decorate([
|
|
79
|
+
(0, swagger_1.ApiBearerAuth)('jwt'),
|
|
80
|
+
(0, common_1.Get)('devices'),
|
|
81
|
+
openapi.ApiResponse({ status: 200 }),
|
|
82
|
+
__param(0, (0, active_user_decorator_1.ActiveUser)()),
|
|
83
|
+
__metadata("design:type", Function),
|
|
84
|
+
__metadata("design:paramtypes", [Object]),
|
|
85
|
+
__metadata("design:returntype", void 0)
|
|
86
|
+
], MpinAuthenticationController.prototype, "listDevices", null);
|
|
87
|
+
__decorate([
|
|
88
|
+
(0, swagger_1.ApiBearerAuth)('jwt'),
|
|
89
|
+
(0, common_1.Delete)('devices/:id'),
|
|
90
|
+
openapi.ApiResponse({ status: 200 }),
|
|
91
|
+
__param(0, (0, common_1.Param)('id', common_1.ParseIntPipe)),
|
|
92
|
+
__param(1, (0, active_user_decorator_1.ActiveUser)()),
|
|
93
|
+
__metadata("design:type", Function),
|
|
94
|
+
__metadata("design:paramtypes", [Number, Object]),
|
|
95
|
+
__metadata("design:returntype", void 0)
|
|
96
|
+
], MpinAuthenticationController.prototype, "revokeDevice", null);
|
|
97
|
+
exports.MpinAuthenticationController = MpinAuthenticationController = __decorate([
|
|
98
|
+
(0, common_1.Controller)('iam/mpin'),
|
|
99
|
+
(0, swagger_1.ApiTags)('Solid Core'),
|
|
100
|
+
__metadata("design:paramtypes", [mpin_service_1.MpinService])
|
|
101
|
+
], MpinAuthenticationController);
|
|
102
|
+
//# sourceMappingURL=mpin-authentication.controller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mpin-authentication.controller.js","sourceRoot":"","sources":["../../src/controllers/mpin-authentication.controller.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAAgH;AAChH,6CAAyD;AACzD,+EAAiE;AACjE,qEAAwD;AACxD,6DAAwD;AACxD,2DAAsD;AACtD,2DAAsD;AAEtD,2DAAuD;AAUhD,IAAM,4BAA4B,GAAlC,MAAM,4BAA4B;IACrC,YAA6B,WAAwB;QAAxB,gBAAW,GAAX,WAAW,CAAa;IAAI,CAAC;IAK1D,KAAK,CACO,YAA0B,EACpB,UAA0B;QAExC,OAAO,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;IAChE,CAAC;IAKD,MAAM,CACM,aAA4B,EACtB,UAA0B;QAExC,OAAO,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;IAClE,CAAC;IAOD,KAAK,CAAS,YAA0B;QACpC,OAAO,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;IACxD,CAAC;IAID,WAAW,CAAe,UAA0B;QAChD,OAAO,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;IACpD,CAAC;IAMD,YAAY,CACmB,EAAU,EACvB,UAA0B;QAExC,OAAO,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IACzD,CAAC;CACJ,CAAA;AAhDY,oEAA4B;AAMrC;IAHC,IAAA,uBAAa,EAAC,KAAK,CAAC;IACpB,IAAA,aAAI,EAAC,OAAO,CAAC;IACb,IAAA,iBAAQ,EAAC,mBAAU,CAAC,EAAE,CAAC;kCAAd,mBAAU,CAAC,EAAE;IAElB,WAAA,IAAA,aAAI,GAAE,CAAA;IACN,WAAA,IAAA,kCAAU,GAAE,CAAA;;qCADS,6BAAY;;yDAIrC;AAKD;IAHC,IAAA,uBAAa,EAAC,KAAK,CAAC;IACpB,IAAA,aAAI,EAAC,QAAQ,CAAC;IACd,IAAA,iBAAQ,EAAC,mBAAU,CAAC,EAAE,CAAC;kCAAd,mBAAU,CAAC,EAAE;IAElB,WAAA,IAAA,aAAI,GAAE,CAAA;IACN,WAAA,IAAA,kCAAU,GAAE,CAAA;;qCADU,+BAAa;;0DAIvC;AAOD;IAHC,IAAA,yBAAM,GAAE;IACR,IAAA,aAAI,EAAC,OAAO,CAAC;IACb,IAAA,iBAAQ,EAAC,mBAAU,CAAC,EAAE,CAAC;kCAAd,mBAAU,CAAC,EAAE;IAChB,WAAA,IAAA,aAAI,GAAE,CAAA;;qCAAe,6BAAY;;yDAEvC;AAID;IAFC,IAAA,uBAAa,EAAC,KAAK,CAAC;IACpB,IAAA,YAAG,EAAC,SAAS,CAAC;;IACF,WAAA,IAAA,kCAAU,GAAE,CAAA;;;;+DAExB;AAMD;IAFC,IAAA,uBAAa,EAAC,KAAK,CAAC;IACpB,IAAA,eAAM,EAAC,aAAa,CAAC;;IAEjB,WAAA,IAAA,cAAK,EAAC,IAAI,EAAE,qBAAY,CAAC,CAAA;IACzB,WAAA,IAAA,kCAAU,GAAE,CAAA;;;;gEAGhB;uCA/CQ,4BAA4B;IAFxC,IAAA,mBAAU,EAAC,UAAU,CAAC;IACtB,IAAA,iBAAO,EAAC,YAAY,CAAC;qCAEwB,0BAAW;GAD5C,4BAA4B,CAgDxC","sourcesContent":["import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, ParseIntPipe, Post } from '@nestjs/common';\nimport { ApiBearerAuth, ApiTags } from '@nestjs/swagger';\nimport { ActiveUser } from '../decorators/active-user.decorator';\nimport { Public } from '../decorators/public.decorator';\nimport { ChangeMpinDto } from '../dtos/change-mpin.dto';\nimport { MpinLoginDto } from '../dtos/mpin-login.dto';\nimport { SetupMpinDto } from '../dtos/setup-mpin.dto';\nimport { ActiveUserData } from '../interfaces/active-user-data.interface';\nimport { MpinService } from '../services/mpin.service';\n\n/**\n * There is deliberately no public \"is MPIN set up for this identifier\" route.\n * That would reintroduce exactly the user-enumeration oracle the opaque\n * credential handle removes. The client decides whether to show the MPIN\n * screen from the presence of its own stored handle.\n */\n@Controller('iam/mpin')\n@ApiTags('Solid Core')\nexport class MpinAuthenticationController {\n constructor(private readonly mpinService: MpinService) { }\n\n @ApiBearerAuth('jwt')\n @Post('setup')\n @HttpCode(HttpStatus.OK)\n setup(\n @Body() setupMpinDto: SetupMpinDto,\n @ActiveUser() activeUser: ActiveUserData,\n ) {\n return this.mpinService.setupMpin(activeUser, setupMpinDto);\n }\n\n @ApiBearerAuth('jwt')\n @Post('change')\n @HttpCode(HttpStatus.OK)\n change(\n @Body() changeMpinDto: ChangeMpinDto,\n @ActiveUser() activeUser: ActiveUserData,\n ) {\n return this.mpinService.changeMpin(activeUser, changeMpinDto);\n }\n\n // Public by necessity - the caller has no session yet. The credential\n // handle is unguessable, so this carries no enumeration surface.\n @Public()\n @Post('login')\n @HttpCode(HttpStatus.OK)\n login(@Body() mpinLoginDto: MpinLoginDto) {\n return this.mpinService.loginWithMpin(mpinLoginDto);\n }\n\n @ApiBearerAuth('jwt')\n @Get('devices')\n listDevices(@ActiveUser() activeUser: ActiveUserData) {\n return this.mpinService.listDevices(activeUser);\n }\n\n // By row id, never by credential handle, so the management UI never has to\n // hold the secret.\n @ApiBearerAuth('jwt')\n @Delete('devices/:id')\n revokeDevice(\n @Param('id', ParseIntPipe) id: number,\n @ActiveUser() activeUser: ActiveUserData,\n ) {\n return this.mpinService.revokeDevice(activeUser, id);\n }\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"change-mpin.dto.d.ts","sourceRoot":"","sources":["../../src/dtos/change-mpin.dto.ts"],"names":[],"mappings":"AAEA,qBAAa,aAAa;IAItB,aAAa,EAAE,MAAM,CAAC;IAKtB,WAAW,EAAE,MAAM,CAAC;IAKpB,OAAO,EAAE,MAAM,CAAC;CACnB"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.ChangeMpinDto = void 0;
|
|
13
|
+
const openapi = require("@nestjs/swagger");
|
|
14
|
+
const class_validator_1 = require("class-validator");
|
|
15
|
+
class ChangeMpinDto {
|
|
16
|
+
static _OPENAPI_METADATA_FACTORY() {
|
|
17
|
+
return { credentialRef: { required: true, type: () => String, maxLength: 128 }, currentMpin: { required: true, type: () => String, maxLength: 32 }, newMpin: { required: true, type: () => String, maxLength: 32 } };
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
exports.ChangeMpinDto = ChangeMpinDto;
|
|
21
|
+
__decorate([
|
|
22
|
+
(0, class_validator_1.IsNotEmpty)(),
|
|
23
|
+
(0, class_validator_1.IsString)(),
|
|
24
|
+
(0, class_validator_1.MaxLength)(128),
|
|
25
|
+
__metadata("design:type", String)
|
|
26
|
+
], ChangeMpinDto.prototype, "credentialRef", void 0);
|
|
27
|
+
__decorate([
|
|
28
|
+
(0, class_validator_1.IsNotEmpty)(),
|
|
29
|
+
(0, class_validator_1.IsString)(),
|
|
30
|
+
(0, class_validator_1.MaxLength)(32),
|
|
31
|
+
__metadata("design:type", String)
|
|
32
|
+
], ChangeMpinDto.prototype, "currentMpin", void 0);
|
|
33
|
+
__decorate([
|
|
34
|
+
(0, class_validator_1.IsNotEmpty)(),
|
|
35
|
+
(0, class_validator_1.IsString)(),
|
|
36
|
+
(0, class_validator_1.MaxLength)(32),
|
|
37
|
+
__metadata("design:type", String)
|
|
38
|
+
], ChangeMpinDto.prototype, "newMpin", void 0);
|
|
39
|
+
//# sourceMappingURL=change-mpin.dto.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"change-mpin.dto.js","sourceRoot":"","sources":["../../src/dtos/change-mpin.dto.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,qDAAkE;AAElE,MAAa,aAAa;;;;CAezB;AAfD,sCAeC;AAXG;IAHC,IAAA,4BAAU,GAAE;IACZ,IAAA,0BAAQ,GAAE;IACV,IAAA,2BAAS,EAAC,GAAG,CAAC;;oDACO;AAKtB;IAHC,IAAA,4BAAU,GAAE;IACZ,IAAA,0BAAQ,GAAE;IACV,IAAA,2BAAS,EAAC,EAAE,CAAC;;kDACM;AAKpB;IAHC,IAAA,4BAAU,GAAE;IACZ,IAAA,0BAAQ,GAAE;IACV,IAAA,2BAAS,EAAC,EAAE,CAAC;;8CACE","sourcesContent":["import { IsNotEmpty, IsString, MaxLength } from 'class-validator';\n\nexport class ChangeMpinDto {\n @IsNotEmpty()\n @IsString()\n @MaxLength(128)\n credentialRef: string;\n\n @IsNotEmpty()\n @IsString()\n @MaxLength(32)\n currentMpin: string;\n\n @IsNotEmpty()\n @IsString()\n @MaxLength(32)\n newMpin: string;\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mpin-login.dto.d.ts","sourceRoot":"","sources":["../../src/dtos/mpin-login.dto.ts"],"names":[],"mappings":"AAWA,qBAAa,YAAY;IAMrB,aAAa,EAAE,MAAM,CAAC;IAKtB,IAAI,EAAE,MAAM,CAAC;CAChB"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.MpinLoginDto = void 0;
|
|
13
|
+
const openapi = require("@nestjs/swagger");
|
|
14
|
+
const class_validator_1 = require("class-validator");
|
|
15
|
+
class MpinLoginDto {
|
|
16
|
+
static _OPENAPI_METADATA_FACTORY() {
|
|
17
|
+
return { credentialRef: { required: true, type: () => String, maxLength: 128 }, mpin: { required: true, type: () => String, maxLength: 32 } };
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
exports.MpinLoginDto = MpinLoginDto;
|
|
21
|
+
__decorate([
|
|
22
|
+
(0, class_validator_1.IsNotEmpty)(),
|
|
23
|
+
(0, class_validator_1.IsString)(),
|
|
24
|
+
(0, class_validator_1.MaxLength)(128),
|
|
25
|
+
__metadata("design:type", String)
|
|
26
|
+
], MpinLoginDto.prototype, "credentialRef", void 0);
|
|
27
|
+
__decorate([
|
|
28
|
+
(0, class_validator_1.IsNotEmpty)(),
|
|
29
|
+
(0, class_validator_1.IsString)(),
|
|
30
|
+
(0, class_validator_1.MaxLength)(32),
|
|
31
|
+
__metadata("design:type", String)
|
|
32
|
+
], MpinLoginDto.prototype, "mpin", void 0);
|
|
33
|
+
//# sourceMappingURL=mpin-login.dto.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mpin-login.dto.js","sourceRoot":"","sources":["../../src/dtos/mpin-login.dto.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,qDAAkE;AAWlE,MAAa,YAAY;;;;CAYxB;AAZD,oCAYC;AANG;IAHC,IAAA,4BAAU,GAAE;IACZ,IAAA,0BAAQ,GAAE;IACV,IAAA,2BAAS,EAAC,GAAG,CAAC;;mDACO;AAKtB;IAHC,IAAA,4BAAU,GAAE;IACZ,IAAA,0BAAQ,GAAE;IACV,IAAA,2BAAS,EAAC,EAAE,CAAC;;0CACD","sourcesContent":["import { IsNotEmpty, IsString, MaxLength } from 'class-validator';\n\n/**\n * Deliberately carries no identifier - no mobile, email or username.\n *\n * `credentialRef` is a server-issued 256-bit handle that already points at a\n * single credential row, and therefore at a single user. That is what removes\n * the user-enumeration surface a public login route would otherwise have: an\n * attacker cannot probe \"does this phone number have MPIN?\" because there is\n * nowhere to put a phone number.\n */\nexport class MpinLoginDto {\n // Bounded so a pathological payload never reaches the regex test or the\n // hash comparison. The handle is always 64 hex characters.\n @IsNotEmpty()\n @IsString()\n @MaxLength(128)\n credentialRef: string;\n\n @IsNotEmpty()\n @IsString()\n @MaxLength(32)\n mpin: string;\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup-mpin.dto.d.ts","sourceRoot":"","sources":["../../src/dtos/setup-mpin.dto.ts"],"names":[],"mappings":"AAEA,qBAAa,YAAY;IAOrB,QAAQ,EAAE,MAAM,CAAC;IAsBjB,IAAI,EAAE,MAAM,CAAC;IAYb,UAAU,CAAC,EAAE,MAAM,CAAC;IAMpB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.SetupMpinDto = void 0;
|
|
13
|
+
const openapi = require("@nestjs/swagger");
|
|
14
|
+
const class_validator_1 = require("class-validator");
|
|
15
|
+
class SetupMpinDto {
|
|
16
|
+
static _OPENAPI_METADATA_FACTORY() {
|
|
17
|
+
return { deviceId: { required: true, type: () => String }, mpin: { required: true, type: () => String, maxLength: 32 }, deviceName: { required: false, type: () => String, maxLength: 64, pattern: "/^[\\w\\s.'()-]*$/" }, platform: { required: false, type: () => String, maxLength: 32, pattern: "/^[\\w.-]*$/" } };
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
exports.SetupMpinDto = SetupMpinDto;
|
|
21
|
+
__decorate([
|
|
22
|
+
(0, class_validator_1.IsUUID)(),
|
|
23
|
+
__metadata("design:type", String)
|
|
24
|
+
], SetupMpinDto.prototype, "deviceId", void 0);
|
|
25
|
+
__decorate([
|
|
26
|
+
(0, class_validator_1.IsNotEmpty)(),
|
|
27
|
+
(0, class_validator_1.IsString)(),
|
|
28
|
+
(0, class_validator_1.MaxLength)(32),
|
|
29
|
+
__metadata("design:type", String)
|
|
30
|
+
], SetupMpinDto.prototype, "mpin", void 0);
|
|
31
|
+
__decorate([
|
|
32
|
+
(0, class_validator_1.IsOptional)(),
|
|
33
|
+
(0, class_validator_1.IsString)(),
|
|
34
|
+
(0, class_validator_1.MaxLength)(64),
|
|
35
|
+
(0, class_validator_1.Matches)(/^[\w\s.'()-]*$/, {
|
|
36
|
+
message: 'deviceName may contain only letters, numbers, spaces and . \' ( ) - _',
|
|
37
|
+
}),
|
|
38
|
+
__metadata("design:type", String)
|
|
39
|
+
], SetupMpinDto.prototype, "deviceName", void 0);
|
|
40
|
+
__decorate([
|
|
41
|
+
(0, class_validator_1.IsOptional)(),
|
|
42
|
+
(0, class_validator_1.IsString)(),
|
|
43
|
+
(0, class_validator_1.MaxLength)(32),
|
|
44
|
+
(0, class_validator_1.Matches)(/^[\w.-]*$/, { message: 'platform may contain only letters, numbers and . - _' }),
|
|
45
|
+
__metadata("design:type", String)
|
|
46
|
+
], SetupMpinDto.prototype, "platform", void 0);
|
|
47
|
+
//# sourceMappingURL=setup-mpin.dto.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup-mpin.dto.js","sourceRoot":"","sources":["../../src/dtos/setup-mpin.dto.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,qDAA+F;AAE/F,MAAa,YAAY;;;;CAgDxB;AAhDD,oCAgDC;AAzCG;IADC,IAAA,wBAAM,GAAE;;8CACQ;AAsBjB;IAHC,IAAA,4BAAU,GAAE;IACZ,IAAA,0BAAQ,GAAE;IACV,IAAA,2BAAS,EAAC,EAAE,CAAC;;0CACD;AAYb;IANC,IAAA,4BAAU,GAAE;IACZ,IAAA,0BAAQ,GAAE;IACV,IAAA,2BAAS,EAAC,EAAE,CAAC;IACb,IAAA,yBAAO,EAAC,gBAAgB,EAAE;QACvB,OAAO,EAAE,uEAAuE;KACnF,CAAC;;gDACkB;AAMpB;IAJC,IAAA,4BAAU,GAAE;IACZ,IAAA,0BAAQ,GAAE;IACV,IAAA,2BAAS,EAAC,EAAE,CAAC;IACb,IAAA,yBAAO,EAAC,WAAW,EAAE,EAAE,OAAO,EAAE,sDAAsD,EAAE,CAAC;;8CACxE","sourcesContent":["import { IsNotEmpty, IsOptional, IsString, IsUUID, Matches, MaxLength } from 'class-validator';\n\nexport class SetupMpinDto {\n /**\n * Stable identifier for the physical device, generated once by the client.\n * Validated as a UUID before it ever reaches a cache key or a bucket name,\n * so it cannot smuggle delimiters into the keyspace.\n */\n @IsUUID()\n deviceId: string;\n\n /**\n * A string, not a number, even though it looks like digits.\n *\n * A numeric MPIN cannot carry a leading zero: JSON forbids leading zeros in\n * number literals, so a client serialising `012345` numerically emits\n * `12345` and the server stores a five-digit MPIN the user never chose -\n * which still satisfies the default `^\\d{4,6}$` and so raises no error.\n * `mpinRegex` is also tenant-configurable and may permit non-digits.\n *\n * Note this cannot be enforced here: the global ValidationPipe runs with\n * `enableImplicitConversion`, so a numeric payload is coerced to a string\n * before @IsString() sees it. Clients must send a quoted JSON string; that\n * requirement is documented in the mobile integration guide.\n *\n * Length and shape are checked server-side against `mpinRegex`, since that\n * setting is the single authority. This only bounds the input.\n */\n @IsNotEmpty()\n @IsString()\n @MaxLength(32)\n mpin: string;\n\n /**\n * Rendered in a device-management list, so it is bounded here rather than\n * trusting every consuming UI to escape it.\n */\n @IsOptional()\n @IsString()\n @MaxLength(64)\n @Matches(/^[\\w\\s.'()-]*$/, {\n message: 'deviceName may contain only letters, numbers, spaces and . \\' ( ) - _',\n })\n deviceName?: string;\n\n @IsOptional()\n @IsString()\n @MaxLength(32)\n @Matches(/^[\\w.-]*$/, { message: 'platform may contain only letters, numbers and . - _' })\n platform?: string;\n}\n"]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { CommonEntity } from "../entities/common.entity";
|
|
2
|
+
import { User } from "./user.entity";
|
|
3
|
+
export declare class UserDeviceCredential extends CommonEntity {
|
|
4
|
+
hashedCredentialRef: string;
|
|
5
|
+
hashedMpin: string;
|
|
6
|
+
mpinScheme: string;
|
|
7
|
+
mpinSchemeVersion: number;
|
|
8
|
+
deviceId: string;
|
|
9
|
+
credentialKey: string;
|
|
10
|
+
deviceName: string;
|
|
11
|
+
platform: string;
|
|
12
|
+
isActive: boolean;
|
|
13
|
+
failedAttempts: number;
|
|
14
|
+
lockedUntil: Date;
|
|
15
|
+
lastUsedAt: Date;
|
|
16
|
+
user: User;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=user-device-credential.entity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user-device-credential.entity.d.ts","sourceRoot":"","sources":["../../src/entities/user-device-credential.entity.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE1D,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAUrC,qBAKa,oBAAqB,SAAQ,YAAY;IASlD,mBAAmB,EAAE,MAAM,CAAC;IAM5B,UAAU,EAAE,MAAM,CAAC;IAKnB,UAAU,EAAE,MAAM,CAAC;IAoBnB,iBAAiB,EAAE,MAAM,CAAC;IAO1B,QAAQ,EAAE,MAAM,CAAC;IAqBjB,aAAa,EAAE,MAAM,CAAC;IAItB,UAAU,EAAE,MAAM,CAAC;IAInB,QAAQ,EAAE,MAAM,CAAC;IAOjB,QAAQ,EAAE,OAAO,CAAC;IAOlB,cAAc,EAAE,MAAM,CAAC;IAIvB,WAAW,EAAE,IAAI,CAAC;IAIlB,UAAU,EAAE,IAAI,CAAC;IAYjB,IAAI,EAAE,IAAI,CAAC;CACd"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.UserDeviceCredential = void 0;
|
|
13
|
+
const openapi = require("@nestjs/swagger");
|
|
14
|
+
const class_transformer_1 = require("class-transformer");
|
|
15
|
+
const common_entity_1 = require("./common.entity");
|
|
16
|
+
const typeorm_1 = require("typeorm");
|
|
17
|
+
const user_entity_1 = require("./user.entity");
|
|
18
|
+
let UserDeviceCredential = class UserDeviceCredential extends common_entity_1.CommonEntity {
|
|
19
|
+
static _OPENAPI_METADATA_FACTORY() {
|
|
20
|
+
return { hashedCredentialRef: { required: true, type: () => String }, hashedMpin: { required: true, type: () => String }, mpinScheme: { required: true, type: () => String }, mpinSchemeVersion: { required: true, type: () => Number }, deviceId: { required: true, type: () => String }, credentialKey: { required: true, type: () => String }, deviceName: { required: true, type: () => String }, platform: { required: true, type: () => String }, isActive: { required: true, type: () => Boolean }, failedAttempts: { required: true, type: () => Number }, lockedUntil: { required: true, type: () => Date }, lastUsedAt: { required: true, type: () => Date }, user: { required: true, type: () => require("./user.entity").User } };
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
exports.UserDeviceCredential = UserDeviceCredential;
|
|
24
|
+
__decorate([
|
|
25
|
+
(0, typeorm_1.Index)({ unique: true }),
|
|
26
|
+
(0, typeorm_1.Column)(),
|
|
27
|
+
__metadata("design:type", String)
|
|
28
|
+
], UserDeviceCredential.prototype, "hashedCredentialRef", void 0);
|
|
29
|
+
__decorate([
|
|
30
|
+
(0, typeorm_1.Column)(),
|
|
31
|
+
__metadata("design:type", String)
|
|
32
|
+
], UserDeviceCredential.prototype, "hashedMpin", void 0);
|
|
33
|
+
__decorate([
|
|
34
|
+
(0, typeorm_1.Column)(),
|
|
35
|
+
__metadata("design:type", String)
|
|
36
|
+
], UserDeviceCredential.prototype, "mpinScheme", void 0);
|
|
37
|
+
__decorate([
|
|
38
|
+
(0, typeorm_1.Column)({ default: 1 }),
|
|
39
|
+
__metadata("design:type", Number)
|
|
40
|
+
], UserDeviceCredential.prototype, "mpinSchemeVersion", void 0);
|
|
41
|
+
__decorate([
|
|
42
|
+
(0, class_transformer_1.Expose)(),
|
|
43
|
+
(0, typeorm_1.Column)(),
|
|
44
|
+
__metadata("design:type", String)
|
|
45
|
+
], UserDeviceCredential.prototype, "deviceId", void 0);
|
|
46
|
+
__decorate([
|
|
47
|
+
(0, class_transformer_1.Expose)(),
|
|
48
|
+
(0, typeorm_1.Index)({ unique: true }),
|
|
49
|
+
(0, typeorm_1.Column)(),
|
|
50
|
+
__metadata("design:type", String)
|
|
51
|
+
], UserDeviceCredential.prototype, "credentialKey", void 0);
|
|
52
|
+
__decorate([
|
|
53
|
+
(0, class_transformer_1.Expose)(),
|
|
54
|
+
(0, typeorm_1.Column)({ nullable: true }),
|
|
55
|
+
__metadata("design:type", String)
|
|
56
|
+
], UserDeviceCredential.prototype, "deviceName", void 0);
|
|
57
|
+
__decorate([
|
|
58
|
+
(0, class_transformer_1.Expose)(),
|
|
59
|
+
(0, typeorm_1.Column)({ nullable: true }),
|
|
60
|
+
__metadata("design:type", String)
|
|
61
|
+
], UserDeviceCredential.prototype, "platform", void 0);
|
|
62
|
+
__decorate([
|
|
63
|
+
(0, class_transformer_1.Expose)(),
|
|
64
|
+
(0, typeorm_1.Column)({ default: true }),
|
|
65
|
+
__metadata("design:type", Boolean)
|
|
66
|
+
], UserDeviceCredential.prototype, "isActive", void 0);
|
|
67
|
+
__decorate([
|
|
68
|
+
(0, class_transformer_1.Expose)(),
|
|
69
|
+
(0, typeorm_1.Column)({ default: 0 }),
|
|
70
|
+
__metadata("design:type", Number)
|
|
71
|
+
], UserDeviceCredential.prototype, "failedAttempts", void 0);
|
|
72
|
+
__decorate([
|
|
73
|
+
(0, class_transformer_1.Expose)(),
|
|
74
|
+
(0, typeorm_1.Column)({ nullable: true }),
|
|
75
|
+
__metadata("design:type", Date)
|
|
76
|
+
], UserDeviceCredential.prototype, "lockedUntil", void 0);
|
|
77
|
+
__decorate([
|
|
78
|
+
(0, class_transformer_1.Expose)(),
|
|
79
|
+
(0, typeorm_1.Column)({ nullable: true }),
|
|
80
|
+
__metadata("design:type", Date)
|
|
81
|
+
], UserDeviceCredential.prototype, "lastUsedAt", void 0);
|
|
82
|
+
__decorate([
|
|
83
|
+
(0, typeorm_1.ManyToOne)(() => user_entity_1.User, { nullable: false }),
|
|
84
|
+
__metadata("design:type", user_entity_1.User)
|
|
85
|
+
], UserDeviceCredential.prototype, "user", void 0);
|
|
86
|
+
exports.UserDeviceCredential = UserDeviceCredential = __decorate([
|
|
87
|
+
(0, typeorm_1.Entity)("ss_user_device_credential"),
|
|
88
|
+
(0, typeorm_1.Index)(["user", "deviceId"]),
|
|
89
|
+
(0, class_transformer_1.Exclude)()
|
|
90
|
+
], UserDeviceCredential);
|
|
91
|
+
//# sourceMappingURL=user-device-credential.entity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user-device-credential.entity.js","sourceRoot":"","sources":["../../src/entities/user-device-credential.entity.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,yDAAoD;AACpD,mDAA0D;AAC1D,qCAA2D;AAC3D,+CAAqC;AAe9B,IAAM,oBAAoB,GAA1B,MAAM,oBAAqB,SAAQ,4BAAY;;;;CA+GrD,CAAA;AA/GY,oDAAoB;AAS7B;IAFC,IAAA,eAAK,EAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IACvB,IAAA,gBAAM,GAAE;;iEACmB;AAM5B;IADC,IAAA,gBAAM,GAAE;;wDACU;AAKnB;IADC,IAAA,gBAAM,GAAE;;wDACU;AAoBnB;IADC,IAAA,gBAAM,EAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;;+DACG;AAO1B;IAFC,IAAA,0BAAM,GAAE;IACR,IAAA,gBAAM,GAAE;;sDACQ;AAqBjB;IAHC,IAAA,0BAAM,GAAE;IACR,IAAA,eAAK,EAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IACvB,IAAA,gBAAM,GAAE;;2DACa;AAItB;IAFC,IAAA,0BAAM,GAAE;IACR,IAAA,gBAAM,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;wDACR;AAInB;IAFC,IAAA,0BAAM,GAAE;IACR,IAAA,gBAAM,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;sDACV;AAOjB;IAFC,IAAA,0BAAM,GAAE;IACR,IAAA,gBAAM,EAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;;sDACR;AAOlB;IAFC,IAAA,0BAAM,GAAE;IACR,IAAA,gBAAM,EAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;;4DACA;AAIvB;IAFC,IAAA,0BAAM,GAAE;IACR,IAAA,gBAAM,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;8BACd,IAAI;yDAAC;AAIlB;IAFC,IAAA,0BAAM,GAAE;IACR,IAAA,gBAAM,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;8BACf,IAAI;wDAAC;AAYjB;IADC,IAAA,mBAAS,EAAC,GAAG,EAAE,CAAC,kBAAI,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;8BACrC,kBAAI;kDAAC;+BA9GF,oBAAoB;IALhC,IAAA,gBAAM,EAAC,2BAA2B,CAAC;IAGnC,IAAA,eAAK,EAAC,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC3B,IAAA,2BAAO,GAAE;GACG,oBAAoB,CA+GhC","sourcesContent":["import { Exclude, Expose } from \"class-transformer\";\nimport { CommonEntity } from \"src/entities/common.entity\";\nimport { Column, Entity, Index, ManyToOne } from \"typeorm\";\nimport { User } from \"./user.entity\";\n\n/**\n * A per-device MPIN credential.\n *\n * Login presents `credentialRef` (a server-issued opaque handle) plus the MPIN.\n * The handle - not a mobile number or email - is what identifies the account,\n * which is why the login route needs no identifier and offers no user\n * enumeration surface.\n */\n@Entity(\"ss_user_device_credential\")\n// Non-unique: one physical device may legitimately hold credentials for\n// several accounts, and each account setup mints its own row.\n@Index([\"user\", \"deviceId\"])\n@Exclude()\nexport class UserDeviceCredential extends CommonEntity {\n\n // SHA-256 of the opaque handle, and the login lookup key. Never exposed:\n // the raw handle is returned to the client once at setup and never stored.\n // SHA-256 rather than bcrypt because the handle is 256 bits of randomness -\n // there is nothing to brute-force, so a slow hash would only add latency.\n // Same treatment as UserApiKey.hashedKey.\n @Index({ unique: true })\n @Column()\n hashedCredentialRef: string;\n\n // bcrypt hash of the MPIN, via HashingService. Never exposed - same\n // treatment as User.password. Slow hashing is warranted here: a 4-6 digit\n // secret is exactly the low-entropy case bcrypt exists for.\n @Column()\n hashedMpin: string;\n\n // Mirrors User.passwordScheme / passwordSchemeVersion so\n // HashingService.needsRehash can upgrade the hash on a successful login.\n @Column()\n mpinScheme: string;\n\n /**\n * The hashing *policy* version this row was hashed under - not a version of\n * MPIN itself. It comes from `HashingService.currentVersion()`, which\n * `BcryptService` currently returns as **2**, so freshly created rows read\n * 2, exactly as `ss_user.password_scheme_version` does.\n *\n * It matters because `BcryptService.normalize` applies the configured\n * pepper only when `version >= 2`. Storing the version per row means an\n * older hash still verifies after the policy changes: `compare()` uses the\n * version the row was written with, and `needsRehash()` upgrades it on the\n * next successful login.\n *\n * The `default: 1` is inherited from the `User` precedent and is never\n * reached, since every write path sets this explicitly. Note it would be\n * *wrong* if it ever were: a row hashed at 2 but recorded as 1 would be\n * compared without the pepper and could never authenticate.\n */\n @Column({ default: 1 })\n mpinSchemeVersion: number;\n\n // Client-supplied, stable for the physical device. Used for grouping and\n // the device-management UI only - never a lookup key. Deliberately NOT\n // unique: several accounts on one device share a deviceId.\n @Expose()\n @Column()\n deviceId: string;\n\n /**\n * Human-readable natural key - `<username>-<deviceId>` - unique per row.\n *\n * Neither column alone can serve as the model's user key: `deviceId` is\n * shared by every account on a device, and `deviceName` is nullable.\n * Combining them is unique in both directions - one user across many\n * devices, and many users on one device.\n *\n * Populated by MpinService rather than declared as a `computed` field in\n * the metadata manifest. Computed fields are evaluated by\n * ComputedFieldCrudManager on the generic CRUD path (`crud.service.ts`),\n * which this service bypasses by writing through the repository directly,\n * so a computed declaration would silently leave this null. It is also\n * beyond ConcatComputedFieldProvider, which resolves `dto[field]` flatly\n * within one model and cannot reach `username` across the user relation.\n */\n @Expose()\n @Index({ unique: true })\n @Column()\n credentialKey: string;\n\n @Expose()\n @Column({ nullable: true })\n deviceName: string;\n\n @Expose()\n @Column({ nullable: true })\n platform: string;\n\n // Revocation is a soft-delete: the row survives so that a correct MPIN can\n // be answered with \"this device was removed\" rather than a baffling\n // \"incorrect MPIN\". Only active rows count towards mpinMaxDevicesPerUser.\n @Expose()\n @Column({ default: true })\n isActive: boolean;\n\n // Cumulative, and reset only on a successful login - never when a lockout\n // expires. That is what makes the second threshold detectable without a\n // separate lockout counter.\n @Expose()\n @Column({ default: 0 })\n failedAttempts: number;\n\n @Expose()\n @Column({ nullable: true })\n lockedUntil: Date;\n\n @Expose()\n @Column({ nullable: true })\n lastUsedAt: Date;\n\n // Deliberately no inverse property on User. Nothing needs\n // `user.deviceCredentials`, and leaving the most widely referenced entity\n // in the system untouched keeps this feature purely additive.\n //\n // `nullable: false` because TypeORM makes relations nullable by default,\n // which would let a credential exist with no owner. Such a row could never\n // authenticate - loginWithMpin rejects it - so it would simply be dead\n // data, but the database should refuse it outright. This also keeps the\n // column honest against the metadata manifest, which declares it required.\n @ManyToOne(() => User, { nullable: false })\n user: User;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"solid-core-error-codes-provider.service.d.ts","sourceRoot":"","sources":["../../src/helpers/solid-core-error-codes-provider.service.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAG1E,qBAEa,2BAA4B,YAAW,kBAAkB;IAClE,IAAI,IAAI,MAAM;IAId,KAAK,IAAI,aAAa,CAAC,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"solid-core-error-codes-provider.service.d.ts","sourceRoot":"","sources":["../../src/helpers/solid-core-error-codes-provider.service.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAG1E,qBAEa,2BAA4B,YAAW,kBAAkB;IAClE,IAAI,IAAI,MAAM;IAId,KAAK,IAAI,aAAa,CAAC,SAAS,CAAC;IA6HjC,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS;CAI/C"}
|
|
@@ -34,6 +34,51 @@ let SolidCoreErrorCodesProvider = class SolidCoreErrorCodesProvider {
|
|
|
34
34
|
httpStatus: 401,
|
|
35
35
|
},
|
|
36
36
|
},
|
|
37
|
+
{
|
|
38
|
+
code: 'solidx-mpin-locked',
|
|
39
|
+
priority: 120,
|
|
40
|
+
match: (txt) => txt.includes(error_messages_1.ERROR_MESSAGES.MPIN_LOCKED.toLowerCase()),
|
|
41
|
+
meta: {
|
|
42
|
+
message: error_messages_1.ERROR_MESSAGES.MPIN_LOCKED,
|
|
43
|
+
httpStatus: 401,
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
code: 'solidx-mpin-revoked',
|
|
48
|
+
priority: 120,
|
|
49
|
+
match: (txt) => txt.includes(error_messages_1.ERROR_MESSAGES.MPIN_REVOKED.toLowerCase()),
|
|
50
|
+
meta: {
|
|
51
|
+
message: error_messages_1.ERROR_MESSAGES.MPIN_REVOKED,
|
|
52
|
+
httpStatus: 401,
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
code: 'solidx-mpin-invalid',
|
|
57
|
+
priority: 120,
|
|
58
|
+
match: (txt) => txt.includes(error_messages_1.ERROR_MESSAGES.MPIN_INVALID.toLowerCase()),
|
|
59
|
+
meta: {
|
|
60
|
+
message: error_messages_1.ERROR_MESSAGES.MPIN_INVALID,
|
|
61
|
+
httpStatus: 401,
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
code: 'solidx-mpin-too-predictable',
|
|
66
|
+
priority: 120,
|
|
67
|
+
match: (txt) => txt.includes(error_messages_1.ERROR_MESSAGES.MPIN_TOO_PREDICTABLE.toLowerCase()),
|
|
68
|
+
meta: {
|
|
69
|
+
message: error_messages_1.ERROR_MESSAGES.MPIN_TOO_PREDICTABLE,
|
|
70
|
+
httpStatus: 400,
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
code: 'solidx-mpin-format-invalid',
|
|
75
|
+
priority: 120,
|
|
76
|
+
match: (txt) => txt.includes(error_messages_1.ERROR_MESSAGES.MPIN_FORMAT_INVALID.toLowerCase()),
|
|
77
|
+
meta: {
|
|
78
|
+
message: error_messages_1.ERROR_MESSAGES.MPIN_FORMAT_INVALID,
|
|
79
|
+
httpStatus: 400,
|
|
80
|
+
},
|
|
81
|
+
},
|
|
37
82
|
{
|
|
38
83
|
code: 'solidx-mcp-server-unavailable',
|
|
39
84
|
priority: 100,
|