diff --git a/README.md b/README.md index ec66d5e..e114a85 100644 --- a/README.md +++ b/README.md @@ -1,33 +1,33 @@ +![MispBump Logo](./images/mispbump.svg) + + # MISPBump -With MISPBump it is easy to share events on your MISP instance with other instances. Instead of generating organisations, sync-users and sync-servers you scan only two QR-Codes and the job is done. +With MISPBump it is easy to synchronise events on different MISP instances. Instead of generating organisations, sync-users and sync-servers you only have to scan two QR-Codes and you are ready for syncing. # Security A key agreement is realized with Diffie Hellman (Elliptic Curve 256 Bit), sensible data is encrypted with AES. -(how are credentials stored in app, keystore?) - +TODO: how are credentials stored in app, keystore? # How does it work? -1. Main screen (no changes) - 1. Gather your organisation information from your MISP instance -![Gather Information](./Screenshots/sync-profile.png) +![Gather Information](./images/Screenshots/sync-profile.png) 1. Scan your partners generated public key and at the same time share yours -![Scan Public Key](./Screenshots/scan-pub-key.png) +![Scan Public Key](./images/Screenshots/scan-pub-key.png) 2. Validate the public key you scanned -![Public Key Received](./Screenshots/pub-key-received.png) +![Public Key Received](./images/Screenshots/pub-key-received.png) 3. After another scan the information you need to synchronise is securely transmitted to your phone -![Secure Info Received](./Screenshots/org-info-received.png) +![Secure Info Received](./images/Screenshots/org-info-received.png) 4. Upload the information to your own MISP instance -![Upload](./Screenshots/upload.png) +![Upload](./images/Screenshots/upload.png) 5. That's it! You are ready to share events across your instances -![Main Screen](./Screenshots/main.png) +![Main Screen](./images/Screenshots/main.png) diff --git a/Screenshots/sync-profile.png b/Screenshots/sync-profile.png deleted file mode 100644 index 90a96d5..0000000 Binary files a/Screenshots/sync-profile.png and /dev/null differ diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0a13b64..038b5da 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,9 +7,9 @@ - diff --git a/app/src/main/java/de/overview/wg/its/mispauth/CredentialsActivity.java b/app/src/main/java/de/overview/wg/its/mispauth/CredentialsActivity.java index 89dcc6e..67a4e81 100644 --- a/app/src/main/java/de/overview/wg/its/mispauth/CredentialsActivity.java +++ b/app/src/main/java/de/overview/wg/its/mispauth/CredentialsActivity.java @@ -10,6 +10,9 @@ import android.support.design.widget.Snackbar; import android.support.design.widget.TextInputLayout; import android.support.v7.app.AlertDialog; import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.DefaultItemAnimator; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; import android.support.v7.widget.Toolbar; import android.text.Editable; import android.text.TextWatcher; @@ -22,15 +25,20 @@ import android.widget.CompoundButton; import android.widget.ProgressBar; import android.widget.TextView; import com.android.volley.VolleyError; +import de.overview.wg.its.mispauth.adapter.OrganisationInfoEntryAdapter; import de.overview.wg.its.mispauth.auxiliary.PreferenceManager; import de.overview.wg.its.mispauth.auxiliary.ReadableError; import de.overview.wg.its.mispauth.cam.DialogFactory; import de.overview.wg.its.mispauth.model.Organisation; +import de.overview.wg.its.mispauth.model.StringPair; import de.overview.wg.its.mispauth.model.User; import de.overview.wg.its.mispauth.network.MispRequest; import org.json.JSONException; import org.json.JSONObject; +import java.util.ArrayList; +import java.util.List; + @SuppressWarnings("ConstantConditions") @SuppressLint("SetTextI18n") public class CredentialsActivity extends AppCompatActivity implements View.OnClickListener { @@ -42,12 +50,16 @@ public class CredentialsActivity extends AppCompatActivity implements View.OnCli private TextInputLayout urlLayout, apiLayout; private TextView emptyView; - private ViewGroup organisationView; +// private ViewGroup organisationView; private ProgressBar progressBar; private Organisation myOrganisation; private User myUser; + private RecyclerView recyclerView; + private OrganisationInfoEntryAdapter adapter; + private List orgInfoEntries = new ArrayList<>(); + @Override protected void onCreate(Bundle savedInstanceState) { @@ -120,10 +132,17 @@ public class CredentialsActivity extends AppCompatActivity implements View.OnCli urlLayout = findViewById(R.id.input_layout_server_url); apiLayout = findViewById(R.id.input_layout_api_key); emptyView = findViewById(R.id.empty); - organisationView = findViewById(R.id.myOrganisationView); +// organisationView = findViewById(R.id.myOrganisationView); FloatingActionButton fab = findViewById(R.id.fab_download_own_org_info); fab.setOnClickListener(this); + + recyclerView = findViewById(R.id.recyclerView); + adapter = new OrganisationInfoEntryAdapter(); + RecyclerView.LayoutManager manager = new LinearLayoutManager(this); + recyclerView.setLayoutManager(manager); + recyclerView.setItemAnimator(new DefaultItemAnimator()); + recyclerView.setAdapter(adapter); } /** @@ -141,15 +160,16 @@ public class CredentialsActivity extends AppCompatActivity implements View.OnCli if (myOrganisation == null) { emptyView.setVisibility(View.VISIBLE); - organisationView.setVisibility(View.GONE); +// organisationView.setVisibility(View.GONE); + recyclerView.setVisibility(View.GONE); } else { emptyView.setVisibility(View.GONE); - organisationView.setVisibility(View.VISIBLE); +// organisationView.setVisibility(View.VISIBLE); + recyclerView.setVisibility(View.VISIBLE); visualizeOrganisation(); - } } private void savePreferences() { @@ -164,7 +184,10 @@ public class CredentialsActivity extends AppCompatActivity implements View.OnCli } if (myUser != null) { + + myUser.clearForStorage(); preferenceManager.setMyUser(myUser); + } if (myOrganisation != null) { @@ -243,20 +266,13 @@ public class CredentialsActivity extends AppCompatActivity implements View.OnCli private void downloadOrgInfo() { if (myOrganisation != null) { - DialogInterface.OnClickListener pos = new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { downloadOrgInfo(); } }; - new DialogFactory(this).createOverrideDialog(pos, null).show(); - - } else { - - downloadOrgInfo(); - } if (!validCredentials()) { @@ -294,7 +310,8 @@ public class CredentialsActivity extends AppCompatActivity implements View.OnCli return; } - organisationView.setVisibility(View.VISIBLE); + recyclerView.setVisibility(View.VISIBLE); +// organisationView.setVisibility(View.VISIBLE); emptyView.setVisibility(View.GONE); progressBar.setVisibility(View.GONE); @@ -305,7 +322,8 @@ public class CredentialsActivity extends AppCompatActivity implements View.OnCli public void onError(VolleyError volleyError) { makeSnackBar(ReadableError.toReadable(volleyError)); progressBar.setVisibility(View.GONE); - organisationView.setVisibility(View.GONE); + recyclerView.setVisibility(View.GONE); +// organisationView.setVisibility(View.GONE); emptyView.setVisibility(View.VISIBLE); } }); @@ -315,7 +333,8 @@ public class CredentialsActivity extends AppCompatActivity implements View.OnCli public void onError(VolleyError volleyError) { makeSnackBar(ReadableError.toReadable(volleyError)); progressBar.setVisibility(View.GONE); - organisationView.setVisibility(View.GONE); + recyclerView.setVisibility(View.GONE); +// organisationView.setVisibility(View.GONE); emptyView.setVisibility(View.VISIBLE); } }); @@ -324,25 +343,32 @@ public class CredentialsActivity extends AppCompatActivity implements View.OnCli private void visualizeOrganisation() { - TextView title = organisationView.findViewById(R.id.organisation_title); - title.setText(myOrganisation.getName()); + orgInfoEntries.add(new StringPair("Name", myOrganisation.getName())); +// TextView title = organisationView.findViewById(R.id.organisation_title); +// TextView title = findViewById(R.id.org_title); +// title.setText(myOrganisation.getName()); - TextView uuid = organisationView.findViewById(R.id.organisation_uuid); - uuid.setText(myOrganisation.getUuid()); + orgInfoEntries.add(new StringPair("UUID", myOrganisation.getUuid())); +// TextView uuid = organisationView.findViewById(R.id.organisation_uuid); +// uuid.setText(myOrganisation.getUuid()); - TextView description = organisationView.findViewById(R.id.organisation_description); - description.setText(myOrganisation.getDescription()); + orgInfoEntries.add(new StringPair("Description", myOrganisation.getDescription())); +// TextView description = organisationView.findViewById(R.id.organisation_description); +// description.setText(myOrganisation.getDescription()); - TextView nationality = organisationView.findViewById(R.id.organisation_nationality); - nationality.setText(myOrganisation.getNationality()); + orgInfoEntries.add(new StringPair("Nationality", myOrganisation.getNationality())); +// TextView nationality = organisationView.findViewById(R.id.organisation_nationality); +// nationality.setText(myOrganisation.getNationality()); - TextView sector = findViewById(R.id.organisation_sector); - sector.setText(myOrganisation.getSector()); + orgInfoEntries.add(new StringPair("Sector", myOrganisation.getSector())); +// TextView sector = findViewById(R.id.organisation_sector); +// sector.setText(myOrganisation.getSector()); - TextView users = findViewById(R.id.organisation_user_count); - - users.setText("" + myOrganisation.getUserCount()); + orgInfoEntries.add(new StringPair("User Count", "" + myOrganisation.getUserCount())); +// TextView users = findViewById(R.id.organisation_user_count); +// users.setText("" + myOrganisation.getUserCount()); + adapter.setList(orgInfoEntries); } private void exitSafely() { diff --git a/app/src/main/java/de/overview/wg/its/mispauth/MainActivity.java b/app/src/main/java/de/overview/wg/its/mispauth/MainActivity.java index becd9dd..cd612e2 100644 --- a/app/src/main/java/de/overview/wg/its/mispauth/MainActivity.java +++ b/app/src/main/java/de/overview/wg/its/mispauth/MainActivity.java @@ -91,7 +91,7 @@ public class MainActivity extends AppCompatActivity { emptyPartnerListView = findViewById(R.id.empty); syncedPartnerRecyclerView = findViewById(R.id.recyclerView); - syncedPartnerAdapter = new SyncedPartnerAdapter(this, syncedPartnerList); + syncedPartnerAdapter = new SyncedPartnerAdapter(syncedPartnerList); RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext()); syncedPartnerRecyclerView.setLayoutManager(mLayoutManager); syncedPartnerRecyclerView.setItemAnimator(new DefaultItemAnimator()); diff --git a/app/src/main/java/de/overview/wg/its/mispauth/UploadActivity.java b/app/src/main/java/de/overview/wg/its/mispauth/UploadActivity.java index 7fff748..7a7cd4e 100644 --- a/app/src/main/java/de/overview/wg/its/mispauth/UploadActivity.java +++ b/app/src/main/java/de/overview/wg/its/mispauth/UploadActivity.java @@ -92,17 +92,16 @@ public class UploadActivity extends AppCompatActivity implements View.OnClickLis } private List syncUploadStates = new ArrayList<>(); - private void SyncUpload() { partnerOrganisation = partnerInformation.getOrganisation(); partnerSyncUser = partnerInformation.getUser(); partnerServer = partnerInformation.getServer(); - syncUploadStates.add(new UploadState("Add local organisation")); - syncUploadStates.add(new UploadState("Add sync user to organisation")); - syncUploadStates.add(new UploadState("Add external organisation")); - syncUploadStates.add(new UploadState("Add sync server")); + syncUploadStates.add(new UploadState("Create local organisation")); + syncUploadStates.add(new UploadState("Create sync user & add to organisation")); + syncUploadStates.add(new UploadState("Create external organisation")); + syncUploadStates.add(new UploadState("Create sync server")); uploadStateAdapter.setStateList(syncUploadStates); diff --git a/app/src/main/java/de/overview/wg/its/mispauth/adapter/OrganisationInfoEntryAdapter.java b/app/src/main/java/de/overview/wg/its/mispauth/adapter/OrganisationInfoEntryAdapter.java new file mode 100644 index 0000000..44e3347 --- /dev/null +++ b/app/src/main/java/de/overview/wg/its/mispauth/adapter/OrganisationInfoEntryAdapter.java @@ -0,0 +1,53 @@ +package de.overview.wg.its.mispauth.adapter; + +import android.support.annotation.NonNull; +import android.support.v4.util.Pair; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; +import de.overview.wg.its.mispauth.R; +import de.overview.wg.its.mispauth.model.StringPair; + +import java.util.*; + +public class OrganisationInfoEntryAdapter extends RecyclerView.Adapter { + + private List list = new ArrayList<>(); + + class MyViewHolder extends RecyclerView.ViewHolder { + + TextView title, value; + + private MyViewHolder(View view) { + super(view); + + this.title = view.findViewById(R.id.title); + this.value = view.findViewById(R.id.value); + } + } + + @NonNull + @Override + public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View row = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_org_info_entry, parent, false); + return new OrganisationInfoEntryAdapter.MyViewHolder(row); + } + + @Override + public void onBindViewHolder(@NonNull MyViewHolder holder, int position) { + holder.title.setText(list.get(position).key); + holder.value.setText(list.get(position).value); + } + + @Override + public int getItemCount() { + return list.size(); + } + + public void setList(List list) { + this.list = list; + notifyDataSetChanged(); + } +} diff --git a/app/src/main/java/de/overview/wg/its/mispauth/model/Organisation.java b/app/src/main/java/de/overview/wg/its/mispauth/model/Organisation.java index af2d218..0005e71 100644 --- a/app/src/main/java/de/overview/wg/its/mispauth/model/Organisation.java +++ b/app/src/main/java/de/overview/wg/its/mispauth/model/Organisation.java @@ -36,13 +36,11 @@ public class Organisation { private int createdBy; private int userCount; - public Organisation() { - } + public Organisation() {} public Organisation(JSONObject json) throws JSONException { fromJSON(json); } - public void fromJSON(JSONObject org) throws JSONException { id = org.optInt(ID_KEY, -1); @@ -65,7 +63,6 @@ public class Organisation { public JSONObject toJSON() { return toJSON(false); } - public JSONObject toJSON(boolean minimal) { JSONObject org = new JSONObject(); @@ -99,7 +96,6 @@ public class Organisation { public void setName(String name) { this.name = name; } - public String getName() { return name; } @@ -107,7 +103,6 @@ public class Organisation { public String getDescription() { return description; } - public void setDescription(String description) { this.description = description; } @@ -115,7 +110,6 @@ public class Organisation { public String getSector() { return sector; } - public void setSector(String sector) { this.sector = sector; } @@ -123,7 +117,6 @@ public class Organisation { public String getNationality() { return nationality; } - public void setNationality(String nationality) { this.nationality = nationality; } @@ -131,7 +124,6 @@ public class Organisation { public int getId() { return id; } - public void setId(int id) { this.id = id; } @@ -139,7 +131,6 @@ public class Organisation { public String getDateCreated() { return dateCreated; } - public void setDateCreated(String dateCreated) { this.dateCreated = dateCreated; } @@ -147,7 +138,6 @@ public class Organisation { public String getDateModified() { return dateModified; } - public void setDateModified(String dateModified) { this.dateModified = dateModified; } @@ -155,7 +145,6 @@ public class Organisation { public String getType() { return type; } - public void setType(String type) { this.type = type; } @@ -163,7 +152,6 @@ public class Organisation { public String getContacts() { return contacts; } - public void setContacts(String contacts) { this.contacts = contacts; } @@ -171,7 +159,6 @@ public class Organisation { public boolean isLocal() { return local; } - public void setLocal(boolean local) { this.local = local; } @@ -179,7 +166,6 @@ public class Organisation { public String getUuid() { return uuid; } - public void setUuid(String uuid) { this.uuid = uuid; } @@ -187,7 +173,6 @@ public class Organisation { public String getRestrictedToDomain() { return restrictedToDomain; } - public void setRestrictedToDomain(String restrictedToDomain) { this.restrictedToDomain = restrictedToDomain; } @@ -195,7 +180,6 @@ public class Organisation { public int getCreatedBy() { return createdBy; } - public void setCreatedBy(int createdBy) { this.createdBy = createdBy; } @@ -203,7 +187,6 @@ public class Organisation { public int getUserCount() { return userCount; } - public void setUserCount(int userCount) { this.userCount = userCount; } diff --git a/app/src/main/java/de/overview/wg/its/mispauth/model/StringPair.java b/app/src/main/java/de/overview/wg/its/mispauth/model/StringPair.java new file mode 100644 index 0000000..791898c --- /dev/null +++ b/app/src/main/java/de/overview/wg/its/mispauth/model/StringPair.java @@ -0,0 +1,11 @@ +package de.overview.wg.its.mispauth.model; + +public class StringPair { + + public String key, value; + + public StringPair(String key, String value) { + this.key = key; + this.value = value; + } +} diff --git a/app/src/main/java/de/overview/wg/its/mispauth/model/User.java b/app/src/main/java/de/overview/wg/its/mispauth/model/User.java index 382ba16..de9b858 100644 --- a/app/src/main/java/de/overview/wg/its/mispauth/model/User.java +++ b/app/src/main/java/de/overview/wg/its/mispauth/model/User.java @@ -63,8 +63,8 @@ public class User { private String dateCreated; private String dateModified; - public User() { - } + public User() {} + public User(JSONObject user) throws JSONException { fromJSON(user); } @@ -138,6 +138,12 @@ public class User { return user; } + public void clearForStorage() { + setAuthkey(""); + setGpgKey(""); + setCertifPublic(""); + } + public int getId() { return id; diff --git a/app/src/main/res/layout/activity_credentials.xml b/app/src/main/res/layout/activity_credentials.xml index 4ce7db7..c03ca4c 100644 --- a/app/src/main/res/layout/activity_credentials.xml +++ b/app/src/main/res/layout/activity_credentials.xml @@ -48,7 +48,7 @@ android:paddingLeft="16dp" android:paddingRight="16dp" android:paddingEnd="16dp" - android:paddingBottom="42dp" + android:paddingBottom="32dp" app:passwordToggleEnabled="true" app:passwordToggleTint="#FFF" android:layout_width="match_parent" @@ -70,18 +70,41 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - + + + + + + + + + + + + + + + + + + + + + + + + + + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" + > + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-hdpi/launcher_handshake_round.png b/app/src/main/res/mipmap-hdpi/launcher_handshake_round.png new file mode 100644 index 0000000..aa2f41a Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/launcher_handshake_round.png differ diff --git a/app/src/main/res/mipmap-hdpi/launcher_handshake_square.png b/app/src/main/res/mipmap-hdpi/launcher_handshake_square.png new file mode 100644 index 0000000..7d50fb2 Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/launcher_handshake_square.png differ diff --git a/app/src/main/res/mipmap-hdpi/launcher_round_2.png b/app/src/main/res/mipmap-hdpi/launcher_round_2.png new file mode 100644 index 0000000..c41209a Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/launcher_round_2.png differ diff --git a/app/src/main/res/mipmap-mdpi/launcher_handshake_round.png b/app/src/main/res/mipmap-mdpi/launcher_handshake_round.png new file mode 100644 index 0000000..8d1c20c Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/launcher_handshake_round.png differ diff --git a/app/src/main/res/mipmap-mdpi/launcher_handshake_square.png b/app/src/main/res/mipmap-mdpi/launcher_handshake_square.png new file mode 100644 index 0000000..b667a85 Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/launcher_handshake_square.png differ diff --git a/app/src/main/res/mipmap-mdpi/launcher_round_2.png b/app/src/main/res/mipmap-mdpi/launcher_round_2.png new file mode 100644 index 0000000..6eea0a2 Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/launcher_round_2.png differ diff --git a/app/src/main/res/mipmap-xhdpi/launcher_handshake_round.png b/app/src/main/res/mipmap-xhdpi/launcher_handshake_round.png new file mode 100644 index 0000000..8fbf9bb Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/launcher_handshake_round.png differ diff --git a/app/src/main/res/mipmap-xhdpi/launcher_handshake_square.png b/app/src/main/res/mipmap-xhdpi/launcher_handshake_square.png new file mode 100644 index 0000000..fa562a7 Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/launcher_handshake_square.png differ diff --git a/app/src/main/res/mipmap-xhdpi/launcher_round_2.png b/app/src/main/res/mipmap-xhdpi/launcher_round_2.png new file mode 100644 index 0000000..e318340 Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/launcher_round_2.png differ diff --git a/app/src/main/res/mipmap-xxhdpi/launcher_handshake_round.png b/app/src/main/res/mipmap-xxhdpi/launcher_handshake_round.png new file mode 100644 index 0000000..54659ec Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/launcher_handshake_round.png differ diff --git a/app/src/main/res/mipmap-xxhdpi/launcher_handshake_square.png b/app/src/main/res/mipmap-xxhdpi/launcher_handshake_square.png new file mode 100644 index 0000000..1ba2b77 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/launcher_handshake_square.png differ diff --git a/app/src/main/res/mipmap-xxhdpi/launcher_round_2.png b/app/src/main/res/mipmap-xxhdpi/launcher_round_2.png new file mode 100644 index 0000000..d440e89 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/launcher_round_2.png differ diff --git a/app/src/main/res/mipmap-xxxhdpi/launcher_handshake_round.png b/app/src/main/res/mipmap-xxxhdpi/launcher_handshake_round.png new file mode 100644 index 0000000..92de8dc Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/launcher_handshake_round.png differ diff --git a/app/src/main/res/mipmap-xxxhdpi/launcher_handshake_square.png b/app/src/main/res/mipmap-xxxhdpi/launcher_handshake_square.png new file mode 100644 index 0000000..83ba86f Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/launcher_handshake_square.png differ diff --git a/app/src/main/res/mipmap-xxxhdpi/launcher_round_2.png b/app/src/main/res/mipmap-xxxhdpi/launcher_round_2.png new file mode 100644 index 0000000..e0f8838 Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/launcher_round_2.png differ diff --git a/Screenshots/main.png b/images/Screenshots/main.png similarity index 100% rename from Screenshots/main.png rename to images/Screenshots/main.png diff --git a/Screenshots/org-info-received.png b/images/Screenshots/org-info-received.png similarity index 100% rename from Screenshots/org-info-received.png rename to images/Screenshots/org-info-received.png diff --git a/Screenshots/pub-key-received.png b/images/Screenshots/pub-key-received.png similarity index 100% rename from Screenshots/pub-key-received.png rename to images/Screenshots/pub-key-received.png diff --git a/Screenshots/scan-pub-key.png b/images/Screenshots/scan-pub-key.png similarity index 100% rename from Screenshots/scan-pub-key.png rename to images/Screenshots/scan-pub-key.png diff --git a/images/Screenshots/sync-profile.png b/images/Screenshots/sync-profile.png new file mode 100644 index 0000000..cc29e87 Binary files /dev/null and b/images/Screenshots/sync-profile.png differ diff --git a/Screenshots/upload.png b/images/Screenshots/upload.png similarity index 100% rename from Screenshots/upload.png rename to images/Screenshots/upload.png diff --git a/images/mispbump.svg b/images/mispbump.svg new file mode 100644 index 0000000..67c294a --- /dev/null +++ b/images/mispbump.svg @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + M I S P + + +