@capgo/capacitor-autofill-save-password 7.0.1

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.
@@ -0,0 +1,17 @@
1
+ require 'json'
2
+
3
+ package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
4
+
5
+ Pod::Spec.new do |s|
6
+ s.name = 'CapgoCapacitorAutofillSavePassword'
7
+ s.version = package['version']
8
+ s.summary = package['description']
9
+ s.license = package['license']
10
+ s.homepage = package['repository']['url']
11
+ s.author = package['author']
12
+ s.source = { :git => package['repository']['url'], :tag => s.version.to_s }
13
+ s.source_files = 'ios/Sources/**/*.{swift,h,m,c,cc,mm,cpp}'
14
+ s.ios.deployment_target = '14.0'
15
+ s.dependency 'Capacitor'
16
+ s.swift_version = '5.1'
17
+ end
package/Package.swift ADDED
@@ -0,0 +1,28 @@
1
+ // swift-tools-version: 5.9
2
+ import PackageDescription
3
+
4
+ let package = Package(
5
+ name: "CapgoCapacitorAutofillSavePassword",
6
+ platforms: [.iOS(.v14)],
7
+ products: [
8
+ .library(
9
+ name: "CapgoCapacitorAutofillSavePassword",
10
+ targets: ["SavePasswordPlugin"])
11
+ ],
12
+ dependencies: [
13
+ .package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", from: "7.0.0")
14
+ ],
15
+ targets: [
16
+ .target(
17
+ name: "SavePasswordPlugin",
18
+ dependencies: [
19
+ .product(name: "Capacitor", package: "capacitor-swift-pm"),
20
+ .product(name: "Cordova", package: "capacitor-swift-pm")
21
+ ],
22
+ path: "ios/Sources/SavePasswordPlugin"),
23
+ .testTarget(
24
+ name: "SavePasswordPluginTests",
25
+ dependencies: ["SavePasswordPlugin"],
26
+ path: "ios/Tests/SavePasswordPluginTests")
27
+ ]
28
+ )
package/README.md ADDED
@@ -0,0 +1,89 @@
1
+ # @capgo/capacitor-autofill-save-password
2
+
3
+ Prompt to display dialog for saving password to keychain from webview app
4
+
5
+ <a href="https://capgo.app/"><img src='https://raw.githubusercontent.com/Cap-go/capgo/main/assets/capgo_banner.png' alt='Capgo - Instant updates for capacitor'/></a>
6
+
7
+ <div align="center">
8
+ <h2><a href="https://capgo.app/?ref=plugin"> ➡️ Get Instant updates for your App with Capgo 🚀</a></h2>
9
+ <h2><a href="https://capgo.app/consulting/?ref=plugin"> Fix your annoying bug now, Hire a Capacitor expert 💪</a></h2>
10
+ </div>
11
+
12
+ Fork of original plugin to work with Capacitor 7
13
+
14
+ ## Install
15
+
16
+ ```bash
17
+ npm install @capgo/capacitor-autofill-save-password
18
+ npx cap sync
19
+ ```
20
+
21
+ ## Prerequisite
22
+ You must set up your app’s associated domains. To learn how to set up your app’s associated domains, see [Supporting Associated Domains](https://developer.apple.com/documentation/safariservices/supporting_associated_domains) in Apple Developer document.
23
+
24
+ Then add in your `App.entitlements`
25
+
26
+ ```xml
27
+ <key>com.apple.developer.associated-domains</key>
28
+ <array>
29
+ <string>webcredentials:YOURDOMAIN</string>
30
+ </array>
31
+ ```
32
+
33
+ To associate your domain to your app.
34
+
35
+ ## How to use
36
+ ```ts
37
+ import { Capacitor } from '@capacitor/core';
38
+ import { SavePassword } from '@capgo/capacitor-autofill-save-password';
39
+
40
+ login(username: string, password: string) {
41
+ // your login logic here
42
+
43
+ SavePassword.promptDialog({
44
+ username: username,
45
+ password: password,
46
+ })
47
+ .then(() => console.log('promptDialog success'))
48
+ .catch((err) => console.error('promptDialog failure', err));
49
+ }
50
+ ```
51
+
52
+ ## API
53
+
54
+ <docgen-index>
55
+
56
+ * [`promptDialog(...)`](#promptdialog)
57
+ * [Interfaces](#interfaces)
58
+
59
+ </docgen-index>
60
+
61
+ <docgen-api>
62
+ <!--Update the source file JSDoc comments and rerun docgen to update the docs below-->
63
+
64
+ ### promptDialog(...)
65
+
66
+ ```typescript
67
+ promptDialog(options: Options) => Promise<void>
68
+ ```
69
+
70
+ Save a password to the keychain.
71
+
72
+ | Param | Type | Description |
73
+ | ------------- | ------------------------------------------- | ------------------------------- |
74
+ | **`options`** | <code><a href="#options">Options</a></code> | - The options for the password. |
75
+
76
+ --------------------
77
+
78
+
79
+ ### Interfaces
80
+
81
+
82
+ #### Options
83
+
84
+ | Prop | Type | Description |
85
+ | -------------- | ------------------- | --------------------- |
86
+ | **`username`** | <code>string</code> | The username to save. |
87
+ | **`password`** | <code>string</code> | The password to save. |
88
+
89
+ </docgen-api>
@@ -0,0 +1,61 @@
1
+ ext {
2
+ junitVersion = project.hasProperty('junitVersion') ? rootProject.ext.junitVersion : '4.13.2'
3
+ androidxAppCompatVersion = project.hasProperty('androidxAppCompatVersion') ? rootProject.ext.androidxAppCompatVersion : '1.7.0'
4
+ androidxJunitVersion = project.hasProperty('androidxJunitVersion') ? rootProject.ext.androidxJunitVersion : '1.2.1'
5
+ androidxEspressoCoreVersion = project.hasProperty('androidxEspressoCoreVersion') ? rootProject.ext.androidxEspressoCoreVersion : '3.6.1'
6
+ }
7
+
8
+ buildscript {
9
+ repositories {
10
+ google()
11
+ mavenCentral()
12
+ }
13
+ dependencies {
14
+ classpath 'com.android.tools.build:gradle:8.7.2'
15
+ }
16
+ }
17
+
18
+ apply plugin: 'com.android.library'
19
+
20
+ android {
21
+ namespace "ee.forgr.autofill_password"
22
+ compileSdk project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion : 35
23
+ defaultConfig {
24
+ minSdkVersion project.hasProperty('minSdkVersion') ? rootProject.ext.minSdkVersion : 23
25
+ targetSdkVersion project.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion : 35
26
+ versionCode 1
27
+ versionName "1.0"
28
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
29
+ }
30
+ buildTypes {
31
+ release {
32
+ minifyEnabled false
33
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
34
+ }
35
+ }
36
+ lintOptions {
37
+ abortOnError false
38
+ }
39
+ compileOptions {
40
+ sourceCompatibility JavaVersion.VERSION_21
41
+ targetCompatibility JavaVersion.VERSION_21
42
+ }
43
+ }
44
+
45
+ repositories {
46
+ google()
47
+ mavenCentral()
48
+ }
49
+
50
+
51
+ dependencies {
52
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
53
+ implementation project(':capacitor-android')
54
+ implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"
55
+ implementation(libs.androidx.credentials)
56
+ implementation(libs.androidx.credentials.play.services.auth)
57
+ // implementation 'androidx.credentials:credentials:1.5.0'
58
+ testImplementation "junit:junit:$junitVersion"
59
+ androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
60
+ androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
61
+ }
@@ -0,0 +1,2 @@
1
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android">
2
+ </manifest>
@@ -0,0 +1,78 @@
1
+ package ee.forgr.autofill_password;
2
+
3
+ import com.getcapacitor.JSObject;
4
+ import com.getcapacitor.Plugin;
5
+ import com.getcapacitor.PluginCall;
6
+ import com.getcapacitor.PluginMethod;
7
+ import com.getcapacitor.annotation.CapacitorPlugin;
8
+ import android.util.Log;
9
+ import android.os.CancellationSignal;
10
+ import androidx.credentials.CredentialManager;
11
+ import androidx.credentials.CredentialManagerCallback;
12
+ import androidx.credentials.CreatePasswordRequest;
13
+ import androidx.credentials.CreateCredentialResponse;
14
+ import androidx.credentials.exceptions.CreateCredentialException;
15
+ import java.util.concurrent.Executor;
16
+
17
+ @CapacitorPlugin(name = "SavePassword")
18
+ public class SavePasswordPlugin extends Plugin {
19
+
20
+ private static final String TAG = "SavePasswordPlugin";
21
+
22
+ @PluginMethod
23
+ public void promptDialog(PluginCall call) {
24
+ String username = call.getString("username");
25
+ String password = call.getString("password");
26
+
27
+ if (username == null || username.isEmpty()) {
28
+ call.reject("Username cannot be empty.");
29
+ Log.w(TAG, "Username was null or empty.");
30
+ return;
31
+ }
32
+
33
+ if (password == null) {
34
+ call.reject("Password cannot be null. Provide an empty string if the password is meant to be empty.");
35
+ Log.w(TAG, "Password was null.");
36
+ return;
37
+ }
38
+
39
+ if (getActivity() == null) {
40
+ call.reject("Activity is not available to show dialog.");
41
+ Log.e(TAG, "Activity was null, cannot access CredentialManager.");
42
+ return;
43
+ }
44
+
45
+ // Build the CreatePasswordRequest
46
+ CreatePasswordRequest createPasswordRequest = new CreatePasswordRequest(username, password);
47
+
48
+ // Get the CredentialManager instance
49
+ CredentialManager credentialManager = CredentialManager.create(getActivity());
50
+
51
+ // Set up executor and cancellation signal
52
+ Executor executor = getActivity().getMainExecutor();
53
+ CancellationSignal cancellationSignal = new CancellationSignal();
54
+
55
+ credentialManager.createCredentialAsync(
56
+ getActivity(),
57
+ createPasswordRequest,
58
+ cancellationSignal,
59
+ executor,
60
+ new CredentialManagerCallback<CreateCredentialResponse, CreateCredentialException>() {
61
+ @Override
62
+ public void onResult(CreateCredentialResponse result) {
63
+ JSObject response = new JSObject();
64
+ response.put("prompted", true);
65
+ Log.d(TAG, "Password save prompt completed successfully.");
66
+ call.resolve(response);
67
+ }
68
+
69
+ @Override
70
+ public void onError(CreateCredentialException e) {
71
+ String errorMessage = "Failed to save password credential: " + e.getMessage();
72
+ Log.e(TAG, errorMessage, e);
73
+ call.reject(errorMessage, e);
74
+ }
75
+ }
76
+ );
77
+ }
78
+ }
File without changes
package/dist/docs.json ADDED
@@ -0,0 +1,88 @@
1
+ {
2
+ "api": {
3
+ "name": "SavePasswordPlugin",
4
+ "slug": "savepasswordplugin",
5
+ "docs": "",
6
+ "tags": [
7
+ {
8
+ "text": "SavePasswordPlugin",
9
+ "name": "interface"
10
+ },
11
+ {
12
+ "text": "Capacitor plugin for saving passwords to the keychain.",
13
+ "name": "description"
14
+ }
15
+ ],
16
+ "methods": [
17
+ {
18
+ "name": "promptDialog",
19
+ "signature": "(options: Options) => Promise<void>",
20
+ "parameters": [
21
+ {
22
+ "name": "options",
23
+ "docs": "- The options for the password.",
24
+ "type": "Options"
25
+ }
26
+ ],
27
+ "returns": "Promise<void>",
28
+ "tags": [
29
+ {
30
+ "name": "param",
31
+ "text": "options - The options for the password."
32
+ },
33
+ {
34
+ "name": "returns",
35
+ "text": "Success status"
36
+ },
37
+ {
38
+ "name": "example",
39
+ "text": "await SavePassword.promptDialog({\n username: 'your-username',\n password: 'your-password'\n});"
40
+ }
41
+ ],
42
+ "docs": "Save a password to the keychain.",
43
+ "complexTypes": [
44
+ "Options"
45
+ ],
46
+ "slug": "promptdialog"
47
+ }
48
+ ],
49
+ "properties": []
50
+ },
51
+ "interfaces": [
52
+ {
53
+ "name": "Options",
54
+ "slug": "options",
55
+ "docs": "",
56
+ "tags": [
57
+ {
58
+ "text": "Options",
59
+ "name": "interface"
60
+ },
61
+ {
62
+ "text": "The options for the prompt.",
63
+ "name": "description"
64
+ }
65
+ ],
66
+ "methods": [],
67
+ "properties": [
68
+ {
69
+ "name": "username",
70
+ "tags": [],
71
+ "docs": "The username to save.",
72
+ "complexTypes": [],
73
+ "type": "string"
74
+ },
75
+ {
76
+ "name": "password",
77
+ "tags": [],
78
+ "docs": "The password to save.",
79
+ "complexTypes": [],
80
+ "type": "string"
81
+ }
82
+ ]
83
+ }
84
+ ],
85
+ "enums": [],
86
+ "typeAliases": [],
87
+ "pluginConfigs": []
88
+ }
@@ -0,0 +1,31 @@
1
+ /**
2
+ * @interface Options
3
+ * @description The options for the prompt.
4
+ */
5
+ export interface Options {
6
+ /**
7
+ * The username to save.
8
+ */
9
+ username: string;
10
+ /**
11
+ * The password to save.
12
+ */
13
+ password: string;
14
+ }
15
+ /**
16
+ * @interface SavePasswordPlugin
17
+ * @description Capacitor plugin for saving passwords to the keychain.
18
+ */
19
+ export interface SavePasswordPlugin {
20
+ /**
21
+ * Save a password to the keychain.
22
+ * @param {Options} options - The options for the password.
23
+ * @returns {Promise<void>} Success status
24
+ * @example
25
+ * await SavePassword.promptDialog({
26
+ * username: 'your-username',
27
+ * password: 'your-password'
28
+ * });
29
+ */
30
+ promptDialog(options: Options): Promise<void>;
31
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=definitions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * @interface Options\n * @description The options for the prompt.\n */\nexport interface Options {\n /**\n * The username to save.\n */\n username: string;\n /**\n * The password to save.\n */\n password: string;\n}\n\n/**\n * @interface SavePasswordPlugin\n * @description Capacitor plugin for saving passwords to the keychain.\n */\nexport interface SavePasswordPlugin {\n /**\n * Save a password to the keychain.\n * @param {Options} options - The options for the password.\n * @returns {Promise<void>} Success status\n * @example\n * await SavePassword.promptDialog({\n * username: 'your-username',\n * password: 'your-password'\n * });\n */\n promptDialog(options: Options): Promise<void>;\n}\n"]}
@@ -0,0 +1,4 @@
1
+ import type { SavePasswordPlugin } from './definitions';
2
+ declare const SavePassword: SavePasswordPlugin;
3
+ export * from './definitions';
4
+ export { SavePassword };
@@ -0,0 +1,7 @@
1
+ import { registerPlugin } from '@capacitor/core';
2
+ const SavePassword = registerPlugin('SavePassword', {
3
+ web: () => import('./web').then((m) => new m.SavePasswordWeb()),
4
+ });
5
+ export * from './definitions';
6
+ export { SavePassword };
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAIjD,MAAM,YAAY,GAAG,cAAc,CAAqB,cAAc,EAAE;IACtE,GAAG,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,eAAe,EAAE,CAAC;CAChE,CAAC,CAAC;AAEH,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAE,YAAY,EAAE,CAAC","sourcesContent":["import { registerPlugin } from '@capacitor/core';\n\nimport type { SavePasswordPlugin } from './definitions';\n\nconst SavePassword = registerPlugin<SavePasswordPlugin>('SavePassword', {\n web: () => import('./web').then((m) => new m.SavePasswordWeb()),\n});\n\nexport * from './definitions';\nexport { SavePassword };\n"]}
@@ -0,0 +1,5 @@
1
+ import { WebPlugin } from '@capacitor/core';
2
+ import type { Options, SavePasswordPlugin } from './definitions';
3
+ export declare class SavePasswordWeb extends WebPlugin implements SavePasswordPlugin {
4
+ promptDialog(options: Options): Promise<void>;
5
+ }
@@ -0,0 +1,7 @@
1
+ import { WebPlugin } from '@capacitor/core';
2
+ export class SavePasswordWeb extends WebPlugin {
3
+ async promptDialog(options) {
4
+ throw new Error("Not implemented on web" + JSON.stringify(options));
5
+ }
6
+ }
7
+ //# sourceMappingURL=web.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAI5C,MAAM,OAAO,eAAgB,SAAQ,SAAS;IAC5C,KAAK,CAAC,YAAY,CAAC,OAAgB;QACjC,MAAM,IAAI,KAAK,CAAC,wBAAwB,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;IACtE,CAAC;CACF","sourcesContent":["import { WebPlugin } from '@capacitor/core';\n\nimport type { Options, SavePasswordPlugin } from './definitions';\n\nexport class SavePasswordWeb extends WebPlugin implements SavePasswordPlugin {\n async promptDialog(options: Options): Promise<void> {\n throw new Error(\"Not implemented on web\" + JSON.stringify(options));\n }\n}\n"]}
@@ -0,0 +1,21 @@
1
+ 'use strict';
2
+
3
+ var core = require('@capacitor/core');
4
+
5
+ const SavePassword = core.registerPlugin('SavePassword', {
6
+ web: () => Promise.resolve().then(function () { return web; }).then((m) => new m.SavePasswordWeb()),
7
+ });
8
+
9
+ class SavePasswordWeb extends core.WebPlugin {
10
+ async promptDialog(options) {
11
+ throw new Error("Not implemented on web" + JSON.stringify(options));
12
+ }
13
+ }
14
+
15
+ var web = /*#__PURE__*/Object.freeze({
16
+ __proto__: null,
17
+ SavePasswordWeb: SavePasswordWeb
18
+ });
19
+
20
+ exports.SavePassword = SavePassword;
21
+ //# sourceMappingURL=plugin.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.cjs.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nconst SavePassword = registerPlugin('SavePassword', {\n web: () => import('./web').then((m) => new m.SavePasswordWeb()),\n});\nexport * from './definitions';\nexport { SavePassword };\n//# sourceMappingURL=index.js.map","import { WebPlugin } from '@capacitor/core';\nexport class SavePasswordWeb extends WebPlugin {\n async promptDialog(options) {\n throw new Error(\"Not implemented on web\" + JSON.stringify(options));\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":";;;;AACK,MAAC,YAAY,GAAGA,mBAAc,CAAC,cAAc,EAAE;AACpD,IAAI,GAAG,EAAE,MAAM,mDAAe,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,eAAe,EAAE,CAAC;AACnE,CAAC;;ACFM,MAAM,eAAe,SAASC,cAAS,CAAC;AAC/C,IAAI,MAAM,YAAY,CAAC,OAAO,EAAE;AAChC,QAAQ,MAAM,IAAI,KAAK,CAAC,wBAAwB,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;AAC3E;AACA;;;;;;;;;"}
package/dist/plugin.js ADDED
@@ -0,0 +1,24 @@
1
+ var capacitorSavePassword = (function (exports, core) {
2
+ 'use strict';
3
+
4
+ const SavePassword = core.registerPlugin('SavePassword', {
5
+ web: () => Promise.resolve().then(function () { return web; }).then((m) => new m.SavePasswordWeb()),
6
+ });
7
+
8
+ class SavePasswordWeb extends core.WebPlugin {
9
+ async promptDialog(options) {
10
+ throw new Error("Not implemented on web" + JSON.stringify(options));
11
+ }
12
+ }
13
+
14
+ var web = /*#__PURE__*/Object.freeze({
15
+ __proto__: null,
16
+ SavePasswordWeb: SavePasswordWeb
17
+ });
18
+
19
+ exports.SavePassword = SavePassword;
20
+
21
+ return exports;
22
+
23
+ })({}, capacitorExports);
24
+ //# sourceMappingURL=plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nconst SavePassword = registerPlugin('SavePassword', {\n web: () => import('./web').then((m) => new m.SavePasswordWeb()),\n});\nexport * from './definitions';\nexport { SavePassword };\n//# sourceMappingURL=index.js.map","import { WebPlugin } from '@capacitor/core';\nexport class SavePasswordWeb extends WebPlugin {\n async promptDialog(options) {\n throw new Error(\"Not implemented on web\" + JSON.stringify(options));\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":";;;AACK,UAAC,YAAY,GAAGA,mBAAc,CAAC,cAAc,EAAE;IACpD,IAAI,GAAG,EAAE,MAAM,mDAAe,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,eAAe,EAAE,CAAC;IACnE,CAAC;;ICFM,MAAM,eAAe,SAASC,cAAS,CAAC;IAC/C,IAAI,MAAM,YAAY,CAAC,OAAO,EAAE;IAChC,QAAQ,MAAM,IAAI,KAAK,CAAC,wBAAwB,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IAC3E;IACA;;;;;;;;;;;;;;;"}
@@ -0,0 +1,53 @@
1
+ import Foundation
2
+ import Capacitor
3
+
4
+ /**
5
+ * Please read the Capacitor iOS Plugin Development Guide
6
+ * here: https://capacitorjs.com/docs/plugins/ios
7
+ */
8
+ @objc(SavePasswordPlugin)
9
+ public class SavePasswordPlugin: CAPPlugin, CAPBridgedPlugin {
10
+ public let identifier = "SavePasswordPlugin"
11
+
12
+ public let jsName = "SavePassword"
13
+ public let pluginMethods: [CAPPluginMethod] = [
14
+ CAPPluginMethod(name: "promptDialog", returnType: CAPPluginReturnPromise)
15
+ ]
16
+
17
+ @objc func promptDialog(_ call: CAPPluginCall) {
18
+ DispatchQueue.main.async {
19
+ let loginScreen = LoginScreenViewController()
20
+ loginScreen.usernameTextField.text = call.getString("username") ?? ""
21
+ loginScreen.passwordTextField.text = call.getString("password") ?? ""
22
+ self.bridge?.webView?.addSubview(loginScreen.view)
23
+ loginScreen.view.removeFromSuperview()
24
+ call.resolve()
25
+ }
26
+ }
27
+ }
28
+
29
+ class LoginScreenViewController: UIViewController {
30
+ let usernameTextField: UITextField = {
31
+ let textField = UITextField()
32
+ textField.frame.size.width = 1
33
+ textField.frame.size.height = 1
34
+ textField.textContentType = .username
35
+ return textField
36
+ }()
37
+
38
+ let passwordTextField: UITextField = {
39
+ let textField = UITextField()
40
+ textField.frame.size.width = 1
41
+ textField.frame.size.height = 1
42
+ textField.textContentType = .newPassword
43
+ return textField
44
+ }()
45
+
46
+ override func viewDidLoad() {
47
+ super.viewDidLoad()
48
+ view.frame = CGRect(x: 0, y: 0, width: 0, height: 0)
49
+ view.addSubview(usernameTextField)
50
+ view.addSubview(passwordTextField)
51
+ usernameTextField.becomeFirstResponder()
52
+ }
53
+ }
@@ -0,0 +1,15 @@
1
+ import XCTest
2
+ @testable import SavePasswordPlugin
3
+
4
+ class SavePasswordTests: XCTestCase {
5
+ func testEcho() {
6
+ // This is an example of a functional test case for a plugin.
7
+ // Use XCTAssert and related functions to verify your tests produce the correct results.
8
+
9
+ let implementation = SavePassword()
10
+ let value = "Hello, World!"
11
+ let result = implementation.echo(value)
12
+
13
+ XCTAssertEqual(value, result)
14
+ }
15
+ }
package/package.json ADDED
@@ -0,0 +1,85 @@
1
+ {
2
+ "name": "@capgo/capacitor-autofill-save-password",
3
+ "version": "7.0.1",
4
+ "description": "Prompt to display dialog for saving password to keychain from webview app",
5
+ "main": "dist/plugin.cjs.js",
6
+ "module": "dist/esm/index.js",
7
+ "types": "dist/esm/index.d.ts",
8
+ "unpkg": "dist/plugin.js",
9
+ "files": [
10
+ "android/src/main/",
11
+ "android/build.gradle",
12
+ "dist/",
13
+ "ios/Sources",
14
+ "ios/Tests",
15
+ "Package.swift",
16
+ "CapgoCapacitorAutofillSavePassword.podspec"
17
+ ],
18
+ "author": "Martin Donadieu <martin@capgo.app>",
19
+ "license": "MIT",
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "git+https://github.com/Cap-go/capacitor-autofill-save-password.git"
23
+ },
24
+ "bugs": {
25
+ "url": "https://github.com/Cap-go/capacitor-autofill-save-password/issues"
26
+ },
27
+ "keywords": [
28
+ "capacitor",
29
+ "plugin",
30
+ "native",
31
+ "autofill",
32
+ "save",
33
+ "password",
34
+ "ios",
35
+ "android"
36
+ ],
37
+ "scripts": {
38
+ "verify": "npm run verify:ios && npm run verify:android && npm run verify:web",
39
+ "verify:ios": "xcodebuild -scheme CapgoCapacitorAutofillSavePassword -destination generic/platform=iOS",
40
+ "verify:android": "cd android && ./gradlew clean build test && cd ..",
41
+ "verify:web": "npm run build",
42
+ "lint": "npm run eslint && npm run prettier -- --check && npm run swiftlint -- lint",
43
+ "fmt": "npm run eslint -- --fix && npm run prettier -- --write && npm run swiftlint -- --fix --format",
44
+ "eslint": "eslint . --ext ts",
45
+ "prettier": "prettier \"**/*.{css,html,ts,js,java}\" --plugin=prettier-plugin-java",
46
+ "swiftlint": "node-swiftlint",
47
+ "docgen": "docgen --api SavePasswordPlugin --output-readme README.md --output-json dist/docs.json",
48
+ "build": "npm run clean && npm run docgen && tsc && rollup -c rollup.config.mjs",
49
+ "clean": "rimraf ./dist",
50
+ "watch": "tsc --watch",
51
+ "prepublishOnly": "npm run build"
52
+ },
53
+ "devDependencies": {
54
+ "@capacitor/android": "^7.0.0",
55
+ "@capacitor/core": "^7.0.0",
56
+ "@capacitor/docgen": "^0.3.0",
57
+ "@capacitor/ios": "^7.0.0",
58
+ "@ionic/eslint-config": "^0.4.0",
59
+ "@ionic/prettier-config": "^4.0.0",
60
+ "@ionic/swiftlint-config": "^2.0.0",
61
+ "eslint": "^8.57.0",
62
+ "prettier": "^3.4.2",
63
+ "prettier-plugin-java": "^2.6.6",
64
+ "rimraf": "^6.0.1",
65
+ "rollup": "^4.30.1",
66
+ "swiftlint": "^2.0.0",
67
+ "typescript": "~4.1.5"
68
+ },
69
+ "peerDependencies": {
70
+ "@capacitor/core": ">=7.0.0"
71
+ },
72
+ "prettier": "@ionic/prettier-config",
73
+ "swiftlint": "@ionic/swiftlint-config",
74
+ "eslintConfig": {
75
+ "extends": "@ionic/eslint-config/recommended"
76
+ },
77
+ "capacitor": {
78
+ "ios": {
79
+ "src": "ios"
80
+ },
81
+ "android": {
82
+ "src": "android"
83
+ }
84
+ }
85
+ }